【非广告,纯干货】本科毕业3年的我,是如何薪资翻倍拿到38万年薪Offer的?【石杉的架构笔记】

3,308 阅读14分钟

欢迎关注微信公众号:石杉的架构笔记(id:shishan100)

目录:

一、以往履历

二、技术积累

2.1 公司里的积累

2.2 业余时间的积累

三、面试过程

3.1 一面:深挖技术

3.1 二面:结合项目

3.3 三面:聊薪资、聊理想、聊人生

先说一下这位同学的面试成果,普通本科学历,毕业仅仅3年,原先年薪也才20万,但是最近跳槽一举拿下年薪38万的offer。

以下是这位同学整理的这次面试经过的一些心得体会,供广大同学参考

一、以往履历

之前经历过的都是小的互联网创业公司,技术氛围不好,过程管理也不规范,做过的项目也都是一个个的风投项目,容易被市场优胜劣汰下来。

进入大公司一直是我的梦想也是我的情结,但是目前年限不够。所以先沉淀一下,找了一家B轮融资的互联网公司,希望下次有幸能写面经的时候能够收到大厂的offer。

二、技术积累

2.1 公司里的积累

① 珍惜项目带来的技术挑战

之前做一个项目时,遇到了地理位置相关的技术挑战,于是接触到了GeoHash算法。

当时是使用mongo存储经纬度 + geo计算来解决了这个问题。

在这个过程就会对MongoDB技术进行一定的研究,而且对地理位置相关的问题也会有一定的经验积累。

做另外一个项目时接触到了千万级别的用户量,在搞活动的时候受到了高并发挑战。

用户量很大时,高并发请求后台系统,对交易链路造成了压力,这里应该如何解决也有了一定的积累。

还有就是我在做一个公司全新探索性项目时,由于是全新的领域,需要进行一定的领域建模。在建模的过程中,大大锻炼了自己的系统设计能力。

② 珍惜团队管理的机会

印象很深刻的一点是,当时由于一个探索性的项目属于公司的试点项目,刚开始后端研发人员就3个人。

所以我们作为老员工,在后面团队扩招时也顺理成章的成了小组leader之类的角色。

新领域有技术调研的困难,也有需求合理性的苦恼,加上刚开始人员不多,基本上是加班特别严重的。

于是公司高层引入了敏捷开发,我们成立了一个个scrum小组,需求拆解,迭代任务,物理看板,每日站立会。

第一次接触scrum给我的职业生涯带来了很大的冲击,而团队管理也让我从另一个角度来认识整个团队的容量和交付能力。

但是一旦把这次机会把握住了,就可以快速积累带一个小团队的能力,包括人员招聘、项目管理、团队管理、任务拆分、进度追踪、保证产出,等等。

2.2 业余时间的积累

① 善于总结和复习

1)周期性总结,有利于对知识的整理记忆。

自己平时会学习很多的技术,比如Java并发、缓存、MQ、微服务、分布式,等等。

但是其实人有一个很大的问题,就是学完就会忘。这个是很正常的,人不是神仙,谁不会忘呢?

所以说一定要周期性的复习,这样你每一年才会发现自己把很多技术都掌握的很扎实。

2)有段落标题有总结的文字比一堆文字更直观

对于自己平时学习的时候记录的笔记,不是说写一堆文字就可以的,我们都需要自己提炼一番,归纳出一堆小标题。

通过小标题的形式串联起来大量的知识点,在复习的时候,哪怕就是看到标题就知道背后的知识点。

② 寻根究底

平时在学习一些技术的时候,往往会找很多的书籍还有视频。

但是其实在学习的时候,不光是吸收书籍或者视频里的东西,还要有自己主动思考的能力。

举几个例子:比如之前研究Spring Cloud技术的时候,就对里面很多技术都有自己的思考,然后带着自己思考的问题主动去里面进行探索。

1、我对Ribbon作为负载均衡技术,在Spring Cloud源码内部的一些实现细节上,有以下的疑问:

  • springclientfactory原理是什么?

  • 谁触发注入了springclientfactory?

  • 为什么ribbon这里的整合使用springclientfactory,还有其他方式吗?

  • 将bean注入ioc容器的方式有哪些?

  • 自动配置的原理是什么?

  • spring.factories和jdk的spi有什么异同?

然后会带着这些问题去深入探索Spring Cloud源码的一些实现。

2、我对Zuul作为SpringCloud的网关也有疑问:

路由表只是从配置文件读取的吗,会不会从serverList里动态刷新路由表呢?

带着这个问题也会去探究其底层源码。

3、对MySQL技术,我的疑问是:

mvcc机制为innodb提供了读写并发的能力,快照读都是通过隐藏的事务ID列来读取快照数据?

此时可以再深入研究innodb的其他细节:

  • innodb的事务的ACID特性是如何实现的?
  • undo日志是存储在哪的,快照读是怎么和undo日志结合起来的?

③ 培养独立看源码,画图的能力(重要性:5颗星)

第三个,平时一定要建立起来自己独立看源码的能力。

比如说之前我通过一些网上的博客,大概看过里面对Atomikos、ByteTCC的源码的分析,了解了XA事务和TCC事务的执行流程和框架设计。

优秀的分布式事务框架其实也有很多,在ByteTCC中,cancel是和try对应的,如果confirm失败,便会根据事务日志一直重试,这是ByteTCC的设计理念。

但是,我们还可以看看其他TCC框架,如tcc-transaction、Hmily他们在TCC方面的设计理念。

根据看源码的方式,先大致浏览文档,跑一个demo,找单元测试和框架入口。

先读静态源码,再debug跟进,边调试边画流程图

慢慢的,这种独立看源码和画图的能力可以得到很大提升,从怕看源码到爱看源码。

三、面试过程

其实这家公司,因为我知道他是一家B轮融资发展很好的公司,所以直接就去面试了。

自己这次的目标,就是找一家发展潜力好的中型互联网公司,而不是直接进大厂,因为自己知道年纪太轻,直接面大厂信心还有所不足,就想先沉淀一下。

3.1 一面

① jvm类加载机制,何时触发类的加载和卸载

主要说了Java为了实现语言的灵活性,采用了在运行时动态加载字节码,以及加载、连接、初始化的各个步骤流程。

还说了加载使用的双亲委派模型以及其打破该模型的案例,各个类加载器加载什么样的类,如何自定义类加载器。

对类的七种主动使用触发类的加载,类的卸载的条件。

**总结起来:**主要就是围绕类加载,聊了一些老生常谈的问题。面试官肯定是知道,但是答的时候,要尽可能的多说多扩展。

这样可以让面试官知道我们大致的知识范围,也掌握面试主动性。

② gc算法

说gc算法之前,先聊了如何判断一个对象可以被回收,我说了引用计数法,GC Root等方式,回收对象的流程。

然后先从标记清除算法开始谈,说出其优缺点,从而引申出复制清除和标记整理算法。各个算法聊完之后,引申出分代清除算法。

聊完算法便开始聊各种垃圾收集器的特点和使用场景。

这里我的一点感受是:很多知识点其实不是死记硬背的,而是前人设计的智慧或者是妥协。

我们可以按逻辑分析的方式跟面试官侃侃而谈,用分析问题的方式来回答,而不是死背答案的方式。

③ nio,aio,netty

这方面其实不太熟,直接跟面试官表明对这方面有欠缺,但是有一定自己的了解。

主要从传统的bio模型开始说起,然后说到tomcat在bio模型下同步阻塞的问题。

接着说了为什么要设计nio这同步无阻塞的模型,是怎么通过一个selector多路复用来监控多个channel的。

最后还聊了聊aio的异步无阻塞模型的大致概念,nio基于事件的同步无阻塞模型适用于服务器端编程,aio异步无阻塞适用于大文件读取。

这里给大家分享的一点心得就是,不熟悉的知识点千万不要乱掰,浪费面试官时间,也让自己在面试中处于被动形势。

可以先表明自己对该知识点有欠缺,再大致说说自己的了解,让面试官快速了解自己的水平。

④ innodb的索引结构

直接和面试官说了innodb的BTree索引的B+树,说说其存储结构和优点。再聊到了聚集索引和辅助索引。

后来补充了下二叉查找树,链表,hash,B树的优劣势以及为什么会选择用B+树来作为索引结构。

尽量多从自己作为设计者的角度来回答问题,表现出分析和表述能力。

⑤ 一致性hash

  • 先聊hash算法的优点
  • 再聊一致性hash的使用场景:
  • 分布式环境下多节点负载数据
  • 防止节点的动态增减影响到大范围的数据
  • 再聊一致性hash的原理,如何实现,自己实现该算法的思路
  • 再聊其他中间件对其的实现,如redis-cluster的hash slot方式

⑥ redis的持久化、哨兵、cluster

这些都是老生常谈的问题,基本上你只要看过石杉老师的亿级流量课程,都可以轻松的回答。

⑦ synchronized的原理

先聊了sync的指令,再说其加锁的原理。

然后聊到了JDK 1.6对其的优化(自旋锁,自适应自旋,偏向锁等),然后说到了sync和wait、notify这对黄金搭档。

⑧ AQS、CAS、以及其他组件

说完sync,面试官就问了JDK的可重入锁,问其实现原理。

自然而然的就说到了AQS,以及可重入锁的那一套原理,然后顺理成章的聊了公平锁,非公平锁。

接着面试官就问了使用AQS的其他组件,然后就聊了读写锁,信号量,CountDownLatch、ThreadPoolExecutor等的原理。

⑨ 让你实现一个RPC框架该如何设计

  • 通讯协议
  • 序列化方式
  • SPI扩展
  • 底层代理
  • 超时、重试、负载均衡
  • 拦截器、插件等自定义支持
  • 注册中心的选型与交互

这类开放式问题按照我个人的理解,应该不是让我们直接回答底层很详细的细节,而是从很hign level的级别来谈谈需要考虑哪些点。

⑩ 设计秒杀系统

我本身没做过秒杀系统,之前也没怎么看过相关的设计,只记得之前上班通勤的时候偶尔翻过几篇博文,于是带着自己的分析跟面试官谈的。

  • 临时机器、带宽申请,环境隔离,不要影响主体业务
  • 与产品沟通,前端限流方式是否影响用户体验(如答题、拼图等)
  • 预估用户量:比如只有40%的用户能抢到,那么直接让50%的用户立即秒杀失败,不进入后续服务
  • 后端做好流量控制,限流降级,一些非核心的数据做好多级缓存
  • 层级过滤下的少量用户,进入秒杀核心逻辑,这时候有多种方式:
  • 使用队列(削峰,串行化,扛并发)
  • redis的incr(单线程)
  • 分布式锁(可以聊聊分段加锁,增大分布式锁的TPS)
  • 再聊聊产品需求设计,是采用下单即锁定库存还是支付才锁定库存

3.2 二面

二面比较关注我的项目经验,主要问了我最近的一个项目以及项目的用户量,订单量,交易量,QPS,TPS等。

另外还问了相关的业务,看我是否对一个项目及业务有着完整的理解,然后跟着项目问了一些简历上写到的东西。

① 分布式事务

跟面试官聊了分布式事务的各种解决方案以及适用场景,大致聊了下具体的细节。

② 分布式锁

很多人聊分布式锁喜欢单刀直入的直接聊redis和zk锁,我喜欢先聊分布式锁的原理。

其实就是在分布式系统中,找一个全局唯一的第三方的一个标识,某个节点的某个线程,获取到该标识,即为获取到分布式锁。

相应的方案有很多:

  • 基于某个远程本地文件锁(只有某个线程能唯一创建一个文件)
  • 基于数据库某张表的唯一索引
  • 基于Redis的setnx/lua实现
  • 基于zk的瞬时序列节点实现

再一个个聊他们的优缺点以及自己是如何在项目中封装落地的。

③ 限流算法

  • 单节点限流:简单的聊了下漏斗和令牌桶算法以及他们的特性
  • 集群限流:想了想用Redis做信号量

顺便聊了下Hystrix的信号量以及线程池限流。

④ 设计模式

设计模式我个人掌握的很熟,这也是很基础的东西。

主要聊了在上一个项目的哪些场景使用了哪些设计模式,为什么要用该模式。

然后又补充了一下,一些第三方框架里使用的一些设计模式。

⑤ RabbitMQ

因为项目用的是RabbitMQ,所以主要聊的是他的使用场景,如何保证消息尽可能不丢失,RabbitMQ的集群模式。都是很基础的问题。

⑥ 手写ArrayList

这个没什么好说的,相信看过相关源码都能写出来。

⑦ 不使用链表怎么让HashMap有序

问问题的时候,二面面试官边面试还在边拿着本子修复线上bug(看起来来的不是时候...)

当时考虑时间很短,没有什么好的想法。

于是说HashMap为什么插入读取是无序的,因为其为了快速查找定位的hash算法,导致其在数组中散列。

如果不使用链表记录顺序的话,可能就想着有个有序的队列之类的来记录索引,从而遍历。

答完之后,个人感觉答得不好,不过也过了。

3.3 三面

三面主要是人事面,聊了聊公司业务,公司目前融资情况,公司人员情况。

人事主要就是聊人生聊理想,问了问上一家离职原因,期望薪资以及入职时间。

最后因为一面和二面,几乎技术面试无死角无短板,哪怕是不擅长的技术问题,也会给出自己的一些思考。

所以最后得到了面试官一致的认可,直接就给出了38万年薪的offer,自己也没有继续面试,直接就去了这家公司。

一大波微服务、分布式、高并发、高可用的原创系列文章正在路上,

欢迎关注公众号:石杉的架构笔记

周一至周五早八点半!精品技术文章准时送上!!!

十余年BAT架构经验倾囊相授