那些年,我们一起跪过的算法题[视频]

那些年,我们一起跪过的算法题[视频]

今天打算用视频讲下面试中的白板编程并且直接手撸代码,我们以一个简单的 python cache 到常用和常考的 lrucache 的实现来示例。 算法题一直是求职面试中比较难的一环(活着就已经如此艰难了,他们竟然还要面算法,还记得 brew 作者面试 google 被拒的事情吗)。笔者刚毕业求职那会也因为算法题跪过不少,本身记性不好,经常忘记,性格闷骚沟通能力又差, 每次面试都要重新准备(曾经因为经验问题、性格问题、算法问题、数据库问题等被拒过)。 录个视频讲下白板编程希望能对求职者有点帮助。(吐槽下录个视频真不容易,中间各种小差错)

我们从提出问题 -> 分析问题 -> 纸笔模拟 -> 编码实现的顺序讲解。

  1. 如何在纸上描述思路(我将使用绘图软件和手写板模仿纸笔,画滴难看请不要吐槽)。 从一个简单的斐波那契函数引入python 中常用的 缓存函数
  2. 纸笔描述解题思路和流程图
  3. 如何根据纸上的草稿和流程图撸代码。白板编程的一些注意事项等

老实说要一次写对这个代码我觉得是有难度的,需要熟悉数据结构和实现、掌握 python 语法、严密的思维等。很多程序员是比较抵触白板编程的,但是对于复杂一些的代码实现,没有纸和笔等辅助工具光用脑子想是比较费劲的,我们的大脑并不擅长大量信息的缓存,也不擅长多线程工作。


https://www.zhihu.com/video/963744415218679808https://www.zhihu.com/video/963745585778606080

看完视频之后,我这里还有几个小问题大家可以在评论区讨论:

  1. 我哪里说错了?这段代码里有明显的 bug 吗?
  2. 如何用内置库的 OrderedDict 实现?你了解它的实现原理吗?
  3. 如何让我们的缓存装饰器支持多个参数?这里我用的斐波那契数函数只传入了一个参数
  4. 这个代码是线程安全的吗?如果不是为什么呢?怎样修改才能保证线程安全?
  5. 你能给它写单测吗?给这个代码写单测看起来并不是很简单,工程代码里单测是少不了的,否则代码有大 bug 了可不好。
  6. 你还能想到什么改进方式吗?
  7. 如果面试的时候算法题没有思路该怎么办呢?怎么忽悠和套路面试官


如何学习算法?

初学者推荐看看《算法图解》,我觉得用纸笔模拟算法过程是一个比较好的方式。如果你在啃《算法导论》(网上有公开课),基本上也是图示+伪代码。理解代码之后尝试用自己熟悉的编程语言实现,这里我用的是 python,python 抽象程度比较高,如果使用 C/C++ 你需要处理内存分配等细节问题,用 python 你可以真正把心思放在算法逻辑本身。


如何准备算法题?

当然笔者也很讨厌那种刁钻的和工作完全不搭边的算法题,毕竟不是所有工程师都参加过算法竞赛(主要是面试到我的话俺也不会)。这次示例的lru 缓存确实是在项目中我们真正使用到的,当然这个代码示例还很简陋,考察最好以工程中实际用到的东西为准。

  • 刷常见算法,手写,面试提前准备。常见的算法比如快速排序、二分、归并排序等最好能手写。我还是建议先理解后实现,这些算法包含了很多经典思想,如果只是死记硬背,面试一紧张就啥都想不起来了
  • 研究一些内置库的实现,比如 python 的 collections 模块(有些面试的同学居然没用过甚至不知道这个模块),然后尝试仿写一个简单版本。阅读源码+模仿

手写代码的一些注意事项

真实场景下如何在有限的时间内写代码?其实一般我们都是很基础的题目,不会刻意刁难面试者。都说面试造核弹,工作拧螺丝,面试尽量看面试者的知识经验和项目需求的匹配度。

  • 充分准备。带好纸、笔、简历,有些可以带电脑用电脑写代码,至少说明咱态度是诚恳的。我以前会带上自动铅笔和橡皮,写代码方便改。
  • 没事多练习。有些面试者一紧张大脑一片空白(我以前就这样),最好就是把常用代码练到手熟
  • 逻辑正确是前提
  • 有图示描述思路最好,如果时间紧代码没写出来,可以直接描述自己的思路。
  • 字不要写太大,尽量工整。每行代码之间留有一定的空隙,方便你修改
  • 如果实在写不出来可以和面试官交流,比如这题如果实在想不出来,能想到用链表也行。很多时候如果给不出最优方案尽量想一个次优方案,别上来就说不会
  • 想不起来的函数名写伪代码,一般面试官不会强制说让你记住每个 api 的名字
  • 如果有多余的时间(一般不会有)注意一些边界条件,防御性编程等

很多工程师写业务久了基础就忘了,而且面试也不准备,即使工作年限挺久了也可能会挂掉,所以还是多准备吧。有的公司比较重视面试者的基础,因为现在转行的也挺多,竞争越来越大了。 其实短时间内面试有时候很难准确地考察面试者,所以如果有 github 项目(不是直接 fork 别人的)、技术博客链接等能让别人多了解你的东西最好,这也是我一直坚持写博客的原因,推荐你也试试。(专栏、个人博客、csdn、gitbook 等都可以)。个人项目能直接了解你的编码风格、水平等,技术博客能展示你学了什么东西。

最后,如果你正在寻求新的工作机会(有项目经验能快速上手),欢迎私信,我们需要一起改(hao)变(hao)世(gan)界(huo)的小伙伴。 也欢迎各路大佬录制撸码视频分享下,互相学习,短视频目前比较火,希望能用它来直观地分享一些有用的小知识。

编辑于 2018-04-10

文章被以下专栏收录