前言

博主19年6月才本科毕业,不过在2018年10月的时候就已经参加工作,至今工龄也有一年半了,在前公司成长挺大,但是渐渐地就到了瓶颈。罔顾疫情,于2020年的4月3日离职,破斧沉舟,带着我以后要冲向大厂的志向,开始了寻找新工作的旅程!!冲鸭!!
面试纪(浙江企朋)

走进公司

电梯直达西投创智中心三号楼的5层,进去一整层都是朋的,宽敞且明亮,有点气派,前台妹子特别潮,多彩的头发,再看看我土到掉渣的穿搭,整个进门的画面好似刘姥姥进了大观园见到了王熙凤。

面试纪(浙江企朋)

前台妹子问了问我是不是某某,领着我就往公司内部走,最外面一排办公区女生居多,估计是运营或者ui部门,我观察了一下好像有左右两侧办公区,没走几步,前台小姐姐就喊住了我,让我在一个叫天王星(貌似)的小会议室稍等片刻又给我端了一杯水,大概过了半分钟,之前在boss上聊过的面试官就进来了。

稍作寒暄,面试进行时

  1. 面试官:请先简单地自我介绍一下
    面试经典开场白,我说了一下自己的毕业时间和工作时间以及工作时间涉及到的项目内容,最后说了一下自己的性格优势比如开朗和特长英语等

  1. 面试官:能聊一下final关键字吗

    :final关键字生产上我用到的不多,更多的时候可能是于声明一个类中的全局变量。不过据我所知,final关键字可以修饰类,方法和变量。当final修饰类时候,该类在声明后,将无法改变其引用地址,同时不能被继承,但是内部的变量值可以被改变。修饰方法的时候,无法被重写。修饰变量的时候,一旦变量初始化后,就不能被修改。

(当时紧张,忘记了被final修饰的方法无法被重写,后来面试官友善提醒了我)
注意:final从字面理解是最终,最后的意思,意味着被修饰的东西是一个最终被确定下来的结果,是无法做修改,继承,重写的。


  1. 面试官:java容器有了解吗,稍微讲一下

    :java容器主要分为collection和map两块,collection下分为set,list。map下有hashmap,hashtable,treemap这些。我个人常用的有arraylist和hashmap这两个。后面我分别阐述了一下这两个容器各自使用场景和底层数据结构等。

补充:面试必考容器知识,其中hashmap底层原理和实现更是重中之重。
在java1.8之前,hashmap散列表,底层是由数组和链表来实现。其实现不同步,意味着他不是线程安全的。同时在扩容的时候由于链表的头插法(拉链法),会导致一个环形链表问题从而出现死循环。
java1.8之后hashmap底层实现用了一个数组+链表+红黑树(可能是链表也可能是红黑树)的结构,有效地修正了环形链表问题,同时提高了极端情况下的查询效率。


  1. 面试官:那你说一下collection和collections的区别吧

    :这个有点答不上来(collection我知道是java集合类,也知道collections是用来操作集合的,但是具体区别不是很懂,怕说错嘴过犹不及,所以选择了不答)

    正确答案:Collection,是单列集合的接口,有子接口List和Set
    Collections,是针对集合操作的工具类,其中包含对集合进行排序和二分查找的方法

  2. 面试官:ok,那跳过这个,说一下你平时学习的思路,以及常用java包

    :平时的话,工作中我会把碰到的问题记录在有道云上,也喜欢写博客,用来巩固自己平时的知识。一开始的话碰到运行时异常比较多,后来去了解了一下java异常体系的东西,记录下来。后来代码水平提高了就碰到框架问题会稍微多一些,这些东西网上比较好找,就没有去记,印象深刻的我会写个博客去发布一下。后来的话,特别有意识的去整理一个java的知识体系,做一个查漏补缺。常用java包的话可能是工具包,并发包这些。


  1. 面试官:ok,那并发包下都用些什么

    :平时可能用些线程池这块

    面试官:线程池配置参数有哪几个

    :主要有核心线程数,最大线程数和存活时间

    面试官:平时用的线程池是哪种,怎么创建的

    :我工作中主要用的是newFixedThreadPool,是用Executor类去实例化的(不推荐)

    注意!!:阿里巴巴开发手册中,线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的tongue更加明确线程池的运行规则,规避资源耗尽的风险。

    面试官:线程池关闭方法有哪些

    :有shutDown()和shutDownNow()两个。执行shutdown命令的时候,线程池状态会变成shutdown状态,但是此时线程池不会立刻退出,而是等到线程池中的所有线程都处理完成,才会结束。
    执行shutDownNow命令的时候,线程池会立刻变成stop状态,并试图停止所有线程,不再处理队列中等待的任务。

    注意:多线程实现方式也是面试常考知识点之一。需要注意的点很多,比如核心线程数,最大线程数,和队列中的任务执行顺序问题。比如关闭线程池的时候,任务处理顺序。比如单个线程关闭的方法interrupt()。


  1. 面试官:接下来有一个场景,你说一下怎么去解决,一个接口,需要开5个线程去分别调用别的接口,那么你如何保证下一个线程是在上一个线程完成之后再去执行

    :1.我可能会用线程的join()方法去做一个保证(刚回答完发现回答的不对,是5个线程顺序执行,不是在main方法后执行)。2.刚才这个好像不行,我可能会用一个原子类AtomicInteger做一个计数,来保证没个线程顺序执行。3.可以用redis中间件来缓存每个线程的执行情况,做一个通信。

    肠子悔青:上述三种方案都是解决方式,但是可行性相当低。此时面试官看出了我的窘境,善意地说,你用redis做一个通信是可以的,但是还有其他解决方式吗,不依赖中间件的。

    面试官:用redis做一个通信是可以的,但是还有其他解决方式吗,不依赖中间件的,Future类知道吗

    :实现线程的方式之一我知道,但是怎么用我生产上没有遇到过,我答不上来(心酸)
    面试纪(浙江企朋)

    正确答案:在并发编程中,我们经常用到非阻塞的模型,在之前的多线程的三种实现中,不管是继承thread类还是实现runnable接口,都无法保证获取到之前的执行结果。
    1.通过实现Callback接口,并用Future可以来接收多线程的执行结果,在下一个线程接收到上一个任务的执行成功信号后,继续下一步操作。
    2.CountDownLatch,相比较于我之前的想用AtomicInteger原子类,CountDownLatch是更好的解决方式,因为它本身就是这样设计的。CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有框架服务之后执行(底层是计数器原理)。

    面试官内心os:就这?这就是你平时看的java并发包!? 0.0。


  1. 面试官:好的,那问一下,你平时做项目有碰到什么生产上的问题吗,同时是怎么解决的?

    :我们生产中还用了一个中间件是rabbitmq,众所周知mq主要有三个用处,削峰异步结构,我们公司的那个项目更多的是用来削峰的,是一个埋点业务,8拉8拉然后处理消息的时候我们使用了线程池去多开处理消息,当时使用的线程池类型是newFixedThreadPool,他的队列使用的是一个无界队列。当时有一次处理消息的程序挂了,导致mq消息堆积了千万条数据,然后重启消费信息的项目时候,消息大量进入代码,后来发现是出现了oom,推测是因为线程池每个线程处理时间较长,队列又是无界队列,导致内存溢出了。我当时解决方法是把日志里有用的信息捞出来手动处理,同时将线程池最大核心线程数调大了,然后修改了一下业务代码,来解决这一个问题。

    面试官:(这里面试官说了啥我有点忘记了,不过解决方式有很多种)

    产生原因:当时oom的原因基本能确定,推测是无界队列的锅。解决方式也有很多种,包括设置多个消费者,限制消费速率这些,上文线程池的创建方式提到过。
    正确答案见阿里巴巴手册:如下
    面试纪(浙江企朋)


  1. 面试官:刚才你提到oom,那你java虚拟机这块有什么了解吗?

    :8拉8拉,讲了java内存模型,运行时数据区的分类,涉及到gc的时候,堆的划分,年轻代的复制算法等。

    注意:java虚拟机的知识非常重要,通常初中级java开发不会有虚拟机调优的工作,但是知道这些知识,有利于自己平时的代码规范和对java的理解,也是面试公司对于一个新人是否具有学习驱动力的考量。


  1. 面试官:看你项目里写了分布式用的dubbo和zk,能说一下具体的作用吗

    :好的,我们公司主要是用zk做一个注册中心,然后dubbo去做一个服务的治理。

    万万没想到:给自己挖了一个坑,到了回答的那一刻我才发现我能说的zk和dubbo竟然就只有这么一句话!还好面试官说dubbo他们公司目前没在用了,只是他之前用过这些所以问了一下,期间还问了dubbo和zk之前的通信,长连接心跳策略这些,dubbo本地缓存这些我基本都回答上来了。


  2. 面试官:看你简历里也有用mysql的,还有性能调优这一块,稍微介绍一下你对mysql的了解

    :好的,我们公司以前用的是oracle,最近我接触的项目比较多用的是一个mysql。然后我这边业务中的话由于开发人员的不稳定性,所以很多时候,调优就像家常便饭。就我个人而言,我知道的sql调优的话可能会有这几种原则。1,业务逻辑不写在sql中。2,尽量少用sql函数,不仅会降低效率,如果是跟索引字段冲突还会导致一个索引失效。3,表之间联查,会尽量把大表放在后面,或者直接减少大表联查,防止全表扫描。4,在sql语句的where位置,order by位置会考虑用索引。
    (后面我又聊了innodb和myisam引擎的区别,事务隔离级别等)

    面试官:你刚才有说到索引失效的场景,我现在有这样一个场景,你说一下索引会不会失效。
    假设我们现在有一个联合索引,a,b,c三个字段,我一个语句查的是 where b=什么 and a= 什么 and c=什么,请问索引会失效吗?我一个语句查的是 where a=什么 and b= 什么,请问索引会失效吗?

    这块地方涉及到mysql最左匹配原则,我复习知识的时候忽略了这块东西,面试过程中碰了壁,就不写我自己的回答了。我这边贴上正确答案以及mysql索引优化的东西。索引底层数据结构和原理,索引分类,事务级别这些程序员必备知识我就不说了,百度谷歌一大把。以下是参考博客:

    参考博客:https://www.cnblogs.com/bypp/p/7755307.html
    https://tech.meituan.com/2014/06/30/mysql-index.html

涉及知识点

1.java基础,java容器,多线程
2.工具:mysql
3.中间件:redis和mq
4.框架:dubbo,zk等
5.场景解剖,业务理解和分析
面试纪(浙江企朋)

总结

四月份我面试了8家公司,包括3次电话面试,5次现场面试。电话面试无一例外都挂了,现场面试四个又全过了(有点诡异),拿到了4个口头offer,今天Q朋公司的话还没有出结果。
据我这四月份的面试来看,总结如下:
小公司问的框架问题比较多,问的业务场景比较多,大公司的话就是java基础问和数据库基础问的比较多,可能大公司的话比较喜欢招有潜力的员工。
Q朋的话我个人看来属于中型偏大公司,面试的内容大多是我所复习到的,技术栈这块的话是比较新颖至少不落后,招收标准靠拢大厂,是一个有潜力的大型平台。
所以技术方面,向往大厂的同学最好打稳地基,一步一个脚印,加油。

彩蛋

面试官全程非常平易近人,面试结束我想扔个一次性杯,面试官不仅指明垃圾桶方向,还一路送我到垃圾桶旁边,难道是在暗示我是。。。。
面试纪(浙江企朋)

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-06-18
  • 2021-05-10
  • 2021-11-13
  • 2021-12-24
  • 2021-12-10
  • 2021-11-06
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-12-04
  • 2022-12-23
  • 2021-10-09
  • 2021-12-30
  • 2022-01-05
相关资源
相似解决方案