写这篇文章的缘由是来自己最近我作为面试官的一场面试,我司是。Net stack,这场面试的岗位是后端高级开发。候选人是一个 12 年工作经验的候选人,简历看起来很 nice,国内某 TOP 高校 cs 专业本科毕业,有在大厂甲方外企的经验,而且第一轮在线算法题是 100%过,乍一看貌似是一个非常牛的大佬,但是经过第二轮面试,让我并不这样认为了,并且让我有了一些思考。
我们第二轮面试的内容整个面试 90 分钟,前 30 分钟两个面试官会问一些技术方面问题,基础为主,然后后 50 分钟当场根据需求写一个应用,最后 10 分钟互动,大概就是”你有什么想问我们”的环节。
先说一下前 30 分钟,我和另一个面试官的问题大多是一些 C#/Sqlserver 的基础问题,类似“请谈一谈你对接口和抽象类的理解”,”聚集索引和非聚集索引的本质区别”,再就是摘了一段我们实际项目中的包含子查询的 Query, 然后让候选人解释一下逻辑,然后说一下执行顺序。
其实在我看来,这 30 分钟就是在暖场,因为这些问题对于一个 10 年+的程序员来说无异于送分题,我们的目的也是如此,通过一些基本功考察的问题,来让候选人进入状态,消除紧张情绪,然后进入下一个环节。但是,这个候选人的缺表现让我们大跌眼镜。一开始,这个候选人不太能分清楚抽象类和接口的使用场景,被我捕捉到以后我问道:“抽象方法和虚方法的使用场景呢?”候选人直接说不知道虚方法,至此,我开始怀疑这个候选人基础是不是不太扎实。接下来另一个面试官开始问那段 SQL 的执行逻辑,SQL 大概如下:
SELECT SUM(D.a), D.b, E.c FROM D
LEFT JOIN E ON D.id = E.id
WHERE D.Date >’2022-01-01’ AND D.Date < ‘2022-12-31’
GROUP BY D.b, E.c
HAVING SUM(D.a) >= 100
ORDER BY E.c
从逻辑上来讲,候选人确实说清楚了,但是当我们问道执行的步骤或者顺序的时候,候选人是不太了解的,我同事问道:“在工作中有没有看过 SQLServer 的查询计划呢?”候选人表示不知道查询计划是什么。当然后面我们也问了关于索引,窗口函数之类的问题,候选人基本上没办法回答上来。
接下来进入写代码环节,需求大概是要求写一个员工管理程序
能够计算所有员工的平均工资,
能够计算 A 部门员工平均工资
能够计算 B 部门员工平均工资
自己写用例,并且能显示出来
考虑扩展性
不限于用什么框架,console, winform,web 什么都可以。
候选人一上来建了 console 的 proj,然后直接在 proj 里面建了一个 Employee 类,在 main 函数里面写计算逻辑。
他当时建 Employee 类大概是这样
public class Employee
{
private string name;
public string Name{get; set;}
private decimal salary;
public decimal Salary{get;set;}
private string department
public string Department{get;set;}
}
我打断他问他为什么要建私有字段但是又不在属性里面封装?候选人恍然大悟,赶紧删了私有字段。接下来候选人竟然直接使用了字符串作为 department,甚至都没有用 enum, 然后再计算平均值的逻辑中直接用字符串来标识部门:
employees.Where(e=> e.department == “A”).Select(e => e.Salary).Average()
随后候选人在 main 方法里面写计算平均值的逻辑,足足花了不止 20 分钟,因为类型问题,一直红波浪,直到我们提醒他可以把鼠标挪到红波浪上检查一下 error,看看是什么问题,候选人才把问题解决了。最后,50 分钟到了候选人并没有成功输出结果。其实我们的期望是,候选人能分别建 proj 来作为 client(console),bisuness(计算逻辑), model(员工类),并且使用 employee 作为基类,使用子类继承基类来区别 A 部门和 B 部门员工,如果不用这个设计,起码要用 enum 来作为部门的类型。最后,用接口来规范计算的方法,在 client 通过依赖注入解耦,当然直接通过接口来实例化也行,起码要有解耦的思维,而不是一股脑的把逻辑全部写在 main 函数中。
在最后的环节中,我看候选人也挺不容易,还是想给一些机会。
于是我主动说:“你有什么比较擅长的,也可以跟我们交流交流,比如缓存中间件, 消息中间件,容器,编排,前端框架,什么都可以。“
结果候选人说:”我都不了解,我只会.net“
我还是想再给给机会:“要么你介绍介绍你遇到的最难得最有挑战一个 bug 或者需求,然后你是怎么解决的“
候选人说:“技术方面确实没有遇到过什么太难得,只是有一次一个 legacy 系统重构任务交到我手上,然后我协调各部门重新梳理需求,重构出来了“
我:“技术上有没有什么挑战吗?“
候选人:“没,技术没什么好说,主要是需求整理难度比较大“
到这里我是真的没办法了,后面问了一下候选人跳槽的原因,他说是因为长期在甲方越来越多的技术任务都外包给乙方,而他的角色从技术人员转化为管理乙方的人员,但是他还是想做技术。但是我觉得挺矛盾,一个喜欢技术的人为什么技术会如此单一呢?单一也没问题,但关键是基础还如此薄弱呢?
这个候选人国内 Top 高校毕业,并且能进外企甲方大厂说明当年技术肯定不差的,基础肯定也相对扎实,但是是什么原因让他在多年后基本功如此拉胯呢?我想,这也是很多程序员正在经历的:随着项目的经验越来越丰富,却与基本功渐行渐远。不可否认,如今框架给我们解决了太多的问题,但是这并不代表着我们就可以完全扔掉基本功。
我们有句名言:“我做出来即可,能跑就行,你为什么还有那么多要求?“如果把写代码比作建房子,地基扎实的房子和直接从地面起的房子,可能从外观上看一模一样,当阳光灿烂时,它们看起来并无差别。但是别忘了,你不会知道暴风骤雨何时会来临,当面对风雨打击的时候,这两个房子会有截然不同的结果。
列位,请警惕起来,千万不要丢掉自己的基本功,在经验日渐丰厚的同时,基础也必须要越发的牢固!
- EOF -
推荐阅读 点击标题可跳转
0、极客专属:几十款程序员秒懂的卫衣
1、支付宝大整改,花呗、借呗退出江湖
2、从前,有两个卖水果的公司……
3、今年这情况,咱还是留个心眼吧!
关注「程序员的那些事」加星标,不错过圈内事
点赞和在看就是最大的支持❤️