面试官视角下的技术人如何实现有效“破圈”

5993eaff042eba31959bbf6a36109fc5.png

先声明本文非广告,请静下来慢慢品味食用

一、现状

最近面试了将近上百人,校招和社招整体五五开,校招生整体感觉技术能力相对比较薄弱,算法能力普遍较强,而社招情况恰恰相反。

二、分析

2.1 校招生

对于校招生而言,算法能力强原因主要有两方面:

  1. 刚刚学习完算法相关课程,参加各种竞赛,比如大学生数学竞赛、互联网+竞赛等等

  2. 有较多的自由支配的时间刷题,对于常见题型有很好的解题思路

技术能力从技术基础能力和技术应用能力两个角度来看,首先是技术基础能力普遍也很不错,主要原因:

  1. 学校开设相关课程,比如计算机系统结构、汇编原理、数据库技术、编程语言等等,部分同学能够做到熟练掌握如何应用,并且能通过应用层深入到底层源码实现,并且能更近一步深入到计算机编译层面,以理解应用层的技术工具是怎么工作的。

  2. 背诵八股文,没有理解这些技术为什么出现,用于解决什么问题;此种方式无法做到技术和应用融会贯通(面试中稍微结合工程问题就无法回答)。

技术应用能力偏弱,主要原因:

    1. 实习经历少;由于没有投产于实际生产环境,遇到的生产实际问题少。

    2. 校内学习项目:大部分项目只做了基本的CRUD以及一些技术组件的基本

        使用,技术复杂度低,通常遇到的问题也一般采用比较简单粗暴的方式解决

     (两种解释:i. 不解决业务也可接受;ii. 自身技术储备不足,无法解决)。

2.2 社招

对于社招同学而言,算法能力偏弱原因主要有两个方面:

  1. 工作时间越来越长,大部分人专注于业务功能开发和架构设计等工作

  2. 算法实际使用场景逐渐减少,对于复杂算法使用的场景更少

技术基础能力和技术应用能力普遍也更好,主要原因:

  1. 应对复杂诡异问题场景多,需要对底层运行原理有深入了解

  2. 真实生产环境为了解决各种业务场景,需要引入多项技术联合使用,以更好的解决业务问题

  3. 业务场景的不断锤炼,对技术的理解深度大大提升

三、如何破局

以校招为例,看看不同情况下的同学如何实现大厂offer梦,头部大厂对于校招生的筛选优先级:学长学姐内推 > 学历&实习经历 > 实习经历 > 学历,可以看出大厂对于实习经历的重视程度,所有大家一定要想办法尽早去实习,如果实在找不到,那就需要自己静下心来,好好钻研自己动手做的项目。下面我们来从几个个角度分析下如何破局。

3.1 找实习

学校和个人条件允许的话,从研二/大三上学期就开始着手去投实习简历,主要渠道:

  • 找往届学长学姐内退,可以达到事半功倍的效果

  • 主动去翻找各大公司招聘官网,一般都会专门设有【实习招聘】模块,去匹配适合自己的岗位,比如快手的实习招聘官网(https://zhaopin.kuaishou.cn/recruit/e/#/official/trainee/?workLocationCode=domestic)。

3.2 找项目练手

网上有很多开源的项目,比如GitHub上有仿12306系统、手写RPC框架、仿大众点评等等,划重点:不是完成基本的CRUD,而是需要将更多技术引入到项目中去解决更复杂的问题,并对引入的技术进一步深入学习和理解。

举个例子:用户下单场景,首先调用商品库获取商品信息,渲染下单页面,其次生成订单数据,调用库存系统扣减库存。

  1. 订单状态如何设计?

答:设计一个简单的订单模型,主要的状态有:预下单、支付成功、支付取消等

  1. 功能如何实现?

答:query商品库,写订单表,更新库存

  1. 订单表和更新库存有一个失败时如何处理?

答:query商品库,引入事务实现写订单表和更新库存

  1. 售卖的商品是个热销产品,大家都在同一时间抢购如何处理?

答:将热销产品提前加载到缓存中(引入缓存技术:Redis、memcache等),增加限流器防止大量流量同时涌入(引入限流器技术:令牌桶、漏桶、滑动窗口等)等等

  1. 单台机器接收的下单请求有限,但单机的处理能力上限在哪里?如何解决?

答:使用压测工具验证机器处理的处理水位线在哪里(引入JMeter、ab等压测工具),使用集群部署模式承载更多的流量(引入docker容器、k8s等容器能力)等

  1. 当订单库单表数据量达到千万级后,DB风险如何解决?

答:使用分库分表承载更大的读写能力(引入分库分表中间件Sharding-JDBC、Mycat、TDDL等)

  1. 引入分库分表后,事务问题如何解决?

答:引入分布式事务;采用最终一致的弱事务策略。

  1. 用户疯狂下单后不支付,超时后如何将订单状态流转到支付取消状态?

答:使用延迟队列完成订单状态的延迟处理(引入RocketMQ等带延迟处理能力的MQ);使用定时任务扫描。

通过以上例子,我们引入了大量的技术使得下单接口能力越来越强。对于大环境越来越不乐观,大家自然就卷起来了,所以仅仅解决了业务问题还不够,还需要对用到的技术有一些深入了解,比如系统引入了Redis,那么Redis的基本架构、字符串、list、set、hash等数据结构的实现原理,以及大Key、缓存穿透&雪崩等常见问题的解决方案。

当一个项目中使用到的技术组件有90%深入的了解之后,相信不管是应对实习、校招还是社招,在八股考核这一块基本上都不太会出现太大问题。

3.3 知识串联

一些同学可能会疑惑,我学习了很多知识点,但是从来没有思考过这些知识点为什么会出现。就像上学的时候,老师只是一味的给你输入知识,但这些知识有什么用?为什么用?什么时候用?全都是一脸懵,最终导致知识很快进入大脑,并光速从大脑格式化。

想象一门技术像一棵树,核心功能链路是树主干,在树干上分叉出来的分支是实现核心功能链路的多个知识点,随着知识点的不断加入,这棵树逐步变得枝繁叶茂,知识点通过这种串联方式可以得到有效的记忆和融会贯通。

举个例子:渲染一个商品页面的时候,为了能够以最短时间将商品基础信息,库存量,销售量,浏览量等数据组装起来返回给前端渲染,通过串行的方式从各个系统获取这些数据,接口响应时间势必会非常慢,为了加快响应速度,需要将串行获取数据的方式转换成并行,即同一时刻同时获取这些数据,那就需要引入线程池了(以Java线程池为例)

  1. 线程池怎么使用?

答: 自定义线程池/使用Executors工具类创建,代码示例如下:

// 方案1:自定义线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS,new ArrayBlockingQueue<>(10));

// 方案2:使用Executors工具类
ExecutorService executorService = Executors.newCachedThreadPool();
  1. 为什么生产环境都不使用Executors工具类创建线程池

答: 稍微深入源码查看,以newCachedThreadPool()线程池为例,点开源码可以轻松发现,线程池最大线程数设置了Integer.MAX_VALUE,可见线上如果使用的话,这个线程池会不断的创建线程出来,很容易将CPU打满从而引发障。

  1. Java的线程池是如何工作的?

答: 为了更好地使线程池安全运行,就需要了解线程池的基本工作原理了。首先创建线程池后等待任务提交,任务提交到线程池后,检查当前工作线程数是否达到核心线程数最大值,未达到则直接创建核心线程出来执行任务,若达到则将任务提交到阻塞队列里等待执行,当阻塞队列满时,则继续创建线程直到达到最大线程数,当任务还在源源不断的提交,则要执行对应的拒绝策略。简单运行原理了解到这里,就会对第2问有更深刻的理解了。

  1. 线程池运行状态和线程数是如何维护的?

答: 了解了基本原理之后,你是否会好奇线程数和线程池运行状态到底是怎么维护的,在稍微深入一步,你会轻松发现线程数和线程池运行状态是维护在一个AtomicInteger变量上,高三位用于存储线程池运行状态,低29位用于存储线程数,因为线程池运行过程中大量场景需要同时使用这两个信息,所以放在一起维护会更加方便。

  1. 为什么使用AtomicInteger呢?AtomicInteger的作用是什么?

答: 回答这个问题,我们就需要看看AtomicInteger的能力是什么?AtomicInteger提供了:i). 原子操作; ii).无锁机制,比synchronized更高效; iii). 适用于高频更新操作; iv). 适用于并发计数器等等。若要深入了解这些信息,就需要进一步深入到底层,去看看Unsafe类的实现,这里不再展开。

  1. 线程是如何工作的?

答: 创建出来的线程去执行任务,那么这些线程是直接通过Thread保存的吗?简单深入一步可以看到,这些工作线程是为包装成Worker对象,而Worker又继承了AbstractQueuedSynchronizer,即大名鼎鼎的AQS,为什么要继承AQS呢?那就需要深入了解AQS的实现原理了。

  1. AQS的实现原理是什么?

答: AQS的核心思想是利用一个虚拟的双端队列来管理线程,当线程请求一个由其他线程持有的锁时,这个请求锁的线程就会被包装为一个节点并加入到队列中。AQS使用volatile修饰的state变量来控制同步状态,通过原子的compareAndSetState方法来安全地更新状态(这里不会展开说,仅为了说明知识如何串联)...

  1. volatile的作用是什么?

答: 第7步引入了volatile关键字,那么接下来就需要知道volatile关键字的属性......

小结: 以线程池为主干的这棵知识树,我们引入线程池工作原理、AtomicInteger、AQS、volatile等等知识点,通过这种方式来将各种知识点串联起来,可以将知识从应用到理解又能提升一个层次。这也是知识串联的一个巨大好处。

后续

有的朋友看到这里还是会有疑问,比如我不认识什么学长学姐,没办法走内推渠道;我不知道项目难点如何发现和深入;我不知道如何将知识串联起来等等问题。我会根据这个疑问线,一点点深入,直到这棵知识树丰满起来。

接下来我会先开启一个知识串联系列,帮助自己和有机会看到本文章的同学,对知识进行高效串联和记忆。我会从本文提到的线程池case作为切入点,敬请期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值