励志!一个非科班生的逆袭之路
前不久收到一位读者的 offer 咨询,我一看好家伙,拿到了好几个大厂的 offer,薪资都很给力
更为难能可贵的是这位朋友是非科班出身的,读硕期间才转的计算机,我觉得他的学习经验对一些读者应该会有帮助,所以邀请他给大家做了一次分享。
另外我想说的是近期虽然一些大厂裁员力度比较大,但我依然觉得互联网行业依然是个值得投入的行业,无论是薪资(毕竟一年顶其他行好几年)还是竞争环境(无需复杂的人际关系,基本只凭技术说话)对普通人都非常友好,踏踏实实练好内功,不愁下家。一只站在树上的鸟儿,从来不会害怕树枝断裂,因为它相信的不是树枝,而是它自己的翅膀,希望这篇文章能帮助一些朋友顺利卷入互联网
2021秋招总结
1.写在前
本人非科班,双非本/211硕,虽然不是生化环材,但是就业前景也不是很乐观。我身边很多转码的同学,而且很多硕士,研究生现在真的越来越多了,可能大部分人读研只是为了混个学历,包括我。如果说你还是本科或者专科,如果没有好的机遇,继续深造还是对的,真正找一个自己喜欢的事并坚持做下去,难能可贵。我可能恰恰相反,也许有很多像我一样的,读研之后方向也不明确,被导师压榨。
其实,我转码是受实验室师兄影响,作为一个非科班的,从来没想过自己以后会搞编程。转码的学习经历也和很多同学相似,当时是和舍友一起,在秋招的时候才发现学院也有好几个转码的。读研期间最开始接触的就是python了,好像研究生最开始学的大都是python,也有matlab,学习了半年多,然后就去学Java了。说真的,语言本身其实没有那么重要,在学习初段可能只是接触了常见语法和基本使用,好多东西往往是触类旁通的,但是非要选择一门语言,经过很多人的推荐,最终还是选择了Java,原因还是Java生态强大,招聘的岗位也相对更多一些。也会出现入职后被要求使用另一种语言,比如遇到有些公司入职后要转Go或者C语言,只要你能接受,大部分公司还是愿意的。总之,选择一门语言就好,其他的有需要再去学,不在多,在精。
至于如何去学习,感觉自己做的并不好。其实,无非就是理论+实践。理论最好是看一些比较权威的书籍,这样会更加系统和全面,我大部分是看的技术博客和视频,有利有弊,好处就是有些牛人的讲解能够深入浅出,但是我觉得忘得太快,可能是方法不对,而且有的地方没有联系起来;实践是很重要的,小到一个排序算法、多线程demo,再到一个后台系统,都需要你去实践。包括我在内,许多非科班同学的实践能力可能比较弱,大佬除外,有时可能知道大体思路,但是总是"提笔忘字",总归还是训练的太少了,对于系统级的项目可以跟视频或者几个人一起做就好了。所以,理论和思考固然重要,多去练习更加重要,眼高手低是不对的。
2.时间线
2020.1-2021.3
这个阶段正是寒假阶段,比较重要,为什么呢?因为春招和实习一般在三月份就已经启动了,如果早有准备,可以找找实习或者用春招锻炼一下自己,以八股和算法,有项目更好了。如果你一点没准备,一般是炮灰,大佬除外,很后悔当时没有意识到这点。其实自己当时也在准备,但是还没有进入“备战”状态,只是慢悠悠的刷个算法题,效率比较低。所以,规划好这个寒假。
2021.4-2021.6
这时候春招已经接近尾声了,实习是可以找找的。但是自己太菜了,准备的太晚了,八股没怎么看,算法也一般,基本上是一轮游,当时就面了两三家,感觉自己啥也不会就继续复习了。如果早做准备,多投几家,情况会截然不同,因为实习难度会比秋招小很多,同时,作为非科班的同学,有一份实习经历是非常重要的,你可以走实习转正,也可以把实习作为跳板进入大厂。总之,找一份实习很重要,尤其是对非科班的同学。
2021.7-2021.10
这段时间一般就是秋招了,现在公司一般会把时间提前,不是过去的金九银十了,应该是金八银九。很多公司在七月份就放出提前批,可以多去尝试,这不和秋招冲突,也就是你有两次机会。比如,我当时投了美团提前批,但是只有客户端岗位,然后栽在终面,面试官还是很厉害的,一针见血。后边我又投了美团的正式批岗位,并拿到了正式批 offer,也可能是不同的部门,面试官没有过问之前的面试。
之后又面试了字节提前批-客户端,是内部实习的群友内推的,找一个能实时联系的内推人还是挺好的。至于为什么是客户端,当时也是随便投了一下,周围很多非科班的朋友也投了客户端或者测开。这里说一下,客户端比较难招到人,如果你想去大厂,会相对简单点。后端投递的人太多,但还是供不应求,选择哪个方向要想清楚。
后边我基本投递的是后端的岗位,进入了海投阶段,但是很多可能因为简历不符合都石沉大海了。结果就是之后的一个半月里从机试到 hr 面挂了一遍,差不多进入面试的有二三十个,包括百度、滴滴、阿里、荣耀、华为等等,但还是太菜了,整个秋招就是大碗挂面,有个公司流程很快(半天面完),比如百度系,有的公司能拖一个多月,比如小米、荣耀等,最后面试的是华为,是十一之后了。其实,到最后就已经很疲惫了,拒了好多公司的面试和笔试。所以,争取在前期发力,不排除公司补录,但是只能等集邮大佬拒绝 offer 之后才可以,主动权要掌握在自己手中。总之,秋招越早准备越好,公司 hc 比较多,精力也会相对更加充足,拿到 offer 的几率就会比较大。
2021.11-2021.12
一般通过 hr 面之后,不出意外你会很快收到公司的意向书。之后就是开奖了,hr 会和你谈薪,发正式 offer,这段时间往往是比较煎熬的,也是一场博弈,有些人单车变摩托,前提是你要有Argue的筹码,比如你拿到了薪资更高或是大厂offer,亦或是你在大厂有实习经历。一般很少有A没的,有时会比较难,但还是要尽力尝试一下。
注意,接收邮件offer,有的也叫两方,这是不用赔违约金的,身边很多朋友签了两方违约也没赔钱。但是,还是谨慎考虑,一般会有截止时间,需要考虑清楚,企业招人成本也是很大的。三方就要更加慎重考虑了,如果没想好,一定不要着急签,如果被催,那就好好和hr说一下,就是尽量拖。也可以以逼签为由催其他公司给你开奖,不是特别着急还是不建议。
当时也拿到了几个Offer,比如字节、美团、百度、滴滴、转转、58、用友,大华,也有一些通讯公司,荣耀、华为、小米、中兴。因为字节出来的比较早而且薪资还可以,所以拒了一些公司,签了字节,不久也被华为后端捞了,其实后期也一直在纠结后端和客户端的岗位,也发现了很多和我相同困惑的朋友,有的坚持后端,有的去了客户端,一般来说就是大厂和中厂,薪资差距这两个因素吧。如何选择,看看你当前最关注的两个因素是什么了,鱼与熊掌不可兼得,如果你知道你签这家公司会有很好的发展,那你一定会签,但是你不知道。
3.面经总结
下面主要总结了一些秋招过程中自己和周围朋友遇到的面试高频题,主要面试岗位还是后端和客户端,网上也有很多面经,这里仅供参考。
基础知识
(1)语言基础(Java)
本人是Java选手,而且周围朋友也是用的Java语言,这里只涉及秋招中遇到的Java高频面试题。
Java虚拟机(JVM)很重要啦,高频八股,比如JVM内存结构(各个部分的功能)、类加载机制(类的生命周期、双亲委派模型)、垃圾回收机制(可达性分析算法、Full GC、垃圾回收算法优劣和适用场景、常见的垃圾回收器CMS和G1)、强软弱虚四引用;
Java语言本身,比如包装类与基本类型(缓存机制)、泛型的理解、String(不可变性,看看源码是怎么重写的)与StringBuffer/StringBuilder 区别、static关键字(修饰变量和方法)、final关键字(不能被重写和继承)、Java异常、Object 类有哪些方法;
面向对象的三大特性(最好结合场景理解)、重载与重写、接口与抽象类、equals与==、hashcode 之间的区别、Java 内部类、Java是值传递(创建副本)、浅拷贝与深拷贝、反射机制(原理、优缺点啥的,动态代理的实现方式之一,但是实际环境中用的 cglib,也要知道)、注解的基本原理。
(2)集合
Java的集合体系(Collection 和 Map 两大接口)、集合存储(是否能存储null、是否有序/安全);
List(ArrayLis,LinkedList的区别、应用场景、扩容机制)、线程安全的List;
Map(HashMap和ConcurrentHashMap结构、jdk1.7和1.8的区别、get和put方法的流程、如何扩容、解决hash冲突的方法、线程安全性)。
(3)并发
创建线程的几种方式(别忘了线程池)、启动线程用 start 方法(区别 run 方法)、wait 与 sleep 方法的区别(最重要一点为是否释放同步锁)、线程的6种状态;
为什么用线程池、线程池的核心参数、线程池工作流程(核心线程数 -> 阻塞队列* -> 最大线程数 -> 拒绝策略*)、线程池的 5 种状态;
说说多线程(或并发)编程、并发编程的三大特性、JMM 模型(实现原理、内存屏障、happen-before原则)、ThreadLocal线程本地变量、死锁的四个必要条件(缺一不可);
AQS关键字、Volatile关键字(弱同步机制,不能把保证线程安全)、synchronized 关键字(用法、底层实现、特性、锁优化)、ReentrantLock(特性,与 synchronized 区别)、乐观锁 CAS(如何实现,存在的问题以及如何去解决)、公平锁与非公平锁、锁可重入性。
计算机基础
(1)操作系统
说说进程与线程、进程的状态与切换(就绪、运行与阻塞之间的转换)、进程调度算法、进程之间的通信方式、进程同步、线程的通信方式(共享内存和消息传递)、fork 函数、银行家算法;
内存的管理方式、逻辑地址与物理地址、页面置换算法、什么是虚拟内存、生产者-消费者模型。
(2)计算机网络
ISO 七层模型、HTTP各个版本之间的特性和区别、常用的 HTTP 方法(get 和 post 的区别)、HTTP的报文格式、常见的HTTP状态码、数字签名、HTTPS(原理、与HTTP之间的联系);
TCP三次握手与四次挥手(高频问题、有很多细节,比如状态变化等)、TCP与UDP的区别、TCP怎么保证可靠传输、流量控制(滑动窗口机制)、拥塞控制、TCP粘包的解决方案;
DNS协议、输入url到显示的内部过程、Cookie 与 Session 的区别。
数据库
(1)MySQL
内连接和(左/右外)连接、数据库操作的基本命令(CRUD)、MySQL结构(Server层和存储引擎层)、日志模块(Redo log和Bin log)、SQL执行很慢的原因、InnoDB和MyISAM的区别;
对 MySQL索引的理解、索引划分(B+树/哈希、聚簇/非聚簇区别)、主键索引与唯一索引的区别、回表查询、创建索引需要注意什么、最左前缀原则;
事务(ACID特性)、事务的隔离级别(如何解决并发事务带来的问题)、MVCC多版本控制原理;
MySQL 中有哪几种锁(按对数据的操作类型和粒度)、InnoDB 3种行锁算法、MySQL死锁。
(2)Redis
Redis基本特性、5 种基本数据类型(底层实现)、Redis 持久化机制(RDB/AOF)、缓存一致性、缓存雪崩/击穿/穿透及对应的解决方案、为什么Redis是单线程,为什么Redis快?
数据结构与算法
(1)数据结构
数组:1. 两数之和、15. 三数之和、53. 最大子序和、88. 合并两个有序数组、33. 搜索旋转排序数组、54. 螺旋矩阵、42. 接雨水、64. 最小路径和、4. 寻找两个正序数组的中位数、41. 缺失的第一个正数
、287. 寻找重复数、189. 旋转数组、283. 移动零、128. 最长连续序列、162. 寻找峰值;
链表:206. 反转链表、92. 反转链表 II、143. 重排链表、19. 删除链表的倒数第N个节点、21. 合并两个有序链表、141. 环形链表、160. 相交链表、24. 两两交换链表中的节点、328. 奇偶链表、148. 排序链表、83. 删除排序链表中的重复元素、82. 删除排序链表中的重复元素II;
二叉树:236. 二叉树的最近公共祖先、102. 二叉树的层序遍历、103. 二叉树的锯齿形层次遍历、199. 二叉树的右视图、94. 二叉树的中序遍历、104. 二叉树的最大深度、110. 平衡二叉树、129. 求根到叶子节点数字之和、662. 二叉树最大宽度、112. 路径总和;
哈希表:3. 无重复字符的最长子串、76. 最小覆盖子串、136. 只出现一次的数字、349. 两个数组的交集、242. 有效的字母异位词、718. 最长重复子数组、560. 和为K的子数组;
栈与队列:42. 接雨水、232. 用栈实现队列、155. 最小栈、225. 用队列实现栈、394. 字符串解码、739. 每日温度、84. 柱状图中最大的矩形、456. 132模式;
除此之外,还有并查集,前缀树、堆。
(2)算法
排序算法(常考冒泡/插入/快排/归并/堆排序)的基本思路、时间复杂度分析、稳定性判定、常考手撕,补充题4. 手撕快速排序、56. 合并区间、253. 会议室 II、215. 数组中的第K个最大元素;
动态规划(DP):53. 最大子序和、5. 最长回文子串、300. 最长上升子序列、70. 爬楼梯、72. 编辑距离、91. 解码方法、44. 通配符匹配、494. 目标和、647. 回文子串、376. 摆动序列、279. 完全平方数、718. 最长重复子数组、1143. 最长公共子序列;
回溯算法:93. 复原IP地址、面试题 08.12. 八皇后、51. N皇后、46. 全排列、78. 子集、39. 组合总和、17. 电话号码的字母组合、77. 组合、40. 组合总和 II、47. 全排列 II;
常考算法还有滑动窗口、二分查找、双指针、贪心算法,LRU。
项目
当时简历上就写了个RPC,但感觉现在人均RPC了,其实本来有写分布式的项目(尚硅谷),但是自己不是很熟,就没写;另外,写了两个实验室项目凑数,一个深度学习算法,另一个偏向系统设计。
(1)RPC
讲讲这个项目你做了啥,有什么同类型的技术(比如Dubbo,gRPC),你去看过吗?
RPC的调用流程是什么,客户端怎么调用服务(动态代理,创建代理类),服务端挂掉怎么办?
如何实现对象的序列化和反序列化,几种常见的序列化方式(Json、Kryo、Hessian);
网络传输(通信交互),我用的是Netty框架,基本原理、线性模型、零拷贝;
服务注册与发现,我用的Nacos,或者是用Zookeeper,为什么用它搞清楚;
其他:比如线程池使用,负载均衡策略,设计模式(责任链模式)。
(2)实验室项目
这类项目面试官一般是不懂的,需要你去讲,就用star法则就好了,比如介绍一下项目背景,做了啥,你的职责,取得了什么结果,也可以说说你的感想和收获;
在这一部分,我在有些项目中担任负责人,面试官就会问很多场景题,怎么去解决问题,这种问题答案比较开放,注意逻辑清晰就好了。
其他
(1)框架
客户端没要求,如果是后端岗位,主要就是SSM、Spring全家桶,包括Spring的两大核心组件(iOC和AOP经常问),Spring Boot自动装配原理,Spring MVC的执行流程;
我被问最多的就是 RPC,设计细节,为什么用这个组件,怎么通信,还有延伸出的场景题。
根据每个人的项目,可能接触其他框架。有点需要注意,了解框架底层是加分项,但如果你简历或者项目没用到,面试官也不会问,切记不懂装懂。如果真的被问到,你不熟悉,你可以说你使用过,但是底层源码还没看到这里,转移话题(你比较熟悉的),比如正在看jdk源码,集合的源码等。
(2)设计模式
六大设计原则,基本思想、每个设计原则最好想一个经典的案例;
常见的设计模式, 理解并了解使用场景(自己项目中用到更好),比如单例模式(会手写其中的一种方式,线程安全性分析)、代理模式、工厂模式、观察者模式,适配器模式。
4.一些建议
早做准备,注意总结
寒假时间很关键,要注重效率和总结,包括算法和八股。比较好的办法是写博客,这样便于后期复习,可以在任意的平台,我当时记录在简书上了,写的时候直接用word可以,当时龙哥就是用 word 整理了一些八股总结,不过直接用 markdown 更加方便一些,更适合随时贴代码。
算法题是一个长期积累的过程,主要就是 leetcode 和剑指 offer,面试题也大都出自这里,在精不在多,应对秋招两三百道 leetcode 足矣,但是如果你有时间多刷肯定是好的。算法题几乎占据了秋招的半壁江山,遇到有个群友三面做了九道算法题,学好算法进大厂也不是梦。对于刚开始准备的同学可以看看左神的算法课程,讲的比较清楚。
八股文的话,初期还是建议多看看书,或者看看视频也可以,无论看什么一定要总结。如果到了寒假就要有针对性的去准备,无非就是语言本身、数据结构与算法、计算机基础(网络和操作系统),还有就是一些常见的设计模式,框架也要了解一些,这个在网上有很多技术博客总结和视频。
以面代练,注重复盘
在秋招刚开始,我是有点畏惧面试的,总是感觉自己没准备好,不是这没看就是那没看。其实,只要你迈出那一步,一切都烟消云散。面试是检验你复习成果的最好方式,也能最高效的找出你当前的漏洞。同时,你可以借此机会和面试官沟通,比如一些技术问题,保持一种谦逊的态度是很重要。排除一些大佬吊打面试官,我一般是被面试官吊打的那种。
面试复盘很重要!你面试下来肯定会存在很多问题,也许是技术问题、也可能是沟通表达,最好做一下记录。看牛客网很多人会去写面经,这是很好的,记录一些问题,方便自己,也能帮助其他人。我这个地方做的不好,最开始是用笔去记,后边会用手机录音,记录整个面试过程(但是几乎没去听过)。我遇到不止一次被问到相同的问题,但是总是感觉自己回答的不好。所以,一定要复盘,重点关注自己不会的或者回答不是特别流畅的问题。
Coding 一般是面试的最后一个环节,但有的公司上来就是算法题。虽然 Coding 能力是一个积累的过程,但是算法临阵磨枪却有奇效,就是面哪个公司刷该公司的高频面试题,比如看看codetop 或者找找牛客网面经。一般公司会使用赛码网或者牛客网出算法题,可以直接运行,不用写输入输出;但是有些公司也会自己出题或者自己描述(原题居多),记得有一次,面试官口述算法题,说了半天是个两数之和,测试用例还是错的。还有一点就是遇到简单题要矜持,不要一两分钟就做出来了。做题前后多和面试官交流,一定先尝试去写,如果真的一头雾水,可以说说思路,也可以让面试官换题,这是下策,我没有试过,但是我朋友有一次换了题之后也没做出来,就很尴尬;做出来的,可以尝试多解(面试官一般也只是让你说说思路)。
逻辑清楚,自信沉稳
面试回答过程中,逻辑一定要清楚。客观题也要组织好语言,可以开门见山,上来给出答案,紧接着给出解释或者自己的理解;也可以先解释分析,最后给出总结。总之,让面试官知道你在说什么,尤其是在介绍项目的时候,怎么能够通过几句话把一件事描述清楚也是不简单的,如果不知道怎么组织语言,Star法则是很好的模板。
客观题一般两种问法,一是自由发挥,比如说说虚拟机、多线程等,这种范围比较大,回答要全面,而且回答经得住面试官推敲的问题,简单来说,就是引导面试官往自己准备的问题,切记说自己不会的,给自己挖坑。同时,一些问题需要总结,可以借此说说自己的理解,错了也没关系;另一个是具体问题,这种情况很可能会遇到自己的盲点,因为面试官对你不了解,只能随便问,这里有一个技巧就是通过简历或者自我介绍引导面试官,把自己熟知的内容写在简历,我曾遇到不止一个面试官对着简历提问。如果真遇到自己的盲点,那就尽量平行迁移,回答相似的技术问题,有时答非所问(适用少部分题目,有时候是你真的搞混了),有些不计较的面试官直接就过了,这是下策,我之前就被美团终面面试官吊打,可能也有压力面的成分。
另外,自我介绍是非常重要的,是开场戏,也可以缓解紧张。注意,稿子还是要背的,但是一定要很自然和自信的说出来,把每一个想呈现给面试官的点说清楚,可以说说自己的一些经历,但最好还是专业一些,不要抓住自己的爱好长篇大论,有实习和项目经历就可以聊聊了(我是非科班的,就说了说在实验室做了啥),不宜过长,建议30~90秒吧。面试官一般都很好,语气和态度都很好,一般很少遇到奇葩。因此,放慢语速,保持自信和沉稳,想清楚再说,至少想想自己会不会,确定一条主线,就是回答的方向。
以上均是一个非科班转码菜鸟的拙见和感想,如果有不当之处还请大佬们指正,希望能帮助到也想转码的朋友!
5.资料推荐
编程书籍
Java语言:《Java编程思想》、《Java核心技术 卷1》;
算法:《算法》(第四版)、《程序员面试指南》、《剑指Offer》;
计算机网络:《图解HTTP》、《计算机网络》(自顶向下方法);
数据库:《MySQL必知必会》;
其他:《鸟哥Linux私房菜》、《图解设计模式》、《重构》;
视频推荐
黑马程序员/尚硅谷/狂神
左神算法
极客时间
博客网站
知识点总结:CS-Notes/JavaGuide
算法题解:windliang/代码随想录(c++)/liweiwei1419/Krahets/labuladong
刷题网站:牛客网/Leetcode/Codetop企业题库/AcWing