简单介绍下背景:本人已工作两年,这次属于社招,不是校招哦!投递的岗位base是北京。
先上正文
一面内容大概:先来道算法题,不难:链表表示的两个数相加。面试官说不用运行,大概写一下就行,说是因为说牛客上的运行环境不行。这题之前做过,写完之后没跑就直接给他了,他问是不是之前刷过,为了装逼我说没有刷过,然后回答说:这题不就是CPU的加法器的实现嘛,计算机组成原理。
Https的过程讲一下。先是说了http+ssl,dns之后,准备讲ssl的原理时,他示意我说回答一下传输层相关的。然后我就回答了tcp三次握手,对着服务器端指定端口,比如80端口发起连接,之后就是正常的数据请求了。
缓存穿透和缓存击穿。其实是知道雪崩、穿透和击穿的,但是一下子没直接说分清穿透和击穿,主要是太久没用过,突然觉得击穿和穿透,好像都差不多啊。
Go 协程简单用法;
Go func与method之前的那个Receiver是什么?(答:类似Java的实例本身,效果同java中的this关键字,同时在go method也可以把这个Receiver当做参数来正常使用);
java 实例放在哪个区,常量放在哪个区;
说一下Netty的IO原理,答:Reactor反应模型,Linux那边叫做IO多路复用。一个线程用来接收请求,将读写事件交给背后的worker线程。Redis、Nginx、Netty都是用到了这种模型。Redis其实也是多线程,只不过是用单线程来接收请求,在客户端看起来是串行接收执行,所以效果上就是单线程。但是IO多路复用才是Redis能高并发的底层保证。
MySQL left join、inner join:inner的就是差集、left的就是保左边;
Go的闭包语法,答了内部函数对外层函数局部变量的引用,类似的还有js、java的lambda;
Redis的setnx;(这个虽然只是提了一下,但是感觉没答好,需要加强。顾着准备Redis集群原理去了)
分布式锁的提供方,答:用过ZK和Redis的分布式锁;
项目相关问了不少,比如前家公司所负责项目的主要内容;
项目所产生的的一些价值,可以具体点,用一些案例或者数字来佐证都行;(这块没答好,接下来二面需要再整个关于项目经验的描述、个人所负责项目、产生的价值等,越具体越好,能有一些具体案例或者数据来支撑更好);
接上,总之,也要花点时间来回顾自己在之前公司的贡献和工作内容,越详细越具体越好,拒绝假大空;
算法题:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
二面大概内容:自我介绍,主要是说了工作经历,负责的项目的主要内容,越详细越好,把最能体验价值的结果或者报告什么的讲一讲;
TCP四次挥手,结合CS两端点的TCP栈和上层应用的交互来解释四次挥手,以及为何需要中间那个FIN-WAIT-2这个过程,最后由被动关闭一方的上层应用通过调用socket.closed()来结束数据传输,进入最终的FIN模式;
操作系统内存模型?这玩意儿不是就段页转换啥的嘛,面试官进一步提示说哪些区放数据,哪些区放线程数据之类的,我问了下您是问类似JVM内存模型那样子的吗?他说不是。我又说,那不是的话,我对操作系统内存模型的认知大概就是高地址空间存放内核数据,然后低地址空间对于进程来说就是个虚拟空间,拥有完整的寻址空间,这里存放着进程的数据和代码等,再细就不是很了解了,然后就跳过这题了;
算法题是股票买卖,一次和无限次两种。写出了无限次的情况,一次的一下子忘记怎么转过来,这题做的比较卡,整题至少有20分钟,哎。今天下午复习的时候还再次复习看了这个股票全家桶系列的解法呢,感觉只有看是不行的,要有充足的时间,就算没有从头理解,也要再默写一遍才算复习过。所以下次如果没有复习状态的时候,不要看着文字思路发呆,可以边默写边找回状态,嗯;
算法题:
给定一个数组代表股票每天的价格,请问只能买卖一次的情况下,最大化利润是多少?日期不重叠的情况下,可以买卖多次呢?
输入: {100, 80, 120, 130, 70, 60, 100, 125}
1)只能买一次:65(60 买进,125 卖出)
2)可以买卖多次: 115(80买进,130卖出;60 买进,125卖出)
输出买卖的序列和最大利润
三面主要内容如下:自我介绍;
介绍项目情况,重点说了近一年的工作项目的大概;
研究生在校的研究内容之类的,比较杂;
项目中的技术亮点:了解几个,面试官貌似对这些也不是很感兴趣,这估计也是后面他觉得我没有成长的原因吧,可能认为这些东西我在之前就应该都学会了的;
实现简单令牌桶算法,没有考虑随时间滑动的情况;
加强版:令牌桶,加上随时间滑动的要求,即:限制用户在任一连续的一小时内,不能超过5W的请求。这边提到了说将一小时分成多格,比如60格这样的,面试官点头貌似同意了,然后就实现代码了,包括协程异步更新时间窗口;
没有基础知识问答;
没有算法题;
三面反问环节,问:我咋样?(措辞是: 这简短的面试交谈过程中,您觉得我咋样?), 面试官说,我这一年来成长不大,几乎没变化,可是我觉得这一年来才是稍微有点儿进步的呀。
不过,经过这么一问,觉得反问环节也挺有意思,以后如果再有面试,反问环境可以多问些面试官关于我们自己的评价和看法,比如:上面说的您觉得经过这一小时的交流,我整体怎么样?如果像上面的面试官说最近一年进步不大,那么应该继续追问:那您觉得应该向什么方向去深入学习和思考比较好呢?态度诚恳一点就行,作为面试官人家还是乐意帮你指出不足之处的。
而上述的两个问题:我咋样和如何改,抛开offer不谈,这两个问题我觉得可以说是正常面试最大的收获了。而面试之前准备的那些知识毕竟比较零散,还是需要靠平时的积累来巩固。面试最重要的是让他人来评价你,以前没反问这两个问题的时候,这些评价人家面试官基本不会主动告诉你,只会整理一下然后录入到公司的人才管理系统,以供后续评价。
但你现在反问一下,就可以得知这两条信息,这些评价信息对你来说才是最有用的,放在公司它只是大量候选人评价数据中的一份,可有可无。但对你来说却是个宝贵的信息,你可以据此从别人的视角来审视自己,这种换个角度的审视比自己平日里思考写总结来得客观。毕竟你表现出来的才是客观的,内在的其他没表达出来的方面只能说你表达能力不行,也是种缺点,需要反思之一。
如果没有进行这样的反问,就不能更加全面的得知别人对你的看法,也就错过发现自己弱点和改正的机会,以前面试反问环节都是傻傻的问一些没多大意义的问题。今后应当多注意,要懂得跟面试官“要回”属于你的那份评价信息。
以上就是面试过程中涉及的一些内容,属于流水记账式的列了一下。
下面谈谈一些感想吧关于算法的考察。结合上述三面的内容,会发现对于社招来说,算法题的比重并没有特别大,相反,工作经验和项目这块的占比会更多,但也不是说不考核算法,该刷的题还是得继续刷,算法是基础;
关于工作项目的梳理,有几个感想。首先表达清楚项目介绍的内容,然后是价值所在,关于项目所产生的的价值和你所做的贡献,这个很重要,是衡量你价值的一个点儿。最好能够梳理一下过去的一些文档和报告,整个具体的数据和细节点来谈谈,避免假大空;
日常工作中,最好有意识的去参加一些高质量的bug交流解决当中,这样不仅能够在日后面试当中跟面试官交流,也能在当初解决问题的时候提升自己的能力。这类高质量bug的解决就属于技术亮点,很考验一个人的基本功;
自我介绍的时候,就不用说自己叫什么、哪里人、什么时候在哪个学校毕业之类的,直接说毕业之后在哪里工作,负责的项目是啥,然后就可以把提前准备好的关于上述第二点的内容都讲一遍;
上述的感想也是比较离散、杂碎。还想再分享一下个人的一些学习经验,欢迎交流指正。
学习经验
技术面结束之后,今后对于基础的知识的学习可能没有这几天这么紧凑了,短时间填鸭式的学习大脑有点忙,不过这种感觉也还行,接触到了新知识有点成就感。当你在浏览面经的时候,里面提到的问题你觉得你都会了,是不是也有种自我肯定的情绪呢。
不过,面经里面提到的知识都是比较分散的,毕竟在那么短的面试时间内,面试官也只能随机抽样的检查,没时间做太全面的交流。这也导致我们看面经的时候都是比较分散的知识点,所以需要在今后,持续的学习,每段时间都专心研究某个知识系列,系统性的学习比较有效果,也比较全面。比如MySQL、Redis、ZooKeeper、MQ、JVM、OS、网络、算法等。
就算法来说,它是需要长时间的积累,短时间内的突击效果不是特别大,也累。所以今后对于算法的学习可以这么来:每日一题、或者之前做过的题目每天拿一两题出来再做一遍,重新思考,深入的多看看题解体会体会,不再是赶时间的去冲量。学会总结,理解每个算法与数据结构的含义,时间久了就能做到不变应万变。
另外,算法大部分还是属于背诵题,不少题目把模板写出来就完成的差不多了,只需要把细节处理一下就差不多了。时间久了,这些模板题就变成条件反射,此时对高级的数据结构也会有进一步的了解,思考速度和解题能力都有所进步。
OS和网络也差不多,这三者属于平日工作都很少直接能够体现出来的知识,平日工作用得少,又没去复习时间一久就会忘记, 用进废退, 人之常情嘛。所以才像上面说的,应该要坚持每日一题、或者时不时挑一些做过的题目重新做做,主要是为了保持手感,而做过的题目拿出来再做一遍也不会花太多时间,这样在日常工作之余也比较容易坚持下来。
通过这段时间的面试准备,算是把算法入门,找到刷题的状态了,此后应该如上所说,坚持每日复习做做老题,偶尔周末时间充裕跟着“每日一题”做做新题,保持下去。
说回OS和网络,这类知识对于逻辑思维的要求没有算法题那么高,算法题属于“CPU相当密集型”,不练就不会。而OS和网络这类可能更多的是理解之后带点记忆的知识,做点输出存到笔记或者博客,定期来回顾回顾就行,属于“轻微IO密集型”,看完之后一段时间,也多少还有些印象,能够知个大概。每两年重看相关书籍,复习一下就可以巩固。
整个计算机体系,包括底层硬件组成原理、再上的操作系统和网络,这些之间其实都是有逻辑关系在的。可以OSI七层或者TCP/IP四层模型来看,它们就是个整体,全部理清之后,在大脑内可以存在相当长的时间。日常工作和生活中,只要遇到计算机相关的问题,大多都可以从这个整体来思考,这种思考也算是种回顾复习。
相比而言,算法算是比较离散的,排序、BFS/DFS、DP等之前的联系不是特别的紧密,至少没有像上述OSI七层模型这种递进关系相互依赖的情况,学习的时候也就可以单独知识点一个个击破了。
关于今后保持基础知识学习的想法,首先算法就如上述所言,每日一题、或者做过的题目重做,这样是为了不给本来就忙碌的工作日增加太大的压力,用简单的算法题来放松放松就行,搞几个AC找找成就感。
而对于基础知识,前期打算继续多翻阅翻阅面经,以面经中的题目为切入点,来复习(好像技术博客首页的文章也是个不错的切入点)。复习过程中再由点及面的去谷歌各种不明白,每个疑问点在输入谷歌之后,一次性多打开几个页面,多看多对比然后结合整理自己的理解,输出到日记或者博客中。
比如,最近看到个比较经典的题目是MySQL的隔离级别,这个问题谷歌一搜,大部分都有提到MVCC、当前读、快照读、行锁、间隙锁,都什么知识啊,反正对于工作经验尚浅的我来说,已经触及到知识盲点了。也好,这些点都记下来,一个也别想跑,然后再分别谷歌这些知识点,可能又会引出一些更加底层的、你没见过的知识点,也没关系,继续记录继续搜。
今后可能又会看到MySQL索引相关的面试题,搜这个的时候,也许会碰到MyISAM、InnoDB、B/B+树、磁盘IO块与系统页、主索引与辅助索引、m叉树的分裂与合并……之类的,这样对MySQL的认知又多了一些。过些时日,你可能想着完整的去学一遍,这时候买本《高性能MySQL》来看,而且你之前学到的隔离级别、索引它里面都提到了,并且更加全面和仔细,从基本概念的出现到最终的常用场景,都给你列出来了。
上述之所以要先从面经题目切入学习是因为个人在看书的时候,总有种大而全的感觉,书毕竟比较理论,面面俱到,有用的没用的都会列出来。而面经上的题目是面试官结合当下工作内容提出的,有可能就是他最近工作中遇到的问题,直接抛给你看你怎么思考。那么这种面经题目就比较有意思,贴合实际工作,能够更好理解,经过面试官这么一折腾印象也更加深刻。这种零散的知识点学的差不多了,再来看书,就比较有感觉,知道书中哪些地方是重要知识,哪些地方其实没那么实用作为了解即可。
其实,日常工作中不管是用到的知识,还是遇到Bug,所涉及的知识点也是比较随机离散的,类似上面浏览面经过程中遇到的问题,看缘分。而在项目排期不那么紧的时间段里,找本书系统化的把之前的碎片化知识点串起来,就很有必要了,既是总结也是巩固。
关于学习的另一个观点:
任何事物都是从小发展到大,学习的时候应该从它过去小的规模,跟着时间推移发展壮大,逐步去了解。比如学习Linux内核可以从早期低版本、JVM、Spring也类似,早期规模小,结构相对简单,比较容易理解。再逐步的按照发展需要,增加各种功能模块,直到当前最终版本。这样的学习路径可以清楚的知识系统中各个模块的由来与作用,也能够知道哪些是基础重要模块,而哪些是为了解决历史特定问题的模块,理清主线。
再举个例子,前些时候看到一篇关于限流的文章。文章一开始先从简单计数谈起,对于早期应用来说,简单的计数算法确实够用,后来随着业务的发展细化,简单计数粒度不够细,所以需要有类似滑动窗口这种效果的限流,也就衍生出了令牌桶和漏桶两种限流算法。
最后放上一个不错的记忆法——艾宾浩斯记忆规律,嗯就是小时候书上介绍的那个。新知识学习之后,分多次,每次不同间隔的去复习,大概十来次就能较好的将短期记忆转化为长久记忆了。而且学过之后,第二遍开始重新复习就简单多了,因为都理解过并整明白了,再重新复习更容易,更快,更省时。
之前考研的时候,背单词就隐约有用到这种方式。整本单词书,第一遍先花个三个月背一遍。之后,第二遍开始就越来越短,越来越快(这都什么虎狼之词)。前些时候背诵《道德经》也是类似,用了个APP,把每天背诵好的篇章截个图放到这个APP中,然后它会根据艾宾浩斯曲线的规律节点,定期提醒你复习。你要做的就是当它提醒的时候,打开快速默念一遍,默写一遍就可以勾掉了。还是那句话,第二遍越到后面,所花时间 就越来越短,越来越快。
以上,关于是学习方式和记忆方法的一些经验分享。
最后
最后再说句,任何工作和学习都是需要背诵记忆的,以此为基础来进行创作、推理和总结。比如何洁,他也是背过了大量的棋谱之后,再结合自身的想象力和逻辑能力,才有精湛的棋艺;比如钢琴家,也是需要背大量的琴谱、*,之后基于此再结合生活经验和灵感,来进行创作。巧妇难为无米之炊,脑中记忆的内容就是我们的大米,只有拥有大米,才有做出香喷喷的米饭的前提。并且大脑擅长的就是记忆,他就像是缓存,之前推理过的经历过的直接缓存在大脑中,之后如果再次遇见,直接查出来返回即可。
之所以还要再啰嗦的说下关于人尽皆知的记忆方法,是想强调任何学习和工作,它首要做的就是先去记忆,背一些概念。所以学习新知识的时候,遇到太多的概念不用慌,先背下来,背不住的就记在小本本上,常回顾。背到一定量之后就能产生质变,之后各种脉络也就慢慢打开了。
看完三件事❤️
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
关注公众号 『 java烂猪皮 』,不定期分享原创知识。
同时可以期待后续文章ing