近日, 华为轮值董事长徐直军撰写了《关于公司高端精英类, 软件类人才面试方法调整的建议》. 其中重点讲到: 软件类人才面试要以考察软件工程能力与编程能力, 识别出真正的软件开发与设计高手. 文章也给出了具体的考核方式:
应聘人员首先应该进行网上编程, 时间 90 分钟, 网上编程符合要求的进入面试环节.
在网上编程环节中, 有两轮面试, 每轮 45 分钟. 每轮面试当面或视频面试, 考察实际编程能力及相关知识技能的掌握程度. 编程时间 30 分钟, 提问与讨论 15 分钟.
看到网上编程的时候, 我立刻想到了 ThoughtWorks 这家公司. ThoughtWorks 的面试重点就是考核面试者的编程能力和设计能力. 面试者在正式面试之前, 首先会受到一个 homework, 只有做完这个 homework, 并且达到要求的候选人才能进入后续的面试. 而后续面试也与我们平常的面试不同, ThoughtWorks 的后续面试都会围绕这份 homework 进行编程面试. 例如: 当场给出新的需求, 让你重构你原来的代码.
对于习惯了国内面试流程的开发者来说, 如果去 ThoughtWorks 面试, homework 过不了都是一种常态. 因为国内互联网公司因为追求速度, 所以很多时候就牺牲了代码的质量. 如果平时都是这么一种状态, 那么面试的时候自然不会考察编程能力了.
华为注重编程能力的考察, 注重软件工程实践也是一件好事. 短期来讲会提高门槛, 但是长期看来会提高编程的科学性, 减少重复劳动. 而且随着国内 IT 行业的不断成熟, 国内公司会越来越注重编程能力的考核. 那作为软件开发者的我们, 应该如何顺应这一趋势提升自己呢?
测试驱动
测试驱动是一种编程的思想, 简单地说就是用测试来驱动编程. 想象一下: 当我们在重构一个系统的时候, 如果没有测试用例, 那么我们重构完成之后怎么能保证它是没有问题的呢? 而如果你的项目一开始就是采用测试驱动开发的, 那么当你完成重构后, 只需要运行一遍测试用例, 就可以发现存在的问题, 从而减少潜在的 bug.
当然测试驱动并没有我说的那么简单, 上面只是测试驱动开发带来的一个好处. 真正的测试驱动需要遵循一套比较完整的流程:
首先, 分析需求, 针对需求编写测试用例.
接着, 针对测试用例编写业务代码.
接着, 对通过测试用例的代码进行重构, 使其更易于扩展.
最后, 还需要运行一次测试用例, 确保重构后的代码没有问题.
通过这么一种方式, 我们能够在一开始的时候就发现需求中的问题, 从而避免代码写完之后进行变更, 从而提高了效率. 而有了测试用例的存在, 我们可以确保重构时不会使原有功能受损.
设计模式
在测试驱动中我们说到重构, 而在重构中不得不说的就是设计模式. 设计模式对于初学者来说就像天书一样, 完全搞不懂它是做什么的. 但如果你有一定的项目经验和源码阅读经验, 你会发现设计模式的好处. 设计模式的本质是用编程模式去承载业务的复杂性, 使得业务代码更加容易扩展.
例如我们使用得最多的策略模式, 其实就是将每种可能的情况放到一个单独的类中, 使得每种情况单独分开, 从而有利于扩展和修改.
- public interface PeelOff {
- void peelOff();
- }
- public class ApplePeelOff implement PeelOff{
- void peelOff(){
- //deal with apple
- }
- }
- public class BananaPeelOff implement PeelOff{
- void peelOff(){
- //deal with banana
- }
- }
而模板模式在源码设计中也用得非常多. 例如在 AQS 的实现中, 在 AQS 的实现中调用了 tryAcquire() 方法, 但在 AQS 中的 tryAcquire() 方法中却没有具体实现. 这是因为其将 tryAcquire() 的具体实现交给了子类, 从而实现了实现方式的多样化.
- // AQS 的 tryAcquire 实现, 使用了模板方法
- // 在 AQS 中直接抛出异常, 没有具体实现, 具体的实现在子类中
- protected boolean tryAcquire(int arg) {
- throw new UnsupportedOperationException();
- }
- // 在 acquire 方法中调用 tryAcquire 方法
- public final void acquire(int arg) {
- if (!tryAcquire(arg) &&
- acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
- selfInterrupt();
- }
类似的设计模式还有很多, 这里就不过多介绍了. 从这些例子中我们可以看到, 因为设计模式的存在, 使得程序更加灵活, 更加易于扩展了. 了解常见的设计模式只是开始, 我们需要在日常工作中不断地尝试使用它们. 在不断的实践中加深对于设计模式的理解, 最终才能对设计模式有深层次的理解和运用.
重构
重构可以说是高级开发人员必备的技能了, 前面所说的设计模式在重构的时候会发挥很大的作用. 但设计模式只是重构过程的一个重要运用, 在重构过程中还有许多可以运用的原则, 例如: 单一职责原则等.
关于重构这块的知识点有很多, 这里就不深入介绍了. 关于重构建议阅读《重构》这本书, 相信会有不少收获.
软件工程
关于这块知识点, 我们许多人都是忽略的. 我现在能回想得起也是在大学的时候, 那时候有一门课程叫软件工程. 但是自从工作之后, 基本上就和软件工程断了联系.
随着工作年限的增长, 慢慢发现这块东西还是非常有用的. 特别是当你作为一个团队 leader 或项目经验, 要去管理整个技术团队的时候, 软件工程就是你必须要懂的东西. 我们前面所说的「测试驱动编程」就是软件工程中的一块, 除此之外还有「领域编程 (DDD)」等.
软件工程可以从项目角度让我们更科学地把我研发进度, 形成更合理的研发体系. 所以关于软件工程的知识点也是我们需要重点学习的.
总结
或许是由于 IT 发展历程的原因, 所以国内 IT 公司都不怎么注重编程能力和软件工程的考核. 但如果你有留意国外公司的面试流程, 你会发现国外公司都比较注重编程能力的考核, 通常都会有手写代码, 在线编程等考核. 我相信随着国内 IT 行业越来越成熟, 肯定有越来越多的公司将编程能力纳入考核范围.
对于软件开发从业者的我们, 我觉得这是一件好事. 编程能力的提升, 软件工程的实践会使得项目变得更加可控, 这在一定程度上会减弱无效的编程劳动, 提高软件开发从业者的幸福感. 与此同时, 它也对我们提出了更高的要求, 需要我们掌握更多的专业知识技能.
简单地说, 我们不应该只是简单地思考如何应付这次面试改革, 而应该去思考这背后的原因. 从而让我们的能力跟上市场的需求, 只有这样我们才能立于不败之地. 在我看来, 测试驱动, 设计模式, 重构, 软件工程是我未来要重点加强的能力.
对于这次华为面试改革, 你觉得软件从业者应该加强哪方面的能力, 欢迎留言讨论.
来源: https://www.cnblogs.com/chanshuyi/p/opinion_of_hw_interview_reform.html