HashCode被设计用来提高性能。equals()方法与hashCode()方法的区别在于:
1,如果两个对象相等(equal),那么他们一定有相同的哈希值。
2,如果两个对象的哈希值相同,但他们未必相等(equal)。
设计模式:
代理模式:
定义:为其他对象提供一种代理,以控制对这个对象的访问
代理对象起到中介的作用,可去掉功能服务或增加额外的服务
火车票代售点就是火车站售票处的代理
常见的代理模式:
远程代理: 为不同地理的对象提供局域网代表对象,
例:客户端&服务器
虚拟代理: 根据需要将资源消耗很大的对象进行延迟,真正需要的时候进行创建
例:浏览帖子,正文优先加载,图片延迟加载
保护代理: 对权限进行控制
例:只有登录才能发帖等等
智能引用代理: 提供对目标对象额外服务
例: 火车票代售处提供一些额外服务
以只能引用代理为例:
静态代理:代理和被代理对象在代理之前是确定的。他们都实现相同的接口或继承相同的抽象类
------------------------------------------------------------------------------------------------------------
下列哪种说法是正确的( )
A 实例方法可直接调用超类的实例方法
B 实例方法可直接调用超类的类方法
C 实例方法可直接调用其他类的实例方法
D 实例方法可直接调用本类的类方法
选d,类方法就是静态方法。其它的就是实例方法
实例方法可以对当前对象的实例变量进行操作,也可以对类变量进行操作,
但类方法不能访问实例变量。实例方法必须由实例对象来调用,而类方法除了可由实例对象调用外,还可以由类名直接调用。
另外,在类方法中不能使用 this 或 super。 关于类方法的使用,有如下一些限制:
1 在类方法中不能引用对象变量。
2 在类方法中不能使用super、this关键字。
3 类方法不能调用类中的对象方法。与类方法相比,实例方法几乎没有什么限制:
1 实例方法可以引用对象变量(这是显然的),也可以引用类变量。
2 实例方法中可以使用super、this关键字。
3 实例方法中可以调用类方法。
------------------------------------------------------------------------------------------------------------
关于C++/JAVA类中static 成员和对象成员的说法正确的是?
A static 成员变量在对象构造时生成
B static 成员函数在对象成员函数中无法调用
C 虚成员函数不可能是static成员函数
D static 成员函数不能访问static成员变量
static为成员变量或函数,在类初始化是加载完成,可以被成员函数调用或访问
在java语言中虚函数指代的就是抽象方法,抽象方法中不能用private,static,synchronized,native等修饰词修饰。
------------------------------------------------------------------------------------------------------------
有如下一段代码,请选择其运行结果()
public class StringDemo{
private static final String MESSAGE="taobao";
public static void main(String [] args) {
String a ="tao"+"bao";
String b="tao";
String c="bao";
System.out.println(a==MESSAGE);
System.out.println((b+c)==MESSAGE);
}
}
Java对String的相加是通过StringBuffer实现的,先构造一个StringBuffer里面存放”tao”,
然后调用append()方法追加”bao”,然后将值为”taobao”的StringBuffer转化成String对象。
StringBuffer对象在堆内存中,那转换成的String对象理所应当的也是在堆内存中。
MESSAGE成员变量及其指向的字符串常量肯定都是在栈内存里的
对于字符串常量的相加,在编译时直接将字符串合并,而不是等到运行时再合并。也就是说
String a = "tao" + "bao" 和String a = "taobao"编译出的字节码是一样的。
所以等到运行时,根据上面说的栈内存是数据共享原则,a和MESSAGE指向的是同一个字符串。
------------------------------------------------------------------------------------------------------------
接口和抽象类:
相同点:都不能被实例化,位于继承树的顶端,都包含抽象方法
不同点:1、设计目的:
接口:
体现的一种规范,类似与整个系统的总纲,
制订了系统各模块应该遵循的标准,因此接口不应该经常改变,一旦改变对整个系统是辐射性的。
抽象类:
作为多个子类的共同父类,体现的是一种模板式设计,可以当作系统实现过程中的中间产品,已经实现了系统部分功能。
2、使用不同
(1)接口只能包含抽象方法,抽象类可以包含普通方法。
(2)接口里不能定义静态方法,抽象类可以。
(3)接口只能定义静态常量属性,不能定义普通属性,抽象类可以。
(4)接口不包含构造器,抽象类可以(不是用于创建对象而是让子类完成初始化)。
(5)接口里不能包含初始化块,抽象类完全可以。
(6)接口多继承,抽象类单继承(只能有一个直接父类)。
总结:
接口所有方法全是抽象方法只能public abstract修饰(默认public abstract修饰),属性默认public static final修饰。
抽象类除了包含抽象方法外与普通类无区别。
------------------------------------------------------------------------------------------------------------
关于volatile关键字,下列描述
A 用volatile修饰的变量,每次更新对其他线程都是立即可见的 //正确
B 对volatile变量的操作是原子性的 //错误
C 对volatile变量的操作不会造成阻塞 //正确
D 不依赖其他锁机制,多线程环境下的计数器可用volatile实现 //错误
------------------------------------------------------------------------------------------------------------
两个最基本的java回收算法:
复制算法和标记清理算法
复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
标记清理:一块区域,标记要回收的对象,然后回收,一定会出现碎片,那么引出
标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象
两个概念:新生代和年老代
新生代:初始对象,生命周期短的
永久代:长时间存在的对象
整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收。
P.S: Serial New收集器是针对新生代的收集器,采用的是复制算法
Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法
Serial Old(串行)收集器,新生代采用复制,老年代采用标记清理
Parallel Old(并行)收集器,针对老年代,标记整理
CMS收集器,基于标记清理
G1收集器:整体上是基于标记清理,局部采用复制
综上:新生代基本采用复制算法,老年代采用标记整理算法。cms采用标记清理。
------------------------------------------------------------------------------------------------------------
Java虚拟机功能:
1 通过 ClassLoader 寻找和装载 class 文件
2 解释字节码成为指令并执行,提供 class 文件的运行环境
3 进行运行期间垃圾回收
4 提供与硬件交互的平台
------------------------------------------------------------------------------------------------------------
关于ThreadLocal以下说法正确的是?
A ThreadLocal继承自Thread //错误,ThreadLocal继承Object,相当于没继承任何特殊的。
B ThreadLocal实现了Runnable接口 //错误,ThreadLocal没有实现任何接口
C ThreadLocal重要作用在于多线程间的数据共享 //错误
D ThreadLocal是采用哈希表的方式来为每个线程都提供一个变量的副本 //正确
E ThreadLocal保证各个线程间数据安全,每个线程的数据不会被另外线程访问和破坏 //正确
线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;
在线程消失之后,其线程局部实例的所有副本都会被垃圾回收
------------------------------------------------------------------------------------------------------------
以下JAVA程序的输出是什么()
public class HelloSogou{
public static synchronized void main(String[] a){
Thread t=new Thread(){
public void run(){Sogou();}
};
t.run();
System.out.print("Hello");
}
static synchronized void Sogou(){
System.out.print("Sogou");
}
}
A HelloSogou B SogouHello C Hello D 结果不确定
------------------------------------------------------------------------------------------------------------
如果是t.start(),(静态同步函数的锁是该类的字节码文件.class main函数和Sogou方法都是static的,所以持有相同锁
HelloSogou.class那么,在main线程(main 是一个线程也是一个进程 )中又开了一个线程,调用Sogou方法,锁会冲突。 选D
但是,t.run()只是普通方法,顺序执行,选B
-----------------------------------------------------------------------------------------------------------
ServerSocket (int port)
创建一个serversocket 绑定在特定的端口
Socket(InetAddress address, int port)
创建一个socket流,连接到特定的端口和ip地址
------------------------------------------------------------------------------------------------------------
一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性。
------------------------------------------------------------------------------------------------------
线程通过调用对象的synchronized方法可获得对象的互斥锁定;
线程调度算法是平台独立的:
线程调度分为协同式调度和抢占式调度,Java使用的是抢占式调度,也就是每个线程将由操作系统来分配执行时间,
线程的切换不由线程本身来决定(协同式调度)。这就是平台独立的原因。
------------------------------------------------------------------------------------------------------------
优化Hibernate所鼓励的7大措施:
1.尽量使用many-to-one,避免使用单项one-to-many
2.灵活使用单向one-to-many
3.不用一对一,使用多对一代替一对一
4.配置对象缓存,不使用集合缓存
5.一对多使用Bag 多对一使用Set
6.继承使用显示多态 HQL:from object polymorphism="exlicit" 避免查处所有对象
7.消除大表,使用二级缓存
------------------------------------------------------------------------------------------------------------
class Car extends Vehicle
{
public static void main (String[] args)
{
new Car(). run();
}
private final void run()
{
System. out. println ("Car");
}
}
class Vehicle
{
private final void run()
{
System. out. println("Vehicle");
}
}
首先final声明的方法是不能被覆盖的,但是这里并不错误,因为方法是private的,
也就是子类没有继承父类的run方法,因此子类的run方法跟父类的run方法无关,并不是覆盖。
new Car().run()也是调用子类的run方法。输出Car。
************************************************************************************************************v
************************************************************************************************************
public class Test2
{
public void add(Byte b){
b = b++;
}
public void test(){
Byte a = 127;
Byte b = 127;
add(++a);
System.out.print(a + " ");
add(b);
System.out.print(b + "");
}
}
public void add(Byte b){ b=b++; } 这里涉及java的自动装包/自动拆包(AutoBoxing/UnBoxing)
Byte的首字母为大写,是类,看似是引用传递,但是在add函数内实现++操作,会自动拆包成byte值传递类型,
所以add函数还是不能实现自增功能。也就是说add函数只是个摆设,没有任何作用。 Byte类型值大小为-128~127之间。
add(++a);这里++a会越界,a的值变为-128 add(b); 前面说了,add不起任何作用,b还是127
************************************************************************************************************
************************************************************************************************************
class C {
C() {
System.out.print("C");
}
}
class A {
C c = new C();
A() {
this("A");
System.out.print("A");
}
A(String s){
System.out.print(s);
}
}
class Test extends A{
Test(){
super("B");
System.out.print("B");
}
public static void main(String[] args) {
new Test();
}
}
//解答1:
初始化过程是这样的: 父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数
1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
3.其次,初始化父类的普通成员变量和代码块,在执行父类的构造方法;
4.最后,初始化子类的普通成员变量和代码块,在执行子类的构造方法;
(1)初始化父类的普通成员变量和代码块,执行 C c = new C(); 输出C
(2)super("B"); 表示调用父类的构造方法,不调用父类的无参构造函数,输出B
(3) System.out.print("B");
所以输出CBB
//解答2:
首先new了一个子类对象,那么就要调用构造方法来初始化该子类对象,但是该类继承自A,所以要先调用父类的构造方法,
这里通过super("B")显示的调用了父类的带参构造。
执行父类的带参构造前要先对父类中的对象进行初始化,对父类中的c成员进行初始化,调用了C类的无参构造,所以调用顺序为:
先调用C类的无参构造
再调用A类的带参构造
最后调用调用子类的构造
------------------------------------------------------------------------------------------------------------
假设有以下代码String s = "hello":String t = “hello”;char c [ ] = {'h','e','l','l','o'};下列选项中返回false的语句是?
A s.equals (t);
B t.equals (c);
C s==t;
D t.equals (new String ("hello"));
Sting 类保存字符串只是保存所有单单的字符串;
而 char[] 字符数组 会在最后自动加上'\n';
所以B:t.equals(c)会返回fasle;
所以 答案B
------------------------------------------------------------------------------------------------------------
根据下面的代码,
String s = null;
会抛出NullPointerException异常的有:
A if( (s!=null) & (s.length()>0) ) B if( (s!=null) && (s.length()>0) )
C if( (s==null) | (s.length()==0)) D if( (s==null) || (s.length()==0) )
String s=null;没有给s开辟任何空间,当执行length()方法时候,
因为没有具体指向的内存空间,所以报出NullPointerException没有指向的错误。
A &是与,位运算,两个都得执行,执行到s.length()自然就报错了。
B s!=null 结果为false 整体就为false ,&& 后面就不会执行。下面的同理。 AC
------------------------------------------------------------------------------------------------------------
************************************************************************************************************
************************************************************************************************************
HashMap和Hashtable两个类都实现了Map接口,二者保存K-V对(key-value对)
HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)。
Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步
迭代 HashMap 采用快速失败机制,而 HashTable 不是,因为 HashTable是线程安全的
HashMap把Hashtable的contains方法去掉了,改成 containsvalue 和 containsKey。因为contains方法容易让人引起误解
HashTable使用Enumeration,HashMap使用Iterator
************************************************************************************************************
************************************************************************************************************
------------------------------------------------------------------------------------------------------------
例化线程: 1、如果是扩展java.lang.Thread类的线程,则直接new即可。
2、如果是实现了java.lang.Runnable接口的类,则用Thread的构造方法:
public class MyRunnable implements Runnable{
public void run() {
(new Thread(new MyRunnable()).start()
}
}
------------------------------------------------------------------------------------------------------------
<<表示左移位
>>表示带符号右移位
>>>表示无符号右移
但是没有<<<运算符
------------------------------------------------------------------------------------------------------------
CopyOnWriteArrayList适用于读多写少的并发场景
ReadWriteLock即为读写锁,要求写与写之间互斥,读与写之间互斥,读与读之间可以并发执行。在读多写少的情况下可以提高效率
ConcurrentHashMap是同步的HashMap,读写都加锁
volatile只保证多线程操作的可见性,不保证原子性
------------------------------------------------------------------------------------------------------------
String str = new String("abc"),"abc"在内存中是怎么分配的?
A 堆
B 栈
C 字符串常量区
D 寄存器
当你new String("abc")时,其实会先在字符串常量区生成一个abc的对象,然后new String()时会在堆中分配空间,
然后此时会把字符串常量区中abc复制一个给堆中的String,故abc应该在堆中和字符串常量
------------------------------------------------------------------------------------------------------------
byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2);
b6=b4+b5;
b8=(b1+b4);
b7=(b2+b5);
上面代码片段中,存在编辑错误的语句是?
本题答案应为:B、C、D
Java表达式转型规则由低到高转换:
1、所有的byte,short,char型的值将被提升为int型;
2、如果有一个操作数是long型,计算结果是long型;
3、如果有一个操作数是float型,计算结果是float型;
4、如果有一个操作数是double型,计算结果是double型;
5、被fianl修饰的变量不会自动改变类型,当2个final修饰相操作时,结果会根据左边变量的类型而转化。
语句1错误:b3=(b1+b2); 自动转为int,所以正确写法为b3=(byte)(b1+b2);或者将b3定义为int;
语句2正确:b6=b4+b5; b4、b5为final类型,不会自动提升,所以和的类型视左边变量类型而定,即b6可以是任意数值类型;
语句3错误:b8=(b1+b4); 虽然b4不会自动提升,但b1仍会自动提升,所以结果需要强转,b8=(byte)(b1+b4);
语句4错误:b7=(b2+b5); 同上。同时注意b7是final修饰,即只可赋值一次,便不可再改变。
------------------------------------------------------------------------------------------------------------
Java类Demo中存在方法func0、func1、func2、func3和func4,请问该方法中,哪些是不合法的定义?( )
public class Demo{
float func0() byte,short,char-> int -> long -> float -> double
{ 小转大不用强转,大转小需要强转
byte i=1; func1 没有返回值;func4 大转小需要强转
return i;
}
float func1()
{
int i=1;
return;
}
float func2()
{
short i=2;
return i;
}
float func3()
{
long i=3;
return i;
}
float func4()
{
double i=4;
return i;
}
}
------------------------------------------------------------------------------------------------------------
java中除了基本数据类型都是引用数据类型
java中的基本数据类型如下:
byte short int long float double char boolean
除此之外都是引用类型
------------------------------------------------------------------------------------------------------------
可用来实现线程间通知和唤醒:
Object.wait/notify/notifyAll
Condition.await/signal/signalAll
------------------------------------------------------------------------------------------------------------
Statement是sql语句的载体
Statement是标准的Statement类,通过字符串对sql语句进行拼接,但是它存在sql注入的危险
PreparedStatement对sql语句进行了预编译,可以防止SQL注入
CallableStatement用来调用存储过程的
BatchedStatement用于批量操作数据库,BatchedStatement不是标准的Statement类
------------------------------------------------------------------------------------------------------------
面向对象的五大基本原则:
单一职责原则(SRP)
开放封闭原则(OCP)
里氏替换原则(LSP)
依赖倒置原则(DIP)
接口隔离原则(ISP)
-----------------------------------------------------------------------------------------------------------
下面有关java实例变量,局部变量,类变量和final变量的说法,错误的是?
A 实例变量指的是类中定义的变量,即成员变量,如果没有初始化,会有默认值 // 正确
B 局部变量指的是在方法中定义的变量,如果没有初始化,会有默认值 //********局部变量必须有初始值******
C 类变量指的是用static修饰的属性 //正确
D final变量指的是用final修饰的变量 //正确
------------------------------------------------------------------------------------------------------------
构造函数不可以用private修饰 //错误,单例模式中,构造器私有化
构造函数必须与类名相同 //正确
构造方法不能被子类继承,所以用final修饰没有意义。
构造方法用于创建一个新的对象,不能作为类的静态方法,所以用static修饰没有意义。
此外,Java语言不支持native或synchronized的构造方法
-----------------------------------------------------------------------------------------------------------
Java默认使用Unioncode编码,即不论什么语言都是一个字符占两个字节
Java的class文件编码为UTF-8,而虚拟机JVM编码为UTF-16
UTF-8编码下,一个中文占3个字节,一个英文占1个字节
Java中的char默认采用Unicode编码,所以Java中char占2个字节
1(byte)字节=8(bit)位
------------------------------------------------------------------------------------------------------------
floor: 求小于参数的最大整数。返回double类型-----n. 地板,地面
例如:Math.floor(-4.2) = -5.0
ceil: 求大于参数的最小整数。返回double类型-----vt. 装天花板;
例如:Math.ceil(5.6) = 6.0
round: 对小数进行四舍五入后的结果。返回int类型
例如:Math.round(-4.6) = -5
----------------------------------------------------------------------------------------------------------
Integer i = 42;
Long l = 42l;
Double d = 42.0; 下面为true的是?
A i == l B i == d C l == d
D i.equals(d) E d.equals(l) F i.equals(l) G l.equals(42L)
ABC3 个选项很明显,不同类型引用的 == 比较,会出现编译错误,不能比较。
DEF 调用 equals 方法,因为此方法先是比较类型,而 i , d , l 是不同的类型,所以返回假。
选项 G ,会自动装箱,将 42L 装箱成 Long 类型,所以调用 equals 方法时,类型相同,且值也相同,因此返回真
------------------------------------------------------------------------------------------------------------
Java致力于检查程序在编译和运行时的错误
Java虚拟机实现了跨平台接口
类型检查帮助检查出许多开发早期出现的错误
Java自己操纵内存减少了内存出错的可能性
Java还实现了真数组,避免了覆盖数据的可能
注意,是避免数据覆盖的可能,而不是数据覆盖类型
------------------------------------------------------------------------------------------------------------
java不允许单独的方法,过程或函数存在,需要隶属于某一类中
java语言中的方法属于对象的成员,而不是类的成员。不过,其中静态方法属于类的成员
-----------------------------------------------------------------------------------------------------------
形式参数可被视为local variable
对于形式参数只能用final修饰符
形参的值在调用时根据调用者更改,实参则用自身的值更改形参的值(指针、引用皆在此列),也就是说真正被传递的是实参