[Java面经] 关于面试的二三事.
今天终于闲下来了, 那么也好总结下这几天面试的经历.
四天的时间一共面了七家, 有一家是自己推迟了没有去.
声明:如若转载请注明出处:http://www.cnblogs.com/wang-meng/p/5895787.html
因为我之前的博文我发现很多被转载都是没有出处的, 直接复制粘贴就变成了他们的产物..
先总结下这么几次面试下来的感受:
1, 先了解市场行情,给出自己的市场定位
了解你所找工作 的一些市场行情, 这样你就知道自己的一个水平是可以拿到一个什么价位了.
因为基本上每家公司都会提前对你的期望工资有个了解, 了解市场行情对你找工作也很有帮助.
2, 对于基础知识做好充足的准备
面试之前我以为面试官更注重于你的项目使用了什么框架, 以及这些框架的原理.
但是真实的面试是面试官都很注重你对于基本知识的理解.
后面会详细说到问了什么内容.
3, 好工作= 平台 + 薪资
当我们选择用人单位时一定要从这两个方面去衡量, 工资的多少固然重要, 但是平台对于我们自身的发展也很重要.
4, 面试过程中保持好的心态
我们面试过程会遇到各种不同风格的面试官, 我从第一场面试到最后一场面试也多多少少有些紧张, 有些问题自己是知道的, 可是当时头脑会一片空白.
在面试过程中我们需要调整好自己的心态.
================================================================================
下面就直接说下这几天的具体面试过程:
我是2016/9/14 正式办理离职的, 然后中秋节(15/16/17)过完, 在9/18日正式开始面试的.
2016年9月18 周日 上午 H公司
因为我自己投的简历大多是住处附近的, 所以刚开始并没有去检索这个公司到底怎么样, 这个公司招Java开发我就投递过去了.
当我第一天兴致勃勃 跑过去后才发现他们是做IT培训加一些外包的公司.
首先是收了简历然后做了笔试题, 在这里说下笔试题的内容:
1,堆,栈,方法区的区别?
2,创建一个类的几种方法? 四种方法. 具体答案百度都有.
3,删除一个文件夹中所有的文件? 写出代码.
4,序列化和反序列化的概念? 读取和写入一个序列化的类. 最后才知道是用ObjectOutputStream和ObjectInputStream. 因为我对IO操作看的不多, 所以这题直接放弃了.
5,两个sql语句, 类似于博客: http://blog.csdn.net/luoxiang183/article/details/52047832 (这个博文大家有兴趣可以看看)
6,abstract和native方法的区别?
上面的笔试题做了有五到, 那个IO操作的自己没有写, 还有第3题我只是知道用递归来遍历删除, 但是具体的代码写的并不好.
通过这个笔试题就暴露出了我的一些缺点, 自己对IO这块有些空白, 所以导致笔试题做的并不好, 最后的话就是面试官和我聊了一下他们公司的情况, 包括培训, 包括他们所做的项目.
第一场的面试之后自己心里还是挺失落的, 一点自信都没有, 可是无论怎样 路还要继续走下去, 于是便回去 准备下下午的面试了.
2016年9月18 周日 下午 R公司
这个公司并不是我自己主动投的简历, 这是一加外包公司, HR在招聘平台看到我的简历主动和我联系的, 于是我下午就直接过去了.
首先是做了笔试题, 笔试题是他们公司17年校招的笔试题, 都很简单而且很基础, 做完之后就直接安排面试了.
面试的人是他们的合作方. 首先是技术一面, 面试官是个很nice的大叔(30岁左右), 主要就问了我一些项目上的东西:
因为我上一个项目是做的类似于电商的网站, 也是客户外包给我们做的, 而后期我自己从网上找了一些学习资源自己又针对于电商这块做了更深入的了解, 大家可以看我前阶段的博文都有写. 所以我对项目这块使用的技术及实现方式都是挺了解的.
1, Q: 你们购物车模块是怎么实现的? A: 我从用户未登录以及登录的两种情况分析. 未登录又有两种情况, 以及我们当时是如何考虑, 选择哪一种方案的角度去给他说, 然后又具体的说了购物车的原理, 其中提到这个地方会使用到Redis.
2, Q: Redis使用的场景及好处是什么? A: 我给他详细的说了我们在项目中的哪些地方会使用到Redis, 以及Redis相比于传统的关系型数据库的优点, 然后就是Redis在我们项目中是如何使用的, 包括如何去操作Redis.
3, Q: 你们项目中使用的Nginx集群是如何搭建的? 它是如何做到负载均衡的? A: 这个问题我就先从为何要使用Nginx来说起, 然后讲了什么叫Nginx反向代理, 接着讲了如何搭建Nginx集群, 以及我在项目中关于这块的职责.
4, Q: 你们这个Dubbo是做什么使用的? A: 关于这一块我首先说了我们的项目是由多个子系统构建的, 然后说我们系统中的一些调用需要使用到Dubbo, 最后对比了Dubbo与WebService的区别.
5, Q: 面试官问我是否了解集合的一些类? A:我说我看过一点HashMap的源码, 然后讲了HashMap中的数组和链表结构, 以及HashMap是如何自动扩容的, 以及扩容带来的好处(空间换时间), 然后就是put/get是如何实现的等.
(关于HashMap问的真的很多, 建议大家有时间一定要看下源码, 这里给出一个总结的很好的博文: http://blog.csdn.net/luanlouis/article/details/41576373)
6, Q: 内存泄漏和内存溢出的? 怎么使用工具去调试内存泄漏和溢出? A: 由于这个我真的接触不多, 我只是说了什么情况下会出现内存泄漏和内存溢出, 每种情况举了一个例子. 关于如何调试我直接说我有了解是通过生成dump文件 然后去调试.剩下就不知道了.
问到这里面试官就没有再问我具体的技术问题了, 于是便开始扯起了家常, 问我是哪里人, 哪个学校毕业的, 然后让我问他一些问题:
首先我问了他们项目是具体做什么的, 然后针对于他说的内容又问了他们主要使用了什么框架, 再就是问了项目的人员组成结构. 这里面问了好几个问题, 最后还是聊得很融洽
就这样一面救过了, 然后就是二面.
二面是个待了十几年的项目组大牛, 二面的话基本没有问太多的技术问题, 基本上就是聊一聊我在上个公司做的东西, 以及为什么要辞职, 以及我的一些价值观的东西, 聊了半个小时之后 就基本上结束了, 最后人事来找我 就开始谈薪资待遇问题了.
这一家的面试还算挺轻松, HR给的薪资也挺诱惑, 但是他们所做的项目并不是我特别感兴趣的, 还有一点就是二面的项目主管说他们加班到11/12 点是常事, 而且是经常性的. 还因为我后面还有几家公司要面试, 所以我就说我下周五给答复.
(在这里要着重强调一点: 想好你的离职理由, 这一点真的很重要, 很多公司也是比较看重这个的.)
================================================================================
2016年9月19 周一 下午 L公司
因为我一开始并不知道这个公司所处的那个位置是不是很远, 所以我一大早就打车过去了, 最后才知道也很近, 因为他们公司是九点上班, 我的面试是九点半, 我八点就到了这个公司楼下, 于是我就在外面等了好大一会, 到了九点我才进入公司面试.
首先是给我一张表格, 上面有你自己的期望薪资, 我写下自己的期望薪资, 然后他们人事看了后 说我写的期望薪资有点高, 剩下的就是给我拿笔试题.
笔试题也不是很难, 做完了后便开始面试了.
1, 类加载的生命周期?
2, arrayList的扩容方式?
3, spring事务的优点?
4, getParameter和getAttribute的区别?
5, group by的使用?
6, onload()和ready()的区别?
7, 项目中的一些问题.
基本上我记得的就这么多, 只要做过一些准备的话 这些面试题都不是问题, 面试也谈的比较融洽, 最后人事找到我说我开的薪资有点高, 并说了他们能够接受的一个最高值, 然后我就是说我还需要考虑一下, 然后周五给他们答复.
2016年9月19 周一 下午 B公司
这个公司是一个猎头给我找的, 做车联网方面的开发的, 这个地方离我住的地方还是有些距离的, 所以中午面试完后直接在外面吃了点饭就去了. 到了面试的公司发现还是去的有点早, 于是便在公司楼下到处晃悠, 期间还发现了不少漂亮妹子(哈哈, 有点扯远了, 自己也是在减缓自己的压力)
进入公司首先也是要做笔试题, 在这里要好好说下这个笔试题:
笔试题包括30个选择题 和几个简答题, 选择题用的是英文, 而且全是多选题, 所以我的笔试题做的并不好.
简答题并不难, 最后一个关于IO操作且写出代码的题我也空着没有做.
剩下的就是面试了, 这次是一下来了两个面试官, 估计是一面二面全都一起来面了.
面试内容是第一个面试官把笔试题从头到尾的先问一遍, 然后第二个面试官把简历从头到尾的再问一遍. 最后是他们再自己按照自己笔记上的内容问一遍. 所以这场面试持续的时间有点长. 在这里写上几个我回答不好的问题.
1, SpringMVC 怎么添加过滤使得避免空指针? 这个最后才知道可以在javabean上设置注解设置这个字段不能为空.
2, 你们项目在什么情况下会使用多线程? 这个我确实没有接触过, 所以直接说多线程我在项目中接触的比较少.
3, 如何通过反射去调用一个类的私有方法? 这个是需要setAccessible()方法来抑制Java访问权限的检查的, 当时觉得前面的问题被问的懵逼了, 大脑也一片空白.
剩下的就不太清了, 总体的话面试还是问了比较多的问题, 大多我都能够很好的回答上来, 这场是让我感觉最压抑的一场面试, 但是自己也接触到了这么一种新的面试体验, 总体觉得自己还是收获很大的.
最后面试官看了我的期望薪资, 也说我写的有些高, 然后就是让我回去等结果. 我就知道自己肯定是挂了, 第二天早上就收到邮件说面试不通过. 我没多想, 仍然在准备接下来的面试.
================================================================================
2016年9月20 周二 上午 C公司
这家公司是一个国企, 也是猎头帮我找的, 早上起了大早, 坐了半个小时的车才到这家公司.
这家公司是一个独立的园区, 绿化很好, 占地面积很大, 当时就觉得这个国企好有钱.. 最后才知道其他的办公楼只是他们母公司旗下的, 他们的研发部只有一层楼 30多个人.
填写了面试基本信息表后就是直接安排面试了, 并没有笔试环节.
面试过程中面试官就问了三个问题.
1, 你对Spirng的理解? 我说了Spring的基本核心内容, 然后说了我们项目中是如何去配合其他框架使用的.
2, 你们负载均衡以及集群是怎么搭建的? 我给他讲了Nginx的原理以及如何搭建的, 以及这样做的优点. 然后讲了我们的系统是如何构建的, 以及为何要使用集群.(其实这些问题在上面几个公司我都回答过)
3, 你们购物车这个是如何做的?(因为我的简历中的项目中写的有我负责购物车这个模块) 然后我就给他讲了一下具体的实现以及用到了什么技术, 其实这些上面几家公司也有问到
问到这里他就直接给我说他问完了,到这里我心里就在打鼓, 我回答的还可以啊, 面试官对我不满意? 然后他让我问他一些问题, 我接着就问他他们项目组的一些具体问题, 感觉我问他的问题比他问我的问题还要多.
这个是HR和面试官坐在一起的, 然后HR就给我讲了下他们公司的发展前景,最后还说了他们的薪资结构, 然后就让我回去等通知了.
同样的, 我以为等通知就是没戏了, 谁知道第二天给我打电话说我通过了, 然后说能够给我的是年薪XX, 而且他们的五险一金全都是按照最高标准去交, 当时听了真的很激动, 当时由于已经确定签约另一家公司, 所以还是和这个公司表示了感谢, 拒绝了这份offer.
2016年9月20 周二 下午 L公司
我现在不想那么盲目的再去找面试了, 百度了这家公司发现网上骂声比较多, 而且这个公司规模也不是很大, 于是我便给这个公司打电话 表示自己去不了啦, 然后表示了自己的歉意.
面试完C公司我就回家睡觉了, 感觉这几天一直在跑 真的很累, 因为暂时还没有找到一个心仪的公司, 所以压力真的很大, 每天不想吃饭, 觉也睡不好.
================================================================================
2016年9月21 周三 上午 CQ公司
这个公司是在我住的附近, 所以踩着约定的时间到了这家公司面试, 公司里面面试者比较多, 我是先做完笔试题, 然后就排队等着面试了.
面试是在中午十一点, 因为后面等待的人还是很多, 所以面试官就面试了30分钟左右, 主要还是问了我一些项目上的内容, 我感觉还是回答的不错的, 最后到了饭点就让我回去等人事通知了.
第二天人事打电话想让我去签约, 开出的薪资还可以, 而且有2-4个月的年终奖.每年需要出差四个月.
因为下午的时候是签约了另一家公司, 所以这一家自己也是推掉了.
2016年9月21 周三 下午 M公司
这一家公司是我最终选择的公司, 无论平台发展和薪资要求都是我很满意的.
首先是进入公司, 感觉公司的环境非常好, 因为提前在网上有对这家公司有过了解, 也用过他们的产品, 所以还是很想进入这家公司的. 我相信大家也一定用过他们家的产品, 这里我就不方便具体透漏了.
首先就是开始做笔试题, 笔试题 并不是很难, 做完后就开始面试了.
一面: 人事面
这里又和我之前面的几家公司不同, 第一轮是人事面, 问的问题就是为何辞职, 问了自己的人生规划, 问了自己的价值观的一些东西, 聊得还挺融洽, 紧接着就是二面了.
二面: 技术一面
面试官确实让我感觉到是个大牛, 他并没有 看我的简历, 只是针对于我的工作经验来问了我三个题.
1, 我们服务器在启动的时候 一瞬间有1000个访问, 那么如果使用一个HashMap去存储的话 你会设置初始值为多大?
其实这个问题我并没有正面的去回答设置多大的初始值, 我给他说了一下HashMap扩容的原理, 并说到了HashMap的阀值是和初始值大小和加载因子相关的, 然后说道要权衡空间复杂度和时间复杂度的情况.
感觉他对这个问题的回答还是比较满意的.
2, 我们是有700W的日活, 如果有一个方法的参数是(String cityCode)查询的话, 怎么去保证同步?
我说的是加synchronize或者加Lock, 接着他就问我这两种的区别, 问他们的性能哪个好. 然后我说在这个案例里面我们可以加Lock, 然后他就问我怎么加Lock去控制颗粒度来达到最好的效果?
到了这里我真的是不知道了, 因为压根就不太了解Lock的机制, 但是他说没关系, 然后想一下怎么去做, 还提示我这个可以引用HashMap的设计思想.
最后我想的就是这里对cityCode进行分组, 通过组去定位具体要查询的cityCode的位置. 对于这个答案他听后 觉得是可以提升一些性能, 但仍不是最好的.
最后的话给我说了下hash碰撞, 通过hash值取模来去颗粒度更精细, 其实这里我知道hashmap中也是通过hash值去定位数组的位置的. 这个问题就到这里了.
我自己又找了下HashMap中关于hashcode定位桶的位置的方法:
1 /** 2 * 根据特定的hashcode 重新计算hash值, 3 * 由于JVM生成的的hashcode的低字节(lower bits)冲突概率大,(JDK只是这么一说,至于为什么我也不清楚) 4 * 为了提高性能,HashMap对Key的hashcode再加工,取Key的hashcode的高字节参与运算 5 */ 6 static int hash(int h) { 7 // This function ensures that hashCodes that differ only by 8 // constant multiples at each bit position have a bounded 9 // number of collisions (approximately 8 at default load factor). 10 h ^= (h >>> 20) ^ (h >>> 12); 11 return h ^ (h >>> 7) ^ (h >>> 4); 12 } 13 14 /** 15 * 返回此hashcode应当分配到的桶的索引 16 */ 17 static int indexFor(int h, int length) { 18 return h & (length-1); 19 }
3, 有两个数字A,B, 他们都是有500位的数字, 如何规定不能使用BigDecimal 去运算的话怎么求的A+B的结果? 并写出代码.
这个是需要当场写出代码的, 而且他也不给我任何提示, 需要我自己想.
这个问题真是让我懵逼了,想了十多分钟,还是感觉自己的应变能力不够, 本打算放弃的, 最后还是想到了HashMap这个玩意, 哈哈, 感觉他好神奇.
思路: (我当时想到的思路, 不一定正确)
1 Map<String,int> a1Map = new HashMap<String,int>(); 2 a1Map.put("a1",1234567890111111); //value值装入小于int类型能够接收到长度 3 Map<String,int> a2Map = new HashMap<String,int>(); 4 a2Map.put("a1",1234567890111111); //value值装入小于int类型能够接收到长度 5 ... 6 Map<String,int> b1Map = new HashMap<String,int>(); 7 b1Map.put("a1",1234567890111111); //value值装入小于int类型能够接收到长度 8 Map<String,int> b2Map = new HashMap<String,int>(); 9 b2Map.put("a1",1234567890111111); //value值装入小于int类型能够接收到长度 10 ... 11 12 int c1 = a1Map.get("a1") + b1Map.get("b1"); 13 int c2 = a2Map.get("a1") + b2Map.get("b1"); 14 if (c12.length() > a2Map.get("a1").length()){ 15 c1 += 1; 16 } 17 ...
我的思路大概就是这样, 先将500位的数字进行分割, 然后分割后的数字进行相加, 这里需要判断进位, 我也不知道对与不对, 但是这样的方式是很麻烦的. 最后面试官听了我说的后说这样也是能够实现的, 但是很麻烦.
最后他说使用for循环遍历, 然后让每个数字相加, 得到的结果反转一下就可以了, 具体的让我回去后百度一下.剩下的就是他让我问他问题, 然后就是聊了一下公司文化, 以及他对这个工作的理解, 聊得时间还挺长.
我百度了一下并没有找到类似的题目, 于是自己回来写了一下, 并不保证结果一定正确, 如有异议请给我回复.
更新(2016/09/22) 我自己写了下代码, 现在贴出来:
1 /* 2 * 需求:两个数字A,B都是有500位, 现在完成它们的相加操作, 不能够使用BigDecimal 3 */ 4 public class TestPlus { 5 public static void main(String[] args) { 6 //这里设置A,B的长度都是3, 不使用int 不使用BigDecimal 7 String a = "12327845678343288"; 8 String b = "45643524555671269"; 9 int c = 0; 10 LinkedList value = new LinkedList(); 11 //判断是否需要进位 12 boolean isNeedCarry = false; 13 14 for(int i = a.length() - 1; i >= 0 ; i--){ 15 //如果需要进位, 那么则给需要进位的数字加1, 然后取第二位. 例如相加后的结果为14, 进位加1位15, 则取5来显示. 16 boolean isAdded = false; 17 c = Integer.parseInt(String.valueOf(a.charAt(i))) + Integer.parseInt(String.valueOf(b.charAt(i))); 18 if (isNeedCarry) { 19 isAdded = true; 20 value.addFirst(String.valueOf(c+1).substring(1)); 21 c += 1; 22 } 23 24 isNeedCarry = addCarry(c); 25 if (isNeedCarry) { 26 if (!isAdded) { 27 value.addFirst(String.valueOf(c).substring(1)); 28 } 29 }else { 30 value.addFirst(String.valueOf(c)); 31 } 32 } 33 34 for (Object object : value) { 35 System.out.print(object); 36 } 37 } 38 39 //判断是否需要进位 40 public static boolean addCarry(int i){ 41 boolean isNeedCarry = false; 42 if (i >= 10) { 43 isNeedCarry = true; 44 }else { 45 isNeedCarry =false; 46 } 47 return isNeedCarry; 48 } 49 }
感觉这个题就是考你临场的一种应变能力, 现在想想这个题目并不难, 主要在于你怎么想. 而且是在那样的一个环境下, 所以说心态很重要.
就这样一面完了, 我以为自己要挂了, 因为自己答得并不是太好. 没想到 一会又来了个面试官对我进行二面.
三面: 技术二面
二面的面试官是一个很风趣的人, 这次他是对着我的笔试题和 简历来问一些问题, 问的问题都是延伸的问题比较多.
比如看我做过购物车模块, 就问我做没做过秒杀模块, 看我做过商品模块, 就问我对于库存了不了解.
当我说不是太了解后 就让我当场想一下应该怎样去实现, 总之面试过程还是很有意思的.
这里我感受到的就是他们的思想很新潮, 他们更注重的是一个人的可塑性, 二面也很快面完了, 感觉这次面试官对我还是比较满意的, 紧接着就是人事来进行最后的四面了.
四面: 人事二面
这里更多的就是聊了一些公司的发展, 公司的待遇 以及我离职的主要原因.
这里一般都是聊这些内容, 最后我同意和他们签约, 然后下周一直接入职.
最后趁着这两天时间好好休息. 通过这些次面试真的感觉自己有太多的不足, 很多基础知识自己掌握的并不是很扎实. 在以后工作中一定会更努力去沉淀自己.
如果也有最近面试的小伙伴 希望我的文章能够对你们有一些帮助, 祝你们都能找到自己心仪的公司.