我看楼下店里能跑啊!
大家好,我是鸭鸭!
老乡鸡菜谱在 GitHub 上又火了一把,现在已经 12.8k+ 的 Star 了。
项目正式名叫《像老乡鸡那样做饭》。其中分了:主食、凉拌、卤菜、早餐、汤、炒菜……等等类目。文字教程大部分来自老乡鸡出品的《老乡鸡菜品溯源报告》。🔥的原因大家懂得都懂,菜谱对留子也是友好度拉满。当然,以下面这位同学的烹饪水平,可能期待老乡鸡开到美国更靠谱一些。至于建议编译自动生成一盘菜的同学,建议还是换一种编译方式。
不过本次事件最好笑的还是老乡鸡官方为了表示感谢,给作者赠送了 1000 元代金券,并发在了项目的 Issue 里(狗头)。卡密直接开源。可想而知,作者并没能吃上这顿老乡鸡。
发卡方式真的过于直白了鸭鸭刚刚查看的时候发现老乡鸡又在 Issue 里发了一次代金券,这次是面向程序员同学的福利。不少同学已经解出来了,目前卡里余额已经领空,不过感兴趣的同学也可以去试试。
当然,为了避免发生向这位同学一样的惨案,大家如果有多的老乡鸡代金券,也可以发给鸭鸭代吃🐶
……
今天来分享一篇 JAVA 阿里饿了么一面的面经。
线程池的原理是什么?
线程池是一种池化技术,用于预先创建并管理一组线程,避免频繁创建和销毁线程的开销,提高性能和响应速度。
它几个关键的配置包括:核心线程数、最大线程数、空闲存活时间、工作队列、拒绝策略。
image.png主要工作原理如下:
- 默认情况下线程不会预创建,任务提交之后才会创建线程(不过设置 prestartAllCoreThreads 可以预创建核心线程)。
- 当核心线程满了之后不会新建线程,而是把任务堆积到工作队列中。
- 如果工作队列放不下了,然后才会新增线程,直至达到最大线程数。
- 如果工作队列满了,然后也已经达到最大线程数了,这时候来任务会执行拒绝策略。
- 如果线程空闲时间超过空闲存活时间,并且当前线程数大于核心线程数的则会销毁线程,直到线程数等于核心线程数(设置 allowCoreThreadTimeOut 为 true 可以回收核心线程,默认为 false)。
什么是自旋锁和可重入锁?
自旋锁
锁自适应自旋是 Java 锁优化中的一种机制,用于减少线程在竞争锁时频繁挂起和恢复的开销。
自适应自旋的核心思想是,在锁争用较少的情况下,线程在进入等待状态前,先执行一段自旋操作(即短暂忙等),而不是立刻挂起线程。
在 Java 中 Syncronized 在争抢重量级锁时候会自旋。具体指的是在重量级锁时,一个线程如果竞争锁失败会进行自旋操作,说白了就是执行一些无意义的执行,空转 CPU 等着锁的释放。
原理:
- 自旋:当一个线程尝试获取锁失败时,它会先忙等一段时间,即自旋,而不是立刻进入阻塞状态。自旋指的是线程反复检查锁是否释放的操作。
- 自适应性:自适应自旋锁通过动态调整自旋的次数来提高性能。自适应的策略基于之前的自旋结果,假如上一次自旋很快获得了锁,下次可能会增加自旋次数;如果自旋失败,则减少自旋时间甚至直接放弃自旋。
优点:
- 自旋可以避免线程的上下文切换开销,因为线程进入阻塞状态会涉及到操作系统层面的挂起和唤醒,代价较高。
- 自适应自旋通过动态调整自旋次数,使得在轻度锁争用情况下的性能提升显著。
缺点:
- 如果锁争用激烈,自旋可能会白白浪费 CPU 时间,因此自适应自旋需要合理的机制来判断是否应该继续自旋。
可重入锁
可重入锁是一种允许同一线程多次获取的锁。简单来说,线程在已经持有锁的情况下,可以再次获得该锁而不会造成死锁。
set 和 list 有什么区别?
List 接口:
- ArrayList:基于动态数组,查询速度快,插入、删除慢。
- LinkedList:基于双向链表,插入、删除快,查询速度慢。
- Vector:线程安全的动态数组,类似于 ArrayList,但开销较大。
Set 接口:
- HashSet:基于哈希表,元素无序,不允许重复。
- LinkedHashSet:基于链表和哈希表,维护插入顺序,不允许重复。
- TreeSet:基于红黑树,元素有序,不允许重复。
所以网上有些说 Set 是无序集合非常不准确,因为需要看具体的实现类。
篇幅有限,
完整答案可以点击下方小程序进行查阅:
我们精选了近两年的高频面试真题,已经有 9000 多道面试题目啦,由大厂资深面试官手写答案,押题命中率超高!
不仅有传统八股文,场景题、项目题、系统设计题等等应有尽有,还在不断更新中!
目前优惠最低特价 129 元即永久(限时上架)畅看所有面试题和答案,正式运营价格为 399+,不要错过这次优惠哈!
且,现在邀请好友注册并成为会员,还可获得 10% 的分佣🧧!详情见面试鸭拉新邀请有赏规则(网页版面试鸭点击头像查看)
网页端网址:www.mianshiya.com