Hey guys, 这里是程序员cxuan,欢迎你收看我最新一期的文章,今天这篇文章源自于我一个忠实读者的亲身经历,这篇文章写了他从大一开始到进入腾讯的一系列感悟和总结,希望能够帮到你。
菜鸡历险记
从二月底开始投简历,到四月拿到 offer,我的春招结束了!
选择直接工作,而不是想大多数人一样选择读研,真的是一个很艰难的决定,参加校招所经历的迷茫担忧焦虑也不亚于参加一场研究生招生考试。
大学伊始,几乎和大多数人一样,我也想当一名好学生,像助班一样闪耀,拿到高绩点,参加各路竞赛,获取保研资格,把简历塞的满满当当,懵懂的认知甚至让我在当时一度陷入唯绩点论的思维,专心埋头苦干。
非常遗憾的是,在大一要结束的那一段时间里,低到让人抬不起头来的 gpa 才让我意识到并逐渐接受,自己也许真的不擅长考试(说到底还是菜找借口),即便大一也挺努力,gpa 依然很低,这让我开始逐渐怀疑起自己的能力。
现在看来绩点固然重要,但其能够证明的东西其实比较有限(起码在计算机领域),除非确实很拔尖,其实大学里很多课程都懂的。。在这里我并不想去批判大学的教育,只希望gpa不要成为量化学生能力的唯一指标和对他人产生傲慢与偏见的理由。
在大一结束的那个暑假,搬到了新校区,开始新的生活,从那一段时间开始,我偶然间发现自己对各种 amazing 的技术有着十足的兴趣,从爬虫到 web,从数据分析到机器学习,基本都有过一段时间的接触,那段时间几乎成为了我技术的启蒙阶段。
时间兜兜转转来到了大二,凭借着自己对技术能力的热爱,我满怀自信的提交了转去计院的转专业申请,第一志愿,上机考挂,第二志愿,上机考过了缺挂在了面试上,一问原因才得知竟是绩点低 + 大一挂了一门通识课。毫不夸张的说,在当时对我的打击真的很大,质疑自己的声音在我脑子里不断回响,"你一个非科班比得过别人计算机系的同学吗?" "你学技术不是在不务正业吗!??" 那个时候几乎因此丧到极点,而如果想再下一个学期转专业将面临着降级。
但是在那一学期,也有一些好事发生。在大二上凭借我对技术的兴趣,引起了 Python 课老师的注意,并邀请我加入其课题组,后面老师也变成了我的导师。我也很顺理成章的结识了几位研究生学长,在那段日子里,几乎有读不完的论文,看不完的算法,一切都很新奇,似乎很快就把我转专业失败的负能量抛之脑后。
晃晃悠悠大二就快结束了。虽然感觉算法领域真的很酷,我也曾幻想着自己能一头扎入人工智能的领域,并且在导师的带领下学习了一段时间,期间也参加了个比赛拿了个奖和水了一篇专例,其实在内心真的很感激,能在大学生涯遇到这样一位愿意为本科生付出如此心血的导师真的是我莫大的荣幸。但是反过来说,虽然算法真的挺有意思也非常热门,但其门槛真的很高而且竞争也越来越激烈。
如何看待 2019 年秋招算法岗灰飞烟灭?
如何看待算法岗一片红海诸神黄昏?
。。。
各路 985 硕士海归,顶会论文,top 竞赛 balabala,着实劝退。本身对论文数学不感兴趣的我最后还是放弃了,还是开发更适合我。
就目前而言,个人认为市面上需要的是具有扎实的计算机基础且具有一定工程能力的算法工程师,而不是各路导包调参侠,不管是哪个技术岗,都需要拥有扎实的编程语言、数据结构、计网、操作系统作为基础。应当先成为一名合格的软件工程师,再努力成长为一名合格的算法/机器学习工程师。
在 20 年初,我也最终下定决心,决定未来在 Java 后端领域深入学习,现在看来,这个选择不一定是最好的,但起码不算差,同时我也退出了导师的课题组,虽然没有继续做下去,但还是打心底的非常感谢导师,因为在做竞赛期间导师对我们的帮助可以说是至关重要,遇到一个愿意为本科生付出如此心血的导师真的是我大学时光里莫大的荣幸。
晃晃悠悠,从《Java 核心技术卷 I》开始啃,一步一步开始深入,到逐渐开始完成些小项目,前路也慢慢变的明朗起来。
期间也遇到了几个志同道合的小伙伴一起做项目,虽然有时真的蛮辛苦,但相信几年后的我回想起来,这肯定是一段非常快乐且值得留恋的时光。
进入 2021 年,俗话说金三银四,春招也逐渐逼近,从 2 月底开始,来来回回复习了半个多月,最终非常幸运的拿到了腾讯的暑期实习 offer,也许和很多大佬比这不算什么,但能进大厂也算是圆了大学一直以来的梦想了吧。
作为一个刚刚结束 2021 春招的人,谈一谈自己一开始的乌托邦与最后的现实,腾讯和阿里是我最早选定的目标(因为学校就在杭州,家在深圳),阿里提前批面了三个部门也都通过了,但最后内推流程只能选择一个部门,一面很顺利评价也很好,但在把我晾了近一个月后奇妙的把我挂了,然后被某部门捞,一面通过,二面评价也不错,然后又等了半个多月,挂(面试体验和鹅厂比相差甚远,流程混乱,部门抢人现象也很严重),字节一面挂(发挥最差的一轮面试),腾讯四轮技术面+一轮HR面过,海康一轮技术面通过。在拿到鹅厂 offer 后也长叹一口气,顺便把后续的面试都推掉了。
很早之前就搭建起了公众号和个人博客,博客也只是偶尔写一下技术方面的文章,也许是忙碌(其实就是懒)的原因,一直都没有付诸行动,希望能凭借自己一点微不足道的经验,分享一下自己的心路历程,看心情更新:)
数据结构与算法
一个可以肯定的点是,无论是哪种技术岗位,对于校招而言,技术栈的要求可能不会特别高,但对于思维的灵活性,编码能力的考量,则是十分看中的,对于算法的准备个人认为应该尽早开始,最好养成每天刷每日一题的习惯,从 2020 年初开始,我就在 LeetCode 开始了我的算法学习之路,来来回回也刷了 500 题了,虽然水平远不及 acmer 那样,但扎实程度也足够应付大厂的算法考验了。
养成一个刷题的好习惯,从长远来看对编码能力的提升很有帮助!
附上一些个人总结的不完全要点:
- 排序(快排、堆排、归并、冒泡、希尔、选择 等)基本思想 时间复杂度 稳定性 最好都能手写
- DFS、BFS、回溯算法
- 单调栈
- 贪心算法
- DP(例如背包问题等)
- LRU(双向链表 + HashMap)
- topN 问题(海量数据找出第 N 大的数据)
- 大文件统计词频(字典树)
- 位运算
- 双指针
- 链表
- 二叉树
- 记忆化递归
- 二分查找
- 堆(例如 大/小根堆)
- 图(有向无向图、dijkstra、floyd 算法之类的)
- 并查集
- 滑动窗口(Sliding Window)
- 红黑树
- AVL
- BTree、B+Tree
再附上一点比较热门的算法学习书籍和 Github 地址吧:
- 剑指 offer(非常经典,几乎涵盖了常见的算法面试题)
- 算法导论(可能会比较难,但是这本书也算算法界的圣经了吧)
- labuladong 的算法小抄:https://github.com/labuladong/fucking-algorithm
计算机网络
计网的重要性同样不言而喻,个人总结的一些不完全的要点如下:
- HTTP 1.1、2.0 和 3.0 的新特性
- HTTP 常见状态码及含义
- HTTPS(握手、CA、解决的问题、对称加密与非对称加密等)
- 常见 HTTP 请求方式的含义
- 如何优化 HTTP/HTTPS
- OSI 七层与 TCP/IP 四层区别及其含义
- TCP 三次握手(是什么、为什么)
- TCP 四次挥手(是什么、为什么)
- TCP TIME_WAIT CLOSE_WAIT状态
- TCP 长短连接
- TCP 的特点及报文结构
- TCP 是如何保证可靠传输的
- TCP 的重传机制
- TCP 的流量控制与拥塞控制
- TCP 滑动窗口
- UDP 特点、使用场景、报文结构
- DNS 解析及其过程
- IPv4、IPv6 区别
- IP 地址的分类
- 子网掩码的含义
- DHCP 协议
- ICMP 协议(ping命令)
- MAC 地址的含义
- 交换机和路由器的区别
- ARP 协议
- 浏览器输入 url 发生了啥
计网就没啥好说的,基础中的基础,面试中的常客,各路谢希仁自顶向下黑皮书啃起来就完事了~
操作系统
个人总结的一些不完全要点:
- 操作系统的四个特性
- 用户态和内核态(是什么、为什么)
- 上下文切换
- IPC 通信
- 线程同步的方式
- 进程、线程、协程的区别
- 进程的三态模型
- 进程调度算法
- 死锁产生的四大条件
- 死锁的预防
- 如何解决死锁
- Linux IO 模型(阻塞式 IO 非阻塞 IO IO 多路复用 信号驱动 IO 异步IO)
- Reactor 模型
- 零拷贝
- 虚拟内存
- 分页 分段 段页式区别及含义
- 页面置换算法
- 磁盘调度算法
- Linux 文件系统组成
- 硬链接与软链接
Java基础
个人总结的一些不完全要点:
- 问到烂的 HashMap、HashTable、ConcurrentHashMap
- 一些常见的集合类(TreeMap ArrayList LinkedList ArrayDeque之类的)
- equals 和 hashCode
- == 与 equals
- 如何理解面向对象(抽象 继承 多态 封装)
- Java 异常分类
- 深拷贝与浅拷贝
- 七大基本类型(语法糖 包装类)
- Object 类有什么方法
- StringBuilder 与 StringBuffer
- String 的 intern() 方法
- 为什么 String 不可变
- jdk 的新特性(8 lambda Optional 9 String 改成 byte[] 存储之类的)
- Java BIO NIO AIO
- 泛型和类型擦除
推荐书籍:《Java核心技术卷 I / II》,进阶点看《Effective Java》《Thinking in Java》
这里我个人并不是很推荐去看视频,论知识的获取而言,我更偏向自己探索吸收,而不是以"喂"的方式学习。
JVM
个人总结的一些不完全要点:
- Java 内存模型、运行时数据区
- Java 对象创建过程
- Java 对象的构成
- 类加载过程
- 类加载器及双亲委派模型(是什么、为什么、如何主动破坏、优缺点、如何实现)
- 堆内存分配分配策略
- 四种引用类型区别及含义
- 如何判断对象已死亡
- 内存泄露分析
- 常见 GC 算法
- 常见垃圾回收器(CMS、G1等)
- Java 到底是值传递还是引用传递
- Full GC 原因及排查
- JVM 常用监控工具(例如 jmap jstack 等)
- JVM 常见参数(例如 Xms Xms SurvivoRatio等)
周志明老师的《深入理解Java虚拟机》啃起来就完事,涉及到的知识也和操作系统有些关联,对于Java的学习,切勿停留表明语法,都动手实践,切勿眼高手低。
多线程
个人总结的一些不完全要点:
- 线程池(Executor 框架,为什么阿里巴巴Java开发手册不允许使用 Executors 去创建线程池,优点,如何使用,如何配参数「可以看看这篇:Java线程池实现原理及其在美团业务中的实践」)
- AQS 原理
- 常见 JUC 工具类(CountDownLatch、CyclicBarrier、Semaphore、Atmoic原子类)
- synchronized 关键字
- ReentrantLock 可重入锁
- 自旋锁 / 互斥锁
- 乐观锁 / 悲观锁
- 公平锁 / 非公平锁
- 读写锁
- Java 锁升级流程(无锁 偏向锁 轻量级锁 重量级锁)
- ThreadLocal(使用场景 原理)
- volatile 关键字(是啥、做了啥、禁止指令重排序、缓存一致性原理、happens-before原则)
- Java线程的状态(NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED)
- Object.wait Thread.sleep Thread.join Thread.yield方法作用
推荐书籍:《Java并发编程实战》《Java并发编程的艺术》都很经典
Spring框架
个人总结的一些不完全要点:
- Spring IoC 思想、特点、原理
- Spring 事务
- Spring 循环依赖
- Spring AOP 原理(动态代理 JDK Proxy CGLib AspectJ java反射机制等)
- Spring MVC 原理
- SpringBoot 自动装配原理
- Spring 常见模块(ioc aop aspects jdbc jms orm web test)
- Spring 事务传播机制
- Spring 用到的的设计模式
- Spring Bean 的生命周期
针对 Spring框架的学习一定要多实践,多翻看官方文档,切勿只停留于片面的技术博客,看看开源项目,从一个小 demo 开始做起,慢慢就会逐渐领会到框架的精髓。
MySQL
个人总结的一些不完全要点:
- 数据库设计的三大范式
- MySQL 常见存储引擎(InnoDB MyISAM Archive 等)
- 死锁 innoDB 行锁(gap X S锁)
- MVCC 机制(原理及实现 undo log 一致性视图)
- 事物的 ACID 特性
- 事物的隔离级别
- 脏读 幻读 可重复读
- 一条 SQL 语句执行的过程(binlog redolog)
- 索引(聚簇索引、辅助索引、联合索引、原理)
- SQL 语句分析
- 慢查询分析
- SQL 语句优化
- 读写分离 分库分表(水平垂直拆分)
推荐书籍:《MySQL 必知必会》《SQL 基础教程》
极客时间丁奇老师的《MySQL 实战45讲》也有口皆碑,很推荐!
多联系SQL语句,在面试中有可能会让你手撕SQL题,多在项目中对sql进行优化、分析。
Redis
个人总结的一些不完全要点:
- 五种数据类型(string、list、hash、set、zset)
- 其他数据类型(BitMap Geospatial hyperloglog等)
- Redis 单线程模型(为什么高效?为什么不用多线程?Redis6.0多线程的目的?)
- Redis IO 多路复用机制(select、poll、epoll、Reactor模型)
- 持久化机制(快照、AOF)
- Redis 内存淘汰机制
- 如何判断数据过期?
- Redis 事务
- Redis 渐进式 rehash
- Redis 集群(主从复制、哨兵、cluster集群)
- 如何保证数据库缓存一致性?
分布式相关
分布式领域的知识真的太多太多了,几乎是一个无底洞,如果对其中一两个框架比较熟悉其实在面试中也是很加分的。
不完全要点:
- CAP 原则与 BASE 理论
- 分布式一致性相关(ZooKeeper、Paxos协议、ZAB协议之类)
- NoSQL(Redis、MongoDB、memocached等)
- SpringCloud(服务发现与注册、负载均衡、网关)
- RPC 框架(例如 Dubbo 这类,序列化协议 protobuf 这类)
- 消息队列(业内使用最多的 Kafka、阿里的 RocketMQ、RabbitMQ)
- 分布式事物、分布式锁
编程工具
- Git
- Docker
- Linux命令
投递与选择
金三银四、金九银十分别对应春招和秋招的时间节点,春招大部分面向的是实习生的招聘,而最后在秋招环节,一大批的 hc 要被成功转正的实习生所占有。
可能对于想进大厂的双非本科生而言,大三的春招就是你进大厂几率最大的时候,往往越到后面,面试的要求会越来越高,"机会是留给有准备的人"这句老话一点都没有错。
尽量选择提前批,很多公司的提前批可以免去笔试,而且这时候 hc 多,面试流程快,只要通过面试基本就有位置。
在投递上,尽可能进大公司,有大公司给你做的背书会让你的职业生涯越走越顺。
一点软实力
抛开技术,其实无论是性格也好,还是情商也罢,虽然表面上看对技术岗似乎影响不大,但这玩意切切实实会潜移默化的影响别人对你的印象。
就比如在对一个问题的阐述上,一些人的发言听起来就很有层次感,很舒服,包括与面试官的沟通(亦或是聊天瞎扯),一个性格随和开朗,不卑不亢,说话有调理的人,谁不喜欢呢?
一位前辈也告诉我,抛开技术层面,面试官也会很在意你的价值观与为人,如果价值观或者人品出现问题则会一票否决。一个高傲,说话有棱有角,目中无人的候选人,即便技术再好可能也不太会博得面试官的认可。
其实软实力这一块要在生活中慢慢锻炼,与不同的人接触沟通,适应不同人的性格。谦卑(不是自卑)的态度,坦诚的交流,冷静的思考,往往是一场面试成功的潜在因素。
心态问题
「少抱怨,行动才是缓解焦虑的最佳途径」
几乎没有人能够做到安逸的度过一生,产生焦虑的情绪也十分正常,所有的焦虑都来自某种持续的心理矛盾。
- 警惕身边贩卖焦虑的消息,冷暖自知
- 尽自己最大的努力,只为让未来的自己不后悔
真的很推荐大家能养成坚持锻炼的习惯
每周三次、每次三十分钟的体育锻炼,与最强劲的精神药物,有同样的效果
坚持锻炼给人带来的好处,其实是潜移默化的,身体素质、心态、外表、性格都会慢慢变好,而且,晚上的时候,会睡得更好。
仿佛乱七八糟的想法和担忧,全部随着汗水流走了,梦中无事,睡眠质量的提高,这本身也能缓解焦虑情绪。运动可以让身体产生内啡肽,极大地缓解焦虑水平,一般来说,跑步之后,虽然身体是累的,但精神明显清爽很多。
给予自己积极的心理暗示,切勿盲目自信,尽力去做,不要让自己后悔,不管结果如何。
说在最后
脚踏实地,保持谦卑。
技术这条路远远没有尽头,且不过是围城罢了,外面的人想拼命往大厂钻,中年程序员想拼命摆脱危机,但无论如何,做技术的一定要保持一个谦卑的心态。
一点拙见,还望包涵!
记得一键三连哦!!!