面试-基础阶段一

构造器 Constructor 是否可被 override?

  • 不可,重写是指在子类中定义一个同方法签名的方法覆盖掉从父类继承而来的方法;构造器名与类名存在一对一关系且无法被子类继承,因此不可被重写
2.重载和重写的区别
  • 重载发生在同一类中,同方法名,不同参数列表(参数的顺序,类型,个数不同),与返回值和权限修饰符无关
  • 重写发生在子类当中,需要存在继承关系,要求同方法签名,不同方法体,返回值类型<=父类返回值类型,权限>=父类权限
3.Java 面向对象编程三大特性
  • 封装性 : 高内聚低耦合
  • 继承性 : DRY原则
  • 多态性 :父引子,接口引实现类
String 为什么是不可变的?
  • String底层是用一个char数组存储字符串的,此数组的引用变量用final修饰,是常引用,无法指向新数组,因此String不可变
  • private final char[] value
4.String、StringBuffer 和 StringBuilder 的区别是什么?
  • 可变性:
    _String不可变
    _StringBuffer和StringBuilder都是可变的(引用指向可变)
  • 安全性
    _String不可变天生线程安全
    _StringBuffer类的所有方法都加了同步锁,因此线程安全
    _StringBuilder类没有,线程不安全
  • 执行效率
    _每次改变String对象,都是生成一个新的String对象,然后重新指向它,性能偏低
    _相比StringBuiler,StringBuiler牺牲了安全性换来了性能的些许提高
5.自动装箱与拆箱
  • 自动装箱:是指把一个对应类型的常量直接赋值给一个包装类对象,包装类对象会自动把数据进行封装
  • 自动拆箱:是指把一个包装类对象直接赋值给一个对应基本数据类型的引用变量,包装类对象会自动把数据吐出,配合赋值操作
6.接口和抽象类的区别是什么?
  • 接口:
    _接口中只能定义抽象方法,不能有具体的实现(jdk1.8的时候可以定义默认方法,用default关键字修饰),定义字段必须用static final修饰
    _接口和类之间是多实现的关系
    _接口之间为多继承
    _接口方法默认是public修饰,不能用private修饰(无法被实现)
  • 抽象类
    _抽象类中可以定义具体实现
    _子类必须实现抽象类的所有抽象方法,否则会编译报错
    _抽象类和类之间是单继承
7.构造方法有哪些特性?
  • 构造方法名与类名相同
  • 构造方法没有返回值
  • 构造方法可重载
  • 系统默认提供一个无参构造方法,手动定义后失效
  • 无法被子类继承,无法被重写
  • _创建类对象时自动调用
8.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?
  • 完成继承属性的初始化工作(借用父类构造器来对继承属性进行空间初始化)
9.== 与 equals区别
  • 对于基本数据类型,都是比较其内容(值),功能无二
  • 对于引用变量,==比较的是其地址值,equals在没被重写前也是默认比较其地址值,重写之后通常用于比较对象内容
10.你重写过 hashcode 和 equals 么,为什么重写 equals 时必须重写 hashCode 方法?
  • 对于底层实现是哈希表的数据结构,存储数据时需要先进行哈希值比较,结果相同再进行内容比较;只重写equals方法(比如说比较的是name字段),如果有两个对象,name字段都是张三,他们就是相同的两个对象,哈希表的存储的对象是不重复的。但是因为没有重写哈希值(默认的哈希码基是对象地址,这两个对象的地址不一样),因此计算得到的哈希值大概率不同,哈希碰撞发生的概率就大大下降了,在不发生哈希碰撞的情况下,这两个对象都会存入到哈希表中,就是说存储了两个重复对象,这是不符合哈希表的特性的。因此通常要求hashCode方法和hashCode方法重写的时候所用的码基(比较因素)相同,使hashCodehashCode方法比对结果有较高的一致性,保证效率和对象唯一,所以重写时要求要不不重写,要不都重写。
11.线程有哪些基本状态,并描述每种状态?
  • 新生状态 : 新建一个线程,完成初始化后进入新生状态,等待方法启动
  • 就绪状态 :
    _新生线程调用start()方法后启动进入就绪状态,进入就绪队列,等待cpu抽调
    _阻塞状态线程完成资源装卸或睡眠时间结束时重新进入就绪状态,进入就绪队列,等待cpu抽调
    _运行状态 : cpu抽调线程,进入cpu执行任务
  • 阻塞状态 : 执行任务过程中需要装卸资源或进入睡眠时出让cpu,进入阻塞状态,进入阻塞队列等待阻塞条件解除
  • 死亡状态 :
    _线程完成所有任务进入死亡状态
    _线程被强制终止进入死亡状态(调用exit方法,断电)
    _有异常抛出而无异常捕捉进入死亡状态
12.final 关键字修饰这三个地方:变量、方法、类,会有什么作用
  • 修饰基本数据类型变量 : 锁定值
  • 修饰引用变量 : 锁定指针
  • 修饰方法 : 方法无法被重写
  • 修饰类 : 类无法被继承
13.Java 序列化中如果有些字段不想进行序列化,怎么办?
  • 用transient关键字修饰阻止变量的序列化
  • 只能修饰变量,不能修饰方法,类
14.获取用键盘输入常用的两种方法
  • 用扫描器Scanner
    Scanner scanner = new Scanner(System.in);
    String s = scanner.nextLine();
    scanner.close;
  • 用输入流
    BufferReader reader = new BufferReader(new InputStream(System.in));
    String s = reader.readLine();
    reader.close();
15.既然有了字节流,为什么还要有字符流?
  • 字节流
    _以字节为处理单元
    _适用于各种流媒体传输
    _默认直接读写不用缓冲区
    _处理字符数据的时候要先把字符转成字节数据,如果转编用的字符集不一致很容易导致乱码,且效率低
  • 字符流
    _以两个字节为处理单元,适配unicode万国码
    _直接读取字符串,根据指定(UTF-8)编码格式转成字节数据(写入相反,反编码)
    _用到缓冲区(因为要进行内部编译反编译)
    _只能处理文本数据
16.描述深拷贝和浅拷贝
  • 深拷贝是在内存中拷贝了一个对象,并创建引用指向这个新对象,底层有两个对象
  • 浅拷贝是创建了个新引用指向原来的对象,底层只有一个对象
17.说说&和&&的区别。
  • & : 左边表达式运算结果为false,仍执行右边的表达式运算
  • && : 左边表达式运算结果为false,不执行右边的表达式
18.final, finally, finalize的区别。
  • final : 关键字,可以修饰类,方法和变量
  • finally : 关键字,用于修饰代码块,通常与try搭配使用,表示最终执行代码块
  • finalize : 是Object的一个方法,垃圾收集器进行垃圾清理前调用,做相应的资源回收工作(如关闭流,关闭文件等)
19.ArrayList和Vector的区别
  • 开始时间 : ArrayList (jdk1.2) 和 Vector (jdk1.1) 是等价类关系
  • 线程安全性 : ArrayList 非线程安全,Vector线程安全(源码有sychronized)
  • 性能效率 : ArrayList较高
  • 拓容量 : ArrayList拓容50%,拓容参数不可设置,Vector拓容100%,拓容参数可设置
20.Arraylist 与 LinkedList 区别?
  • 底层数据结构方面 : ArrayList基于Object数组,LinkedList基于双向链表
  • crud性能方面 : ArrayList查询性能好,支持随机元素访问,LinkedList增删性能好
  • 空间占用方面 :
    _ArrayList物理存储空间连续,空间浪费体体现在末尾一般存在预留位
    _LinkedList物理存储空间不连续,每个存储单元占用空间比ArrayList大(需要存储前后链接单元的地址)
21.ArrayList的拓容机制
  • 新容量 = 旧容量 + 旧容量 * 50%
22.HashMap和Hashtable的区别
  • 线程安全性 : HashMap非线程安全,HashTable线程安全
  • 键值限制 : HashMap允许键和值为null,HashTable不允许
  • 拓容量 :
    _HashMap的hash数组默认容量为16,拓容方式为16 * 2n
    _HashTable的hash数组默认容量为11,拓容方式为旧容量 * 2 + 1
23.说说List,Set,Map三者的区别?
  • List和Set 继承了Collection接口,Map本身是一个父接口
  • List : 单元素有序集合,存取有序,元素可重复
  • Set : 单元素不重复集合,存取无序,元素不可重复
  • Map : 双元素映射集合,以键值对的形式存储,key唯一
24.什么是线程死锁
  • 线程死锁是指两个或多个线程同时被阻塞,线程之间相互申请对方拥有的资源,却对获得的资源保持不放,进入无限期阻塞状态,称为线程死锁
25.如何避免线程死锁?
  • 破坏互斥条件(理论上无法破坏)
  • 破坏请求与保持条件(请求资源的同时,死抱资源不放)
  • 破坏不剥夺条件(申请对方资源的失败,强制释放对方的资源)
  • 破坏循环等待条件(反序释放资源)
26.说说 sleep() 方法和 wait() 方法区别和共同点?
  • 二者都可以暂停线程的执行
  • 主要区别 : sleep()没有释放锁,wait()释放了锁
  • sleep()方法睡眠时间到了线程会自动苏醒,wait()方法默认不会自动苏醒,但也可以设定一个等待时间使线程自动苏醒
  • 应用方面 : sleep()常用于线程的主动暂停,wait()同常用于线程之间的通讯/交互(存在互动性质的情况)
27.HashMap和ConcurrentHashMap的区别

线程安全方面 :
_ HashMap非线程安全,concurrentHashMap线程安全
_concurrentHashMap采用了锁分段技术,把Hash数组分成了若干段,每段之间都有锁,插入数据需要获取相应小段的锁,这种技术让锁的精度更高,并发性能更好

28.现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • 利用Thread类的join方法
  • 在T2中调用T1的join(0)方法,在T3中调用T2的join(0)方法,如此便能使并行的线程变成串行
    额外补充 :
    join(0)中的0表示在join()方法所在线程执行完后再执行调用join()方法的线程
    join(10)则表示在join()方法所在线程执行完等待10毫秒后再执行调用join()方法的线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值