**2019年对我而言必定是人生当中最重要的一年。因为实习的原因,我第一次体验了北京和上海的生活,匆匆且忙碌。这一年生活当中充斥着各种求职咨询,面试,做题,仿佛一夜回到了高三。不过,我是幸运的。从寒假实习开始到暑假实习再到秋招,一路以来我并没有体会到太多的挫折,一路高歌,最终也收获了我自己认为还不错的offer。也许是因为运气,也许是因为坚持,但是硕士这2年来我也经历了种种心酸和波折。我起初走过很多弯路,在无数个深夜里苦恼自己的无知和弱小,曾跌入低谷,连续数天的低沉,最终慢慢调整,告诉自己不能松懈,直到现在…
** 我希望可以把我从实习到秋招这一路以来的体会和经历分享给大家。作为一个还没有正式进入公司的在校学生,我在技术上还是一个实打实的”菜鸟“,但是作为一个应届求职者,我是"专业的"。本节我将从面经积累,价值观以及学习路线这三个角度介绍我的经验。
我有一个习惯,就是记录和整理知识。从春招实习开始,我每一次面试都会录音,事后都会复盘。所有的面试记录,面试官问的问题,手写的算法题以及我个人面试的感受我都会记录下来。看过《深入理解计算机系统》的小伙伴都应该知道程序的执行是有空间局部性和时间局部性,其实面试官考察的知识点的范围也是如此。当你多次遇到同一个问题的时候就应该去把它记录下来。与其面对茫茫多的知识,不知从何入手,不如将自己遇到的问题一个一个”缓存“起来,建造一个属于自己的知识”字典“。当你的知识"字典"足够系统和完善,你就足以收获理想的offer。我的积累方案如下:
1.面试录音,及时复盘
2.事不过三,重复出现的问题单独归纳和整理
3.知识串联,通过关联的方式加强对琐碎知识点的记忆
我认为没有最好的学习方案,只有最适合自己的方案。
实习和秋招的面试过程都是一场又一场的持久战,我在2年前也和大家一样对面试畏惧,对学习恐慌,非常迷茫。很庆幸自己走过了这2年,在此我会将我自己的学习方法和面试经验总结给大家。整个学习路线分为以下几个部分:编程语言学习,操作系统学习,服务器编程学习,计算机网络学习,分布式数据库学习,其他方面学习。
编程语言千万种,到底该学哪一种?
我认为语言不分优劣,只分喜好,只看需求。本硕这几年我学过C/C++,JAVA,Python,Matlab,Golang,Javascript,用来用去还是C++和Golang适合我,但是我也不排斥去使用其他语言。
学习编程语言第一步:上课。如果你是刚入学的小白,那就去好好上课吧,计科老师说的一定比我好。如果你已经错过时机或者没办法天天去教室里上课,那么网课是我最推荐的。
在哪里可以搜索合适的课程:
我个人主要使用的语言是C++,所以我以C++学习为例:C++不容易学好,如果仅仅是学习语法或者写个算法题那一两周可能就可以上手。但是想用好C++还是需要很长时间的coding和源码阅读积累。我个人的方案是先看书,再实践,再看书这样的不断循环。道理大家肯定都懂,但是能够坚持做下来的太少了。
给大家推荐我看过的几本C++相关的书籍:
C++项目那么多,到底该看哪一个?
只看书不coding永远都是空中楼阁,而且C++的知识点非常多且琐碎,一种需求可以有多种实现,如果不实战真的很难发现其中不同之处。所以需要一些项目练手。如果大家和我一样是后台开发方向,那么可以去找一些网络服务器相关的项目去练手,一方面可以加强对Linux操作系统的理解,又能增加网络知识,同时也可以锻炼C++ coding能力,一举多得。那么有哪些值得做的项目呢?
1.做别人推荐的好项目:
WebServer
我在实习前看的是大佬 (牛客id:健康成长天线宝宝啊 )的个人项目WebServer:https://github.com/linyacool/WebServer。基于他的项目和我后续看书的总结,在1-2个月的时间里我也实现了一个web服务器,这个项目是我简历上除了实习项目之外被问的最多的项目。
2.看STL源码:
STL源码,有各种C++高级技能的实现。推荐大家去看看STL里的快排实现源码,第一次看到真的很有意思。
3.开源项目:
下面是几个还不错的开源项目,如果当前有不错的基础可以去通过源码学习:
libevent:Libevent是一个轻量级的开源高性能网络库,采用事件触发,封装了以下三种事件的响应:IO事件,定时器事件,信号事件。
Memcached:Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态数据库驱动网站的速度。
Redis:Redis是一个基于纯内存的存储系统,虽然是C写的但是值得一看。
切记,项目当中实现功能只是一方面,测试和文档整理也很重要,项目的每一步都需要文档和数据的支撑。
Linux发展到今天,早已超出我们的想象。如果不是想专门做操作系统这块的话,我的学习经验也许可以借鉴。首先我推荐大家看这本**《深入理解计算机系统》** :
这本书十分经典了,每一次看都会有新的领悟,本书对于计算机体系结构的讲解非常细致,有很多非常有意思的Lab。这本书从程序执行的计算机角度开始,介绍了处理器的体系结构,程序的机器级优化,虚拟存储器,系统级IO,网络等等多个方面。推荐大家和 CMU 15-213 CSAPP 这门课一块看。
其次再推荐2本书:
《Linux内核设计与实现》: 建议和操作系统原理的课本结合一起看
如果是面对秋招,我总结下来以下这些关键知识点是需要理解的:
Linux环境如何搭建
学习操作系统当然要配合Linux一起, 过去一般建议大家装个双系统比如Ubuntu16.04。如果大家觉得双系统麻烦或者虚拟机慢,那么我还有以下2种方式让大家在几分钟之内就可以获得一个稳定的Linux开发环境:
方法1: 买阿里云、腾讯云、华为云的服务器。买最便宜的,可以不用关机,远程ssh登录即可,无论手里是什么平台的系统,都可以一秒进入Linux,这也是我常用的方式。
方法2: 安装docker,花10min学习docker基本概念和操作,用docker安装Ubuntu16.04的镜像,然后进入容器。这个方法也是跨平台的,非常的简易,我会在后续专刊当中单独介绍docker的原理和使用方式。
服务器编程其实就是建立在对linux系统调用的理解以及网络协议的理解上的。如果这两块的知识比较好的话就可以动手实现一些简单的服务器,然后对比别人实现的,压测一下性能,这样就可以作为一个个人项目。下面几本书我建议大家可以选看:
还有很多不错的开源库的实现,比如muduo库。造造轮子也能成为自己的一个项目,推荐大家在有时间的情况下去看看。
计算机网络这部分,我最开始看的是浙大的计算机网络课程。主要是专注于协议的原理和分层模型理解,因为计算机网络的原理还是比较琐碎的,建议大家多做些笔记和文档,不论对于记忆还是日后的复习都是很有用的。下面4本书值得一看:
计算机网络主要的常考知识点如下:
TCP/IP
1.分层模型
2.三次握手、四次挥手原理
3.拥塞控制
4.流量控制与滑动窗口
5.TCP与UDP比较
6.DDos攻击
7.close_wait,time_wait状态原因
HTTP
1.http/https 1.0、1.1、2.0
2.get/post 以及幂等性
3.http 协议头相关
4.Cookie Session 的比较
5.长连接与短连接,websocket的对比
Socket
1.IO模型
2.select ,poll,epoll原理和对比
如果只是会MySQL基础可能是远远不够的,像是Redis,MongoDB等非关系型数据库也是当前的热门。分布式数据库,分布式存储是当前每个大公司都会非常重视的核心,所以数据库基础非常的重要。
数据库常考知识点:
MySQL相关
1.索引:B树、B+树底层结构,索引失效条件
2.sql语法
3.关系型数据库三范式
4.存储引擎:InnoDB和MyISAM对比
5.数据库的锁:行锁,表锁,页级锁,意向锁,读锁,写锁,悲观锁,乐观锁等等
6.数据库隔离级别:脏读、不可重复读、幻读
7.事务的ACID理论
8.查询优化:explain,慢查询,show profile
9.分布式:分库分表,读写分离
Redis相关
1.Redis 特点
2.Redis 底层数据结构:跳表,字典
3.数据淘汰策略
4.持久化方式:AOF,RDB
5.哨兵模式
6.集群同步方式
由于篇幅原因在此我不会把每一个方向和知识点都详细罗列,如果各位有兴趣可以看我在春招实习写的学习路线:
后台开发/基础架构方向 学习路线
最后我想说:秋招 = 心态 + 实力 + 面试技巧 + 运气
心态:建议大家保持一个积极的心态,不轻视自己也不高估自己,脚踏实地做好自己;
实力:建议大家加深自己某一个方面的深度,拓宽技术面的广度,只有深度+广度才能脱颖而出;
面试:我会在后面的专刊当中专门给大家分享我的面试技巧,希望大家可以参考;
运气:作为求职者我们没有足够的信息,无法预知某个公司岗位的难度,不要嫉妒别人的轻松,机会只给有准备的人,努力的人运气一般都不会差;
我目前还在慢慢的职业摸索阶段,也还是一个菜鸟而已,如果有任何错误的地方也欢迎大家指正修改。我的方法和经验不一定适合所有人,如果这篇文章真的可以帮助到未来求职的你也就达到我的目的和初衷。愿大家一起进步。
相信很多人和我一样,都是非科班出身(计科/软院),没有在最开始的时候接触最基础的算法课程和训练。我一开始也很苦恼,在硕士阶段才来弥补,一方面面对科研的压力平时时间很紧迫,另一方面不知道有哪些合适的资源可以去提升自己,往往浪费很多时间在找书找课上。网上的公开课很多很多,算法教程又是一大堆。同时网上刷题的OJ那么多,题目又是海量,到底该怎么入手?本文就将从我个人的痛点切入,介绍下我认为的比较好的算法学习策略,在本节最后我也对我秋招遇到的算法题做了一个总结。
个人总结下来,初期学习算法有以下几个痛点:
1.编程能力不足。初期由于编程能力不足会导致眼高手低,看着都会,写起来很费劲。
2.过于心急。很多同学在早期就想进入刷题阶段,算法基础还不扎实,题目类型都不熟悉,匆忙刷题只会打击自己的自信心。
3.效率低下。比如一开始就去看《算法导论》这样的大而全的书,会导致时间成本太高,效率很低。
4.选择困难。市面上太多资源,算法课,OJ,如何选择成为初期最大的困难。
5.定位错误。应对秋招的算法要求和算法竞赛的要求是不一样的,很多人缺乏明确的定位。
6.缺乏策略。很多同学因为没有策略,花了很多时间但是算法能力提升缓慢。不能用战术上的勤奋来掩盖战略上的懒惰。
算法能力不是指算法工程师的能力,算法能力是一项通用的基础能力,指的是对于基本算法和数据结构的了解程度和解决通用算法问题的编程能力。
所以:算法能力 = 数据结构 + 基础算法 + 编程能力 + 逻辑思维。
数据结构:对基本数据结构的设计思路,使用场景,性能特点的熟悉程度。
基础算法:对基础算法的设计思路,使用场景,复杂度的了解程度。
编程能力:代码编写,边界检查,调试能力,优化能力。
逻辑思维:题意理解,过程推导,解法分析,性能计算。
算法能力是比较容易量化的,一般来说对于大部分人,你能够解决LeetCode上全部easy题和大部分中等难度题,就可以应对大部分国内互联网公司的应试要求,再细化来说就是LeetCode 400-500题量水平。
如今国内互联网公司越来越喜欢考察应届生算法知识,体现在这几个方面:
1.增加手写算法题数目;
2.手写算法题的结果直接决定面试是否通过;
3.算法问题深度增加;
以我个人实际经历来说,大厂的面试尤其会在第2点体现更加突出。就阿里来说,阿里的技术面试会在正式开始前,面试官会通过邮件发一道算法题,只有应聘者在规定时间内完成手写算法题,才会开始后续面试内容。这意味着,算法题将成为第一道门槛。目前我面试过的公司当中算法比重较高的几家公司如下:字节跳动,依图,商汤,小马智行等等。
面试算法题一般不会很难,和算法竞赛的要求差别很大,如果简历上没有出现ACM等算法比赛获奖经历,面试官是不会特意为难。面试考察的是算法的基础知识和编程基本功,题目一般简短明确,容易理解,甚至是往年的原题,但是往往隐含边界分析,bug排查,所以需要谨慎小心。
我把算法学习的过程分为2个阶段:
阶段1:课程学习阶段:这个阶段我建议先找一些比较靠谱的视频或者公开课去学会比较好。如果学校里的课还不错可以去上学校的专业课。如果不是计算机或者软院的学生,有条件的可以蹭课,以下是计算机专业的必修基础课程(选自南京大学计算机本科教学计划):
课程名 | 课程名 | 课程名 |
---|---|---|
计算思维 | 计算机系统基础 | 计算机网络 |
程序设计基础 | 数据结构 | 软件质量保障 |
离散数学 | 算法设计与分析 | 数据库理论 |
数字电路 | 软件工程 | 高级程序设计 |
计算机图形学 | 概率论 | 编译原理 |
密码学 | 操作系统 | 网络安全 |
其中我认为和算法相关最重要的课程如下:
如果没有实际上课的条件我推荐网课的方式,下面是我学习的课程:
如果有条件***可以去YouTube上看,如果没法***也可以在B站上看,好处就是有字幕不用自己人肉翻译,同时多终端都可以看,比如地铁上可以拿出手机看,也是非常好的学习积累的方式~
同时也建议大家在看完相应课程的时候看一看书去巩固知识和增强细节的记忆:
如果你时间不够,那么牛客网左神的算法课你就不能错过了。非常系统和直接,都是干货。很多的面试题在左神的课上都有讲解。我个人建议有条件的同学可以刷1-2遍,尤其在春招实习之前。左神的课很系统,能够很好的把前面的知识点串联起来。
阶段2: 刷题阶段:基础学完之后,就需要大量的刷题。我不推荐每天没日没夜的刷,我也曾经这样一天刷十几道,但是效率其实不高。我建议在有一定题量后每天写个1-2题就足够,难度leetcode中等。重要的是刷完题之后的积累!尤其是如何优化代码的思路和边界分析,不要去一味的追求题量。切记题目是永远也刷不完的。
刷题策略:
1.记录解法。我个人的做法是将每次写的题目和代码同步到Github上,通常1题会写1-2个解法,如果遇到特殊思路会将思路的关键词贴在commit上。一是方便自己查找,二是方便在日后遇到同样的题目时可以快速回忆解法。
2.限时做题。在刷题时需要给自己时间紧迫感,简单题10min,中等题25-30min。
3.张弛有度。不必陷入某几个难点纠结过多时间,比如动态规划和贪心策略,做一些典型的题目,掌握基本技巧,不需要给自己太多包袱和压力,用更多的时间去应对考察概率更大的题目。
必刷
OJ个人推荐
笔试和面试是不同的,笔试追求的是尽快AC,在时间有限的情况下不需要在乎解法的优劣。笔试算法题安排的时间通常要半个小时到一个小时,所以难度会大一些。笔试算法题的内容比较灵活,很多会给很长一段场景描述,需要正确理解题意。不过有内推的情况下,笔试能避免就避免。
以上都是我在春招实习和秋招面试当中遇到的一些手写算法题,仅供大家参考,具体题目如下:
1.阿里:反转一个句子当中的单词的顺序;
2.阿里:CanTransform:如hit->hat,hat->cat,cat->fat。但是不能单步从hit->hog。设计算法判断给定输入能否在字典范围内经过任意次步骤完整转换;
3.阿里:一个二叉树上求两个节点之间路径长度的最大值;
4.百度:找到不含重复字符的最长子串的长度;
5.百度:2n*2n 的方阵顺时针转 90 度;
6.商汤:按顺序打印二叉树的每一层的最后一个节点的值;
7.小马:将 1-n 这 n 个数按照 string 大小排序;
8.依图:给一个循环有序的数字查找目标元素;
9.依图:两个有序数组合并;
10.依图:k 个有序数组归并;
11.依图:输入一个 2 维数组,行和列都从小到大有序,判断给定的值是否存在;
12.猿辅导:求一棵树当中任意两个节点最长路径长度;
13.猿辅导:给你一个 list 都是父子节点的对,写个程序将其转换成森林,如果有环怎么处理?
14.腾讯:o(n)时间,1个变量实现洗牌;
15.字节:最长回文子串;
16.字节:给你一个字符串,字符串当中是一段c语言的代码和注释,注释只有/* */这样的可以嵌套,不包含//,请返回去除所有注释的代码,如果代码当中的/和/可以不完全匹配如何告知出现错误;
通常情况下用户所看到的软件应用程序只是其中的一小部分比如网页端或者App端的显示界面,但是有一大部分是看不到的。看不到的这一大部分,就是我们常说的广义上的后台。后台(后端) 其实是相对于前端开发的一个对应的统称,从企业来讲除了客户端和前端开发以及测试开发以外的其他研发类型的岗位大多都可以属于后台开发这一个范畴。后台开发在宽泛的意义上负责服务的中下层,比如中台,框架,业务开发到底层存储,计算,网络以及服务的监控和报警。在后台开发这一岗位上也对求职者有更全面的要求,无论是算法能力还是coding能力以及对计算机体系结构的理解再到当前流行的组件的运用能力,都是企业和面试官关注的重点。本节我将介绍后台(后端)开发的主要技能树,帮助大家了解作为求职者需要点哪些技能点。
初阶属于必要的关键技能也是立足之本,只有最基础的牢牢掌握才能将上层应用的更好。此阶段对应在学校自我学习阶段。其中语言基础,网络编程,算法和基础数据结构,操作系统是面试当中最频繁出现的问题。
中阶包括具体的常用的组件,工程化和测试相关能力,此处内容需要结合企业实习当中具体的方向深入学习。
高阶涉及到后台开发的深入研究方向,我本人实习阶段做过云计算方向,对云计算有一定了解,在此将云计算方向的一些技能点列出供大家参考;这些方向里每一个都需要大量的时间去研究和学习,可能是未来大家真正工作当中主要的方向。
后端开发可以往以下几个方向发展:
相比于前端,客户端,后台开发的前景更加宽阔,未来可以往业务方向或者中下层的各种组件和架构发展,在并发量和规模越来越大的场景下,面对的问题和挑战也越来越多。在这几年的秋招过程当中,后台开发是最火热也是竞争压力最大的岗位之一。