前言
在2016年的校招过程中面试了很多大公司,做了很多套笔试题,遇到了很多算法面试场景。深知其中的水深火热,笔试中绝大一部分是算法题,如果连算法基础题不及格,就会失去见到面试官的机会。当然,自己也不能算是精通,只能说有一点个人经验,趁热打铁分享一系列校招算法基础方面的东西,我会利用空闲时间不断更新这个系列,直到完成。自己在大学阶段的算法称不上很好,只把算法与数据结构学习过,刷过一些小题目,前后Offer共有七八个吧,都是互联网公司,目前入职某个互联网大厂。
面试过程中也遇到了因为算法太差引起的尴尬,原本很简单的算法题,回答并不好,本系列主要以我的面试为线索,做一个算法笔试面试总结,本系列从【笔试面试的算法和编程】开始。
笔试面试的算法和编程
不说鸡汤了,直接上代码,用C语言实现函数void *memmove(void *dest, const void *src, size_t n)。memmove函数的功能是拷贝src所指向内存内容前n个字节到dest所指的地址上。
下面写一个错误的代码作为反例,也是最容易想到的实现方法
void *memove(void *dest, const void *src, size_t n)
{
char *p1 = dest;
char *p2 = src;
while (*p2 != \0)
*p1++ = *p2++
return p
}
这个函数咋一看比较正确,其实漏洞百出。
错误的思路
两个指针分别指向dest地址、src地址,然后将src地址中值存放到dest地址中,完事。
正确的思路
先不说指针的初始化这些小问题,问题比较大的是内存重叠、临时变量没有释放、没有考虑内存越界、指针操作错误。
要结合memcpy函数的优缺点,它不具有内存重叠检查,而memove具有这个检查特性,这也是面试经常考察的地方,对于内存边界的敏感性。
正确的代码
void *memmove(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_source, *tmp_dest;
tmp_source = (char *)source;//注意,void*类型不能直接操作,需要进行转换。
tmp_dest = (char *)dest;
if((dest
在这份正确的代码中就有考虑到内存重叠问题,做了很好的判断,并且对指针操作的规范性做了很好的处理,比如void 类型不能直接被操作,需要进行char转换,还有assert断言进行地址是否有效的判断。
总结
从这个简单的算法小题就分析出面试官需要什么样子的答案,你说第一个,部分正确,可能你的面试就被减分一半,如果你能用assert考虑到空指针的情况,就对了一部分。加入还能考虑到内存重叠问题,那就更好了。如果你还能针对内存重叠有各种算法的优劣比较,和面试官讨论下,就能进BAT,因此,学会写算法,面试算法是一个技术活。
下面是算法面试的干货
“算法”与工作
以前自己也不重视算法,对ACM也是漠不关心,觉得公司的项目和算法没有任何关系,其实错了,算法是一种能力的体现,算法优秀的话在处理很多细节问题,更加有效率,也是求职的必经之路
怎么进入大公司
作为亲身经历,算法肯定是优先考虑的,好的算法会带来业务的效率提升,大公司很多业务也需要优秀的算法去设计实现
基础差,如何提高刷题速度
首先弄清楚思路,白纸书写,然后调试。算法归类和总结,算法没必要很高难度,图论,动态规划可以放一下
如何转行找IT工作
首先简历关,多涉及IT方面的技能,组织和活动能力,在某一方面有程序员的实力,找入手的岗位,不要眼高手低,如果之前是数据分析,就转行数据库方面的,如果之前做过美工,就转行前端入门岗位,对服务器熟悉,就去做各种flask,django,webpy,ngix。充实简历,尽力描述自己的技能,自己带一些项目,算法基础不错,超过面试官的预期
面试过程中的交流沟通
换位思考,多交流自己的想法,不要茫然下笔,解释想法,补充想法
面试过程遇到BUG
通过testcase,定位BUG,理清思路,动手修改。
解决BUG的方式,先问Google,再问人,一定要强调debug能力
推荐算法书籍
《The Algorithm Design Manual 》
《Cracking The Coding Interview (CC150题)》
《剑指offer》
《进军硅谷》
在线算法资源
LeetCode OJ
我的算法之路(书籍和成长经历)