昨天上午刚改好简历,bb还没回我修改意见就直接发了,没想到当天下午就接到了面试通知,说明天就要面。早晨有考试,还有另一门结课,于是定在了15:00
13:50出发,14:40到达三里屯soho
前台美女挺漂亮,妆略浓,微俗。装修很好,白色风格,显得干净。
之前简单查了下小伙的资料,本科吉大计算机,研究生北大信科,11年届,宣传海报上有图。
14:50,一面
唠家常,扯简历,blabla一大堆,这时我还蛮有激情的,状态很不错,对自己比较满意。
问了些基础的,什么TCP握手啊,乱七八糟的。
开始做题,
第一道,归并排序,递归非递归。没什么意思
第二道,二叉搜索树变有序双向链表,直接用递归写就好,只是好久没用链表指针什么的,有点生疏,而且困劲上来了,毕竟今早晨不到7点就起了啊!最后看着自己写的代码都迷糊,勉强过关。
小伙说挺好,没啥事,我去给你找二面。
趴桌子上眯了一会,更困了……
15:50左右,二面
一个比小伙岁数大点的小伙,略傲,不娇,不过显然要比小伙有气场多了,没家常,直接扯简历,可之前扯的已经很多很详细了,我是有点累了,也没刚才有激情了,随便说了说就结束了。开始做题。
只有一道,有重复元素的一个有序数组,统计value出现的次数。
实在是太累了,做了好久,结果页不是很满意,傲不娇还给我又倒了杯水,最后给的算法思路是对的。其实很简单的一道题,就二分查找嘛。代码稍后补上,见附[1]。
期间傲不娇还说了一下(start+end)/2的溢出问题,我改成了(a/2+b/2+(a%2&&b%2)),傲不娇说要更直观一点。
不知道啥叫“直观”,他也没继续纠结,就说回去查查,附[2]平均数的溢出问题。
傲不娇已经玩了半天手机了,总结是“你有解决问题的能力,不过怎么这么绕呢”。
我也没好意思说又困又累。
他出门前指了下厕所,然后找三面了,我也懒得去。
赶紧站起来,伸懒腰,拉筋,做活动,好不容易精神起来了。
16:35?忘了,三面
一位大哥,气场更稳重了,进门就一句话“继续写代码”,我还在那拉筋呢,忙站起来说好。
第一道,输入一个由数字组成的字符串,要求输出的字符串中不包含5和连续的10
我还以为是算法题,想了想什么调换位置啊,什么乱七八糟的,也是有点蒙。
大哥说不是算法题,就是写代码的题,还直接说让我考虑150,我才明白过来是“输出字符串中不包含”
然后落笔开始写,先打给个草稿,然后整理了一下。
整体比较简单,只是细节问题,最后他看的时候我又补了几个小毛病,他在那写测试样例的时候我又发现了个小bug,11550000,后面的0比前面的1多时的情况,然后又加了两行代码。只不过当首部需要删除的时候有个退化,O(n)的问题编程了O(n^2),问题不大。最后见附[3]。
第二道,不用写代码,直接说算法。
大哥一直很严肃,这题题说的很萌:一个环,还上一些节点,奥特曼打小怪兽,有的屋子是一堆怪兽,有的屋子是一堆面包,打怪兽掉血,吃面包长血。假设奥特曼走完一圈一定能活下来,问从哪走能活。如图所示,其实挺简单,随机选一个作为起点,一个一个往后加,如果加和成负值了,往前提起点,直到加和为正时再往后走,挺简单的,就不说了。
第三道,说的也很萌,估计这大哥以前是搞ACM出身,A到B地的公路里程牌,一面是A到B剩余的公里数,另一面是B到A的,但风很大,说不定就把牌子给吹转向了,给一组序列,判断是否是一组合法的牌子序列。
这题有点意思,给出的答案应该问题不大,还需要整理,不过估计他当时也累了,我俩都懒得细想了。答案见附[4]。
最后一般都是这个:“有没有什么问题了。”我客套了一下,然后问“您觉得在大公司和创业公司工作有什么区别,有哪些优劣。”他说我不是在“海鱼”那干过么,我说我想听听您的意见,他还说他听说“海鱼”那好像不太行了。
关键要看你所在的团队,离你最近的这些人的水平,所以去大公司重要的是看mentor
1.大公司升职慢,一个萝卜一个坑
2.大公司时间多,成长慢,不过可以自己做code review,慢慢雕琢
3.大公司稳定,还炫了一下他们已经融到B轮了
17:45,再见。
倒是没什么新颖的,倒是跟我爸说的个别观点有点像。
总之,题保持稳定的刷,科研实习总要有一种。等消息,机会对半开吧。
附[1]
#include<stdio.h> #include<stdlib.h> int binary_search(int a[], int n, int value, int direct) //left is 0, right is 1 { int start = 0, end = n - 1, mid; while (start <= end) { mid = (start & end) + ((start ^ end) >> 1); if (a[mid] < value || (a[mid] == value && direct == 1)) { start = mid + 1; } else if (a[mid] > value || (a[mid] == value && direct == 0)) { end = mid - 1; } } return mid; } int main() { int a[12] = { 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4 }; int value = 3; int left = binary_search(a, 12, value, 0); int right = binary_search(a, 12, value, 1); left += (left != value); //这里要注意一下,有可能直接把value划外面去了,就是可能得到的位置是2的最后一个 right -= (right != value); printf("%d\n", right - left + 1); system("pause"); }
附[2]
double avg_positive(int a[], int n) { int i; double result = 0; for (i = 0; i < n; i++) { result += (a[i] - result) / (i + 1); } return result; }
这里直接默认数组a是递增的了,否则括号要价格绝对值,可以解决正数的平均数,有正有负的话还是会溢出。
多个数的时候可以这样做
double avg_positive(int a[], int n) { int i; double result = 0; for (i = 0; i < n; i++) { result += (a[i] - result) / (i + 1); } return result; }
当只有两个数的时候,除了上面提到过的,还可以用位操作的方式,前提是同号,显得更高端一些
int avg_two1(int a, int b) { return (a&b) + ((a^b) >> 1); }
证明如下
对于c=(a+b)/2,按位表示为a[n]a[n-1]……a[0]和b[n]b[n-1]……b[0],可以证明c[i]=((a[i+1]+b[i+1])的低位)+((a[i]+b[i])的高位)
(a[i+1]+b[i+1])的低位 = a ^ b
((a[i]+b[i])的高位) = a & b
所以 c = (a ^ b >> 1) + (a & b)
写一下就都清楚了,面试时可以写出来尝试着虐虐面试官。