java基础面试题总结

1.集合分类

  两个大类:Collection(接口) 和Map(接口)

Collection下有三个接口 List,Set,Queue 

List接口有三个实现类:arrayList,LinkList,vector(线程安全 synchronizer 锁方法,基本不用)

Map接口有两个实现类:HashMap和HashTable(线程安全 synchronizer 锁方法 基本不用)

arrayList和LinkList的区别:

arrayList基于动态数组结构;linkList是基于链表结构

arrayList 查询快

linkList 新增删除快,只需要移动指针

HashMap 和 Hashtable 的区别?
HashMap 允许空键值,Hashtable 不允许;

HashMap 继承自 AbstractMap,Hashtable 继承自 Dictionary 类,两者都实现了 Map 接口; HashMap 的方法不是同步的,Hashtable 的方法是同步的。


HashMap的实现原理

通过put和get存储和获取对象,存储对象时,我们将K/V传给put方法时,它调用hashcode计算hash从而得到bucket位置,进一步存储,HashMap会根据当前bucket的占用情况自动调整容量。获取对象时,我们将K传递给get,他调用hashcode计算hash从而得到bucket位置,并进一步调用equals()方法确认键值对。
如果需要更具体的信息https://blog.csdn.net/Woo_home/article/details/103146845

集合的线程安全如何实现

通过集合工具Collections提供的同步方法

1.Collections.synchronizedList

2.Collections.synchronizedSet

3.Collections.synchronizedMap

遍历list的几种方法

List<String> list = new ArrayList<>();

第一种:for (String id : list) {}

第二种:for (int i = 0; i < list.size(); i++) {}

第三种:Iterator iterator = list.iterator(); while (iterator.hasNext()){ String a= (String) iterator.next();}

遍历Map的几种方法

Map<String, String> map = new HashMap<>();

第一种:for (String key : map.keySet()) { String value = map.get(key); }

第二种:for (Map.Entry entry : map.entrySet()) { String key = (String) entry.getKey(); String value = (String) entry.getValue(); }

2.线程

java线程的五种状态

新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

  • 1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

  • 2.同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

  • 3.其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

线程同步的几种方式

1、synchronized修饰
2、volatile实现同步(只能保证可见性,不能保证原子性)
3、使用局部变量ThreadLocal
4、使用原子类(AtomicInteger、AtomicBoolean……)
5、使用Lock
6、使用容器类(BlockingQueue、ConcurrentHashMap)

实现线程的几种方式

  • 继承Thread类创建线程
  • 实现Runnable接口创建线程
  • 实现Callable接口创建新线程(可用Future返回结果)

ThreadLocal

提供线程内部的局部变量,这些变量在多线程环境下访问(get/set)时能保证与其它线程里的变量相对独立

锁是什么

锁主要用来实现资源共享的同步。只有获取到了锁才能访问该同步代码,否则等待其他线程使用结束释放锁

有哪几种锁?

synchronize和Lock

synchronize: 可以放在方法前面;也可以放在代码块前面,但需要指定上锁的对象。

 Lock:拥有synchronize相同的语义,但是添加一些其他特性,如中断锁等候和定时锁等候,所以可以使用lock代替synchronize,但需要在finally中手动释放。

synchronize和Lock两者的区别

  性能不一致:资源竞争激励的情况下,lock性能会比synchronize好,竞争不激励的情况下,synchronize比lock性能好。

  锁机制不一样:synchronize是在JVM层面实现的,系统会监控锁的释放与否。lock是代码实现的,需要手动释放,在finally块中释放。可以采用非阻塞的方式获取锁。

  用法不一样:synchronize可以用在代码块上,方法上。lock通过代码实现,有更精确的线程语义
 

乐观锁和悲观锁的理解及如何实现,有哪些实现方式?

乐观锁,每次操作时不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止
悲观锁是会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。
乐观锁可以使用volatile+CAS原语实现,带参数版本来避免ABA问题,在读取和替换的时候进行判定版本是否一致
悲观锁可以使用synchronize的以及Lock


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不是码农的农民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值