Java常见问题

1.==和equals的区别。

  1. ==是操作符,equals是方法;
  2. 对于基本数据类型(short,int,long,double,float)只能使用==,没有equals方法
  3. 对于引用类型变量有equals方法,如String继承Object,equals是Object的方法。存在equals是否被覆写的问题。如果没有被覆写,则equals和==一样,是比较两个值在内存中存放的地址。如果被覆写,则equals会比较两者字符串内容是否一致。

2.Object类中定义了哪些方法。

  1. clone():Object clone() 方法用于创建并返回一个对象的拷贝。clone 方法是浅拷贝,对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存,相对应的深拷贝则会连引用的对象也重新创建。
  2. equals()
  3. hashCode()
  4. toString()
  5. notify():线程不能一直在等待集合中,必须有方法对其进行唤醒,notify()方法可以对线程进行唤醒。
        notify()方法调用的一般形式如下:
        对象名.notify();
        当使用当前对象时,使用this作为当前对象的引用,故可以直接写成notify();
        当使用某个对象的notify()方法时,将从该对象的等待集合中选择一个等待的线程唤醒,唤醒的线程将从等待集合中删除
  6. notifyAll():notifyAll()方法会将所有在等待集合中的线程唤醒,但由于所有的被唤醒的线程仍然要去争用synchronized锁,而synchronized锁具有排他性,最终只有一个线程获得该锁,进行执行状态,其他线程仍要继续等待。
        notifyAll()方法调用一般形似如下:
        对象名notifyAll();
        当使用当前对象时,使用this作为当前都对象的引用,故可以直接写成notifyAll();
        notify() 和notifyAll()方法不需要放入try...catch...语句中,主要的区别是:notify是唤醒一个线程,而notifyAll()是唤醒该对象等待集合中的所有线程。
        当只有一个线程等待,另一个线程通知时,建议使用notify(),当有多个线程等待时,建议使用notifyAll()。
  7. wait(): wait()方法的调用的一般形式是:
        对象名.wait();
        称作线程在对象上的等待,作用是把当前的线程放入对象的等待集合中。
        wait()方法通常需要放入以synchronized()方法修饰的语句块或方法中,如果在synchronized外部调用wait()方法,运行时刻Java虚拟机会抛出IllegalMonitorStateException异常。
        wait()方法通常被放到try{}catch() 语句块中,例如:
        try{
            wait();
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        当线程调用wait()方法后,Java虚拟机会让当前的线程进入到休眠状态,并释放对对象的同步锁的控制权,允许其他线程执行该同步代码,要唤醒该线程,需要在同一个对象上调用notify()或notifyAll()方法。
  8. finalize():资源清理
  9. getClass():获取对象的运行时对象的类

3.hashCode 的作用是什么?

4.ArrayList, LinkedList, Vector 是什么?有什么区别?

  1. ArrayList:Java ArrayList | 菜鸟教程 (runoob.com)
  2. LinkedList:Java基础教程——List(列表) - 虎老狮 - 博客园 (cnblogs.com) 
  3. Vector:同上,可看作线程安全版的ArrayList。

5. String, StringBuilder, StringBuffer 的区别是什么? 

  1. String: 不可变的字符序列,若要向其中添加新字符需要创建一个新的 String 对象。
  2. StringBuilder: 可变字符序列,支持向其中添加新字符(无需创建新对象)。
  3. StringBuffer: 可以看作线程安全版的 StringBuilder。

6. HashMap HashTable 的区别

  1. HashTable 是线程安全的,而 HashMap 不是
  2. HashMap 中允许存在 null 键和 null 值,而 HashTable 中不允许    

7.什么是ThreadLocal?

  • ThreadLocal并不是一个Thread(线程),而是Thread的局部变量,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立改变自己的副本,不会影响其它线程所对应的副本。
  • ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
  • ThreadLocal常用方法:
  1. public void set(T value)     设置当前线程的线程局部变量的值
  2. public T get()      返回当前线程所对应的线程局部变量的值  

8.HashMap

  • 多线程下会出现什么问题?
  1. 扩容死链(1.7):因为1.7的数据扩容重新排序采用的是头插法,所以在多线程运行的情况下,会导致转移数据是的顺序错乱,从而使头尾相连,导致死链。
  2. 数据错乱(1.7,1.8):在多线程下,相同桶下标的元素基于运行先后的不同,会存在数据覆盖导致数据丢失的问题。
  • 为什么使用红黑树?
  1. 为了加快查找效率,但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。
  • 为什么树化阈值是8?退化阈值是6?
  1. 因为是基于源码贡献者研究,一个桶中保存8个元素的概率已经降低到0.00000006,几乎为不可能事件,而如果出现了大于8的情况,则说明是元素本身和hash函数的问题,相同的问题后续还会出现,所以引用红黑树,提高效率。
  2. 如果选用8作为退化阈值,则会出现树化退化交替的问题,选择7则意义不大,于是选择6作为退化阈值。

 

  

 图片来源:黑马程序员网上课程。

  • key的要求:
  1. HashMap的key可以为null,但是map的其他实习不行。
  2. 作为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)的用法。

  • 堆区:
  1. 存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
  2. jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身.
  3. 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
  • 栈区:
  1. 每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
  2. 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
  3. 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
  4. 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.
  • 静态区/方法区:
  1. 方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
  2. 方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
  3. 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

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) 的区别。重载的方法能否根据返回类型进行区分?

  • 重载对返回类型没有特殊的要求,不能根据返回类型进行区分
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值