1.==和equals的区别。
- ==是操作符,equals是方法;
- 对于基本数据类型(short,int,long,double,float)只能使用==,没有equals方法
- 对于引用类型变量有equals方法,如String继承Object,equals是Object的方法。存在equals是否被覆写的问题。如果没有被覆写,则equals和==一样,是比较两个值在内存中存放的地址。如果被覆写,则equals会比较两者字符串内容是否一致。
2.Object类中定义了哪些方法。
- clone():Object clone() 方法用于创建并返回一个对象的拷贝。clone 方法是浅拷贝,对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存,相对应的深拷贝则会连引用的对象也重新创建。
-
equals()
-
hashCode()
- toString()
- notify():线程不能一直在等待集合中,必须有方法对其进行唤醒,notify()方法可以对线程进行唤醒。
notify()方法调用的一般形式如下:
对象名.notify();
当使用当前对象时,使用this作为当前对象的引用,故可以直接写成notify();
当使用某个对象的notify()方法时,将从该对象的等待集合中选择一个等待的线程唤醒,唤醒的线程将从等待集合中删除 - notifyAll():notifyAll()方法会将所有在等待集合中的线程唤醒,但由于所有的被唤醒的线程仍然要去争用synchronized锁,而synchronized锁具有排他性,最终只有一个线程获得该锁,进行执行状态,其他线程仍要继续等待。
notifyAll()方法调用一般形似如下:
对象名notifyAll();
当使用当前对象时,使用this作为当前都对象的引用,故可以直接写成notifyAll();
notify() 和notifyAll()方法不需要放入try...catch...语句中,主要的区别是:notify是唤醒一个线程,而notifyAll()是唤醒该对象等待集合中的所有线程。
当只有一个线程等待,另一个线程通知时,建议使用notify(),当有多个线程等待时,建议使用notifyAll()。 - wait(): wait()方法的调用的一般形式是:
对象名.wait();
称作线程在对象上的等待,作用是把当前的线程放入对象的等待集合中。
wait()方法通常需要放入以synchronized()方法修饰的语句块或方法中,如果在synchronized外部调用wait()方法,运行时刻Java虚拟机会抛出IllegalMonitorStateException异常。
wait()方法通常被放到try{}catch() 语句块中,例如:
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
当线程调用wait()方法后,Java虚拟机会让当前的线程进入到休眠状态,并释放对对象的同步锁的控制权,允许其他线程执行该同步代码,要唤醒该线程,需要在同一个对象上调用notify()或notifyAll()方法。 - finalize():资源清理
- getClass():获取对象的运行时对象的类
3.hashCode 的作用是什么?
4.ArrayList, LinkedList, Vector 是什么?有什么区别?
- ArrayList:Java ArrayList | 菜鸟教程 (runoob.com)
- LinkedList:Java基础教程——List(列表) - 虎老狮 - 博客园 (cnblogs.com)
- Vector:同上,可看作线程安全版的ArrayList。
5. String, StringBuilder, StringBuffer 的区别是什么?
- String: 不可变的字符序列,若要向其中添加新字符需要创建一个新的 String 对象。
- StringBuilder: 可变字符序列,支持向其中添加新字符(无需创建新对象)。
- StringBuffer: 可以看作线程安全版的 StringBuilder。
6. HashMap 和 HashTable 的区别
- HashTable 是线程安全的,而 HashMap 不是
- HashMap 中允许存在 null 键和 null 值,而 HashTable 中不允许
7.什么是ThreadLocal?
- ThreadLocal并不是一个Thread(线程),而是Thread的局部变量,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立改变自己的副本,不会影响其它线程所对应的副本。
- ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
- ThreadLocal常用方法:
- public void set(T value) 设置当前线程的线程局部变量的值
- public T get() 返回当前线程所对应的线程局部变量的值
8.HashMap
- 多线程下会出现什么问题?
- 扩容死链(1.7):因为1.7的数据扩容重新排序采用的是头插法,所以在多线程运行的情况下,会导致转移数据是的顺序错乱,从而使头尾相连,导致死链。
- 数据错乱(1.7,1.8):在多线程下,相同桶下标的元素基于运行先后的不同,会存在数据覆盖导致数据丢失的问题。
- 为什么使用红黑树?
- 为了加快查找效率,但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。
- 为什么树化阈值是8?退化阈值是6?
- 因为是基于源码贡献者研究,一个桶中保存8个元素的概率已经降低到0.00000006,几乎为不可能事件,而如果出现了大于8的情况,则说明是元素本身和hash函数的问题,相同的问题后续还会出现,所以引用红黑树,提高效率。
- 如果选用8作为退化阈值,则会出现树化退化交替的问题,选择7则意义不大,于是选择6作为退化阈值。
图片来源:黑马程序员网上课程。
- key的要求:
- HashMap的key可以为null,但是map的其他实习不行。
- 作为key的对象,必须实现hashCode和equals,并且key的内容不能修改。(若桶下标一致,则equals比较值,若相同,则放弃当前插入的值)。
1.面向对象的特征有哪些方面?
- 封装:
- 继承:
- 多态:
2、访问修饰符public,private,protected,以及不写(默认)时的区别?
- public:所有包和类都可以访问;
- private: 同一类中可以访问;
- protected:同一类或者同一个包中和子类可以访问;
- default(默认): 同一类或者同一个包(若子类和父类在同一个包中)可以访问;
3、String是最基本的数据类型吗?
- 不是基本数据类型,Spring是一个类。
4、float f=3.4;是否正确?
- 不正确,在Java中,整数类型默认为int类型,而小数类型数据默认为double,而double类型不能够通过自动类型转换为float类型,所以错误。
5、short s1 = 1;s1 = s1+1;有错吗?short s1 = 1;s1 += 1;有错吗?
- 第一个不对,s1是short类型的数据,1是int类型的数据,s1 + 1会自动将short类型数据转换为int类型数据,而int类型数据要返回给short需要强制类型转换,所以不对;
- 第二个正确,+=是Java中的运算符,存在强制类型转换,所以正确。
6、Java有没有goto?
- 其实goto这个词是C语言中的,goto语句通常与条件语句配合使用,可用来实现条件转移, 构成循环,跳出循环体等功能。而在结构化程序语言 中一般不主张使用goto语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。但是在java语言中,goto这个词只是作为了保留字,还没有使用。那是因为java语言讲究简单,方便。
7、int 和Integer有什么区别?
- Integer是int的包装类;int是基本数据类型;
- Integer变量必须实例化后才能使用;int变量不需要;
- Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;
- Integer的默认值是null;int的默认值是0。
8、&和&&的区别?
- & 需要判断 &前后两端的条件是否成立;
- && 判断前端条件不成立,后端条件直接不执行。
9、解释内存中的栈(stack)、 堆(heap)和方法区(method area)的用法。
- 堆区:
- 存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
- jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身.
- 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
- 栈区:
- 每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
- 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
- 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.
- 静态区/方法区:
- 方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
- 方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
- 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
10、Math.round(11.5) 等于多少? Math.round(-11.5)等于多少?
- Math.round()方法是四舍五入法:给原数据+0.5,然后再向下取整,Math.round(11.5)=12,Math.round(-11.5)= -11
11、switch 是否能作用在byte 上,是否能作用在long上,是否能作用在String 上?
- 隐式类型转换:即自动类型转换,
转换规则: 从存储范围小的类型到存储范围大的类型。 具体规则为: byte→short(char)→int→long→float→double
- 在switch(odds),odds只能是一个整数表达式或者枚举常量,整数表达式可以是int或者Integer,由于隐式类型转换的原因,byte,short,char以及他们的包装类都可以作用在switch上。
- 根据隐式类型转换,显然long,float,double以及String类型数据不符合规定,所以不行。
- 在JDK7之后,String类型数据可以作用在switch上,是因为JDK7之后的新特性,可以将String类型数据通过HashCode和equals方法转换为整型数据。
- switch中可以是枚举类型(JDK1.5之后)。
12、用最有效率的方法计算2乘以8?
- 因为将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,而位运算cpu直接支持的,效率最高,所以,2乘以8等於几的最效率的方法是2 << 3。
13、数组有没有length()方法? String 有没有length()方法?
- 数组没有length()方法,只有length属性,用来记录数组的长度;
- String有length()方法,用来计算字符串的长度。
14、在Java中,如何跳出当前的多重嵌套循环?
- 在最外层循环之前加一个标号,在内层循环中加上带有标号的break语句,就可以跳出多重嵌套循环;
- 也可以在循环中加入一个条件判断语句,当需要跳出循环时,将该语句的值进行反转,再加上break即可跳出循环。
15、构造器( constructor) 是否可被重写(override) ?
- 构造器(构造方法)Constructor 不能被继承,因此不能重写 Override,但可以被重载 Overload(不同参数即可)。
- 每一个类必须有自己的构造函数,在创建对象时自动调用,如果添加有参构造函数后,默认无参构造函数则被覆盖。子类不会覆盖父类的构造函数,但是在创建子类对象的时候,会自动调用父类构造函数。
16、两个对象值相同(x. equals(y) == true), 但却可有不同的hash code,这句话对不对?
- 正确,在没有重写equals()方法和hashCode时,会存在equals相等,但有不同的hashCode值。
17、是否可以继承String类?
- 不可以,
根据String源码可以看出,String类使用final声明的,而final声明的类不能被继承。
- final可以用来修饰 类 、变量 和 方法,
final修饰类的时候 ,这个类就不能被继承了 类中所有的方法也就被隐式的变为final方法
final修饰的方法的类可以被继承,但是final修饰的方法无法被覆写
final修饰的变量相当于常量,只能被赋值一次,赋值后值不再更改 ,这就表示了final修饰的变量必须被初始化,初始化可以在声明变量的时候,也可以在构造函数中初始化。
18、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
- 是值传递,Java编程语言中只有值传递参数。当一个对象作为参数传递到方法中时,参数的值就是该对象的引用。对象的内容可以在方法中被改变,但对象的引用是永远不会改变的。
19、String 和StringBuilder、StringBuffer 的区别?
- String: 不可变的字符序列,若要向其中添加新字符需要创建一个新的 String 对象。
- StringBuilder: 可变字符序列,支持向其中添加新字符(无需创建新对象)。
- StringBuffer: 可以看作线程安全版的 StringBuilder。
20、重载(Overload) 和重写(Override) 的区别。重载的方法能否根据返回类型进行区分?
- 重载对返回类型没有特殊的要求,不能根据返回类型进行区分