网易内推Java开发工程师(一面+二面+HR面)

网易7月底就开始内推,我投的是网易传媒(北京)的Java开发工程师。

笔试没什么可说的,之前刷过一些题,顺利通过。按面试的时间安排来看笔试成绩还不错,安排在第一批的。

顺便吐槽一下牛客网的笔试系统,笔试开始半个小时判题系统就挂了,之后延长了一个小时笔试时间。

8月17号晚上收到笔试通过通知短信,面试安排在20号,时间太紧,然后查了下票只剩硬座了=。=没办法只能忍受一天一夜的硬座。

19号晚上到达北京,休息了一晚上第二天赶往网易北京研发中心,去等了一会然后就签到开始面试了。

 

一面

面试官比较年轻,可能年龄和我差不多。

刚开始有点紧张,差点脑子短路,之后就缓过来了。

下面是大概的面试过程,可能顺序不太对的上:

请先自我介绍一下

就大概按照简历上说了下,学校、专业、求职意向,还说了我的竞赛经历。

说一下Java虚拟机的内存模型吧

这里理解错问题了,要注意审题啊

我答的是多线程的内存模型,主存、工作内存之类的。说完面试官也没有反驳=。=

这里应该回答堆栈相关,即Java虚拟机的运行时数据区域。

详细参考:《深入理解Java虚拟机》学习笔记(2)——运行时数据区域

请描述一下Java虚拟机的垃圾回收机制

这是个送分题啊!基本上被问到就可以扯上很久。

大概就是围绕Java虚拟机的运行时数据区域(自己都没意识到把上一个问题的坑填了,面完才发觉)、可达性分析、4种引用、回收算法、垃圾收集器来回答。

被问到这个问题时候面试刚开始没多久,比较紧张,想说的太多,差点不知道从什么地方开始。。

详细参考:

《深入理解Java虚拟机》学习笔记(1)——JVM垃圾回收与内存分配策略

《深入理解Java虚拟机》学习笔记(4)——垃圾收集器

我看你项目中用了MyBatis,那你知道为什么现在越来越多的人倾向使用MyBatis呢?它和Hibernate有什么区别?

这个问题答得不是很好,明明前天才看了的,当时却想不起来了。就随便说了下MyBatis更加轻量级,容易掌握,而且比Hibernate更加灵活。MyBatis可以进行更为细致的SQL优化。

正解:

两者相同点

  • Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。
  • Hibernate和MyBatis都支持JDBC和JTA事务处理。

Mybatis优势

  • MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
  • MyBatis容易掌握,而Hibernate门槛较高。

Hibernate优势

  • Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
  • Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
  • Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
  • Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。

详细参考:Hibernate与 MyBatis的比较

spring AOP是如何实现的?

spring AOP有JDK动态代理和CGLIB代理两种实现方式

JDK动态代理和CGLIB代理有什么区别?

这个详细的实现有点记不住了,回答的是JDK动态代理是通过接口实现的,而CGLIB是通过字节码层面的类实现的。

虽然大体上没错,但是不够详细啊=。=

正解:

  • JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理;其核心是InvocationHandler接口和Proxy类。
  • CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强;需要引入包asm.jar和cglib.jar。

那你知道spring默认使用哪种代理吗?

这个确实不知道,当时就回答的不知道。感觉这种问题不能乱猜,猜错会影响面试官对你的印象。

正解:

  • 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
  • 如果目标对象实现了接口,可以强制使用CGLIB实现AOP
  • 如果目标对象没有实现接口,则默认采用CGLIB实现AOP

你项目中用到了MySQL,那你知道MySQL有哪些引擎吗?

回答的是用过MyISAM和InnoDB,还有两个不记得了。期间还被面试官提醒名字

正解:MyISAM、InnoDB、MEMORY、MERGE

说说MyISAM和InnoDB有什么区别

这个问题回答得惨不忍睹,之前也看过,但是基本记不起来了,当时深入浅出MySQL那本书是一晚上翻晚的。

我回答的MyISAM读速度比较快,不支持外键,而InnoDB支持外键

正解:(转自:InnoDB与Myisam的六大区别

MyISAM InnoDB
构成上 每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。

.frm文件存储表定义。

数据文件的扩展名为.MYD (MYData)。

索引文件的扩展名是.MYI (MYIndex)。

基于磁盘的资源是InnoDB表空间数据文件和它的日志文件,InnoDB 表的大小只受限于操作系统文件的大小,一般为 2GB
事务处理 MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持 InnoDB提供事务支持事务,外部键等高级数据库功能
SELECT,UPDATE,

INSERT,DELETE

如果执行大量的SELECT,MyISAM是更好的选择 1.如果你的数据执行大量的INSERTUPDATE,出于性能方面的考虑,应该使用InnoDB表

2.DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。

3.LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用

AUTO_INCREMENT的操作 每表一个AUTO_INCREMEN列的内部处理。

MyISAMINSERTUPDATE操作自动更新这一列。这使得AUTO_INCREMENT列更快(至少10%)。在序列顶的值被删除之后就不能再利用。(当AUTO_INCREMENT列被定义为多列索引的最后一列,可以出现重使用从序列顶部删除的值的情况)。

AUTO_INCREMENT值可用ALTER TABLE或myisamch来重置

对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引

更好和更快的AUTO_INCREMENT处理

如果你为一个表指定AUTO_INCREMENT列,在数据词典里的InnoDB表句柄包含一个名为自动增长计数器的计数器,它被用在为该列赋新值。

自动增长计数器仅被存储在主内存中,而不是存在磁盘上

关于该计算器的算法实现,请参考

AUTO_INCREMENT列在InnoDB里如何工作

表的具体行数 SELECT COUNT(*) FROM table,MyISAM只要简单的读出保存好的行数,注意的是,当COUNT(*)语句包含WHERE条件时,两种表的操作是一样的 InnoDB中不保存表的具体行数,也就是说,执行SELECT COUNT(*) FROM table时,InnoDB要扫描一遍整个表来计算有多少行
  表锁   提供行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non-locking read in
SELECTs),另外,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如UPDATE table SET num=1 WHERE name LIKE "%aaa%"

说说异常的类继承关系

大概就是说的Exception和Error都继承于Throwable,然后Exception的子类又分RuntimeException和非RuntimeException,RuntimeException就是运行时异常,比如:NullPointerException、IndexOutOfBoundsException

而Error和RuntimeException属于Unchecked Exception,不需要try...catch处理

其他的属于Checked Exception,需要try...catch处理

Checked Exception一般是什么引起的?

程序不能直接控制的无效外界情况(如用户输入,数据库问题,网络异常,文件丢失等)

concurrent包用过哪些东西?

回答的ConcurrentHashMap

ConcurrentHashMap原理是什么?

大致说了下Hashtable和ConcurrentHashMap的区别,ConcurrentHashMap是存的段,段里面存的桶,加锁是对段进行加锁。(JDK8修改了实现方式)

ConcurrentHashMap默认桶的个数是多少?

这个没有注意看过,于是回答的HashMap是16个,ConcurrentHashMap不太清楚。回去看了下源码,都是16个。

悲观锁和乐观锁用过吗?

回答的没用过但是知道概念,比如synchronized是悲观锁,而Java的原子类比如AtomicInteger使用CAS乐观锁实现的。

后来面完才意识到这不就是用过么,当时sb了。

 

之后就是一些非技术性问题了,简单列举下,就不放我的回答了

你最看重一个公司的哪一点?

对加班怎么看?

平时怎么学习的?

之后的提问环节我问的面试官平时工作都做些什么。

整个面试过程大概20分钟,面完让我在等候区等通知。之后一等就是两个小时,接到通知都已经是12点了,然后给我们发了饭票,让我们去吃饭。

附上网易食堂照片

IMG_5252 IMG_5253

之前被通知下午一点半开始下午的面试,中午的时间就稍微把上午问到的问题查了下,一点半一到就被分配面试了。

 

二面

二面是个比较成熟的面试官,估计至少是leader级别的了

感觉二面就是压力面,面试是在一个很小的房间,大概5平米,和面试官的距离很近,可以清楚看到他的表情。

不过到了二面反而不紧张了,而且从面试官的表情可以看出你答得怎么样,感觉还是和面试官比较谈得来。

二面大概就是围绕项目和基础,不过挖得很深,你提到的东西一定要知道原理,不要抱侥幸心理,只要你说出来肯定会被深入的问下去,所以回答的时候要注意不要给自己挖坑,要尽量往自己知道的方向带。

二面大概面了40~60分钟,具体时间不太清楚了。当时我是关了手机的,没看时间。

做个简单的自我介绍吧

同一面

给我介绍一下你这个项目吧

就大概说了下这个项目是做什么的,以下问题都没有可复制性,我就只列出问题了

为什么要做这个项目?

你做的这个模块的结构给我说下吧

你对缓存后的结果做了测试吗?(期间说到了MyBatis缓存)

你觉得可以怎么优化你的模块?

期间提到了SQL优化,然后被问到了:

有哪些优化SQL语句优化方式?怎么知道优化的结果

这个问题答得不好,虽然看过但是不太记得了(又是MySQL!)

正解:(详细请看《深入浅出MySQL》第18章)

优化SQL语句的步骤:

  1. 通过show status 命令了解各种SQL 的执行频率
  2. 定位执行效率较低的SQL 语句
  3. 通过EXPLAIN 分析低效SQL 的执行计划
  4. 确定问题并采取相应的优化措施

优化方式:

  • 使用索引
  • 使用OPTIMIZE TABLE命令来进行表优化。这个命令可以将表中的空间碎片进行合并,并且可以消除由于删除或者更新造成的空间浪费
  • 优化INSERT语句:对MyISAM表,导入大量数据时关闭索引的更新,结束后开启,同时可以和LOAD DATA INFILE命令配合使用
  • 优化GROUP BY语句:GROUP BY 默认排序,可以通过指定ORDER BY NULL禁止排序
  • 优化ORDER BY语句:使用一个索引来满足ORDER BY子句,而不需要额外的排序。WHERE条件和ORDERBY 使用相同的索引,并且ORDER BY的顺序和索引顺序相同,并且ORDER BY的字段都是升序或者都是降序。
  • 优化子查询:有些情况下,子查询可以被更有效率的连接(JOIN)替代。连接(JOIN)之所以更有效率一些,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。
  • 对于含有OR的查询子句,如果要利用索引,则OR之间的每个条件列都必须用到索引;如果没有索引,则应该考虑增加索引。

MySQL有哪些引擎?MyISAM和InnoDB有什么区别?

幸好我面完一面就看了这个问题的答案,二面又被问到了。同上正解

你觉得可以怎么优化你的模块?

说了个实现算法的优化方案,面试官比较满意。

 

之后就开始问Java基础问题了

一上来就是一面的老问题。看来面试官之间并没有交流,JVM真的是送分题。

Java虚拟机的内存模型(这次审题对了)

Java垃圾回收机制

不过虽然和一面问题一样,但是面试官随时会打断你的描述,然后问一些更深的问题,比如

你用过哪些JVM参数?

你自己设置过使用哪个回收算法吗?

不过我当时说的时候也说得比一面要深入,所以并没有被问多少问题,感觉只要熟悉《深入理解Java虚拟机》这本书JVM这块就没问题了。

什么叫线程安全?

线程安全就是说多线程访问同一代码,不会产生不确定的结果。

线程有哪些状态?

  • New (新生)
    如用new Thread()创建一个新线程,这个线程还没有开始运行
  • Runnable (可运行)
    一旦调用start方法,线程处于可运行状态。系统会为这个线程分配它运行时所需的除处理器之外的所有系统资源。处于此状态的线程可能正在运行也可能没有运行,这取决于操作系统给线程提供运行的时间。
  • Blocked (被阻塞)
    当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态。当所有其他线程释放该锁,并且线程调度器允许本线程持有它的时候,该线程将变为非阻塞状态。
  • Waiting (等待)
    当线程等待另一个线程通知调度器一个条件时,进入等待状态,如调用Object.wait()方法时,需要等待其他线程调用Object.notify()或Object.notifyAll()
  • Timed waiting (计时等待)
    有几个方法有一个超时参数,调用它们导致线程进入计时等待状态。这一状态将一直保持到超时期满或者接收到适当的通知。
  • Terminated (被终止)
    因run方法正常退出而自然死亡。或因为一个没有捕获的异常终止了run方法而意外死亡。

Java使用锁的方式有哪几种?

synchronized、ReentrantLock、volatile

volatile的原理是什么?

我的回答:每个线程会将类变量复制一份到工作内存,当修改一个类变量副本时会立即写会主存,之后其他线程的此变量副本会变为过期状态,当其他线程发现过期时会从主存中重新读取。

大致没有问题,但是回答不标准。

正解:

有volatile变量修饰的共享变量进行写操作的时候在汇编代码中会多出Lock前缀。

Lock前缀的指令在多核处理器下会引发了两件事情:

  1. 将当前处理器缓存行的数据写回到系统内存。
  2. 这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。

为了提高处理速度,处理器不直接和内存进行通信,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完不知道何时会写到内存。如果对声明了volatile的变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。但是,就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题。所以,在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一
致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器对这个数据进行修改操作的时候,会重新从系统内存中把数据读到处理器缓存里。

集合你用过哪些?

ArrayList、LinkedList、HashMap...然后说常见的都用过。

HashMap是怎么实现的?

桶数组实现,每个桶是一个链表,然后说了一下JDK8对HashMap的优化,当桶中元素个数大于等于8时链表改为红黑树实现,可以防止hashCode攻击,然后解释了下什么事hashCode攻击,为什么可以防止。

JDK1.8有哪些新特性?

我先说了下接口可以有静态方法和默认方法了。然后面试官说,不要说语法层面的,说大方向上的。

然后想了下说对并发进行了优化,面试官让举例,于是举concurrentHashMap,修改实现方式,代码从2000行左右增加到了6000行左右。(表现自己看过源码,并且把话题扯开)

concurrentHashMap的实现原理

表明自己不太清楚JDK8的实现方式,但是知道JDK7的,然后面试官便问JDK7的,答案同一面。

 

然后就是一些非技术性问题:

除了写代码,你平时还喜欢做什么?

你怎么学习的?比如MyBatis怎么学的?

你最喜欢的一门课是什么?

二面没有提问环节,直接让我出去等几分钟之后问状态。

感觉我二面相对于网上其他人来说算是比较简单,也没有问框架原理的问题。

出去之后刚坐下几分钟就通知我去HR面了。

 

HR面

HR面大概就是做性格调查吧,随便聊了聊,大概就10几分钟,但是感觉有些问题还是要慎重回答,我的答案就不太慎重,因为过了2面整个人都放松了。希望不要因为HR面被刷。下面是大致问题:

自我介绍

你用过网易的哪些产品?

当你和团队中成员意见不合怎么处理?

有一个高管的位置空缺,而有另一个绩效和你差不多的同事与你竞争,你会怎么办?

如果这次内推没有通过,你会怎么想?

你父母是做什么的?

提问环节我问的如果通过,能否提前去实习。

问用过哪些网易的产品时我没有说网易传媒的产品被吐槽了,希望对结果影响不大。

 

Categories: 随笔