小弱石的求职季笔记(二)
比较知名的互联网公司就只投了网易和欢聚,其它的都完美错过......
于是从欢聚那失败归来后,赶紧印了数份简历,每天跑来跑去听宣讲会。
厦门这边正好就来了几家搞游戏的,于是就去看了...
三、厦门吉比特,游戏研发(一面挂,后来问要不要先去实习看看,如果能力可以会转正,没去)
刚看到这个公司的时候,感觉从来没见过...然后看了介绍,居然是以前做出《问道》的那家公司。
吉比特今年开出的待遇非常好,技术类月薪12k~18k,福利在厦门也是比较好的,笔试的时候整个大教室都坐满了,竞争挺激烈的。
笔试的话大部分都是c/c++的基础题,还有一些算法题,也参杂一了些Java和操作系统的问题,平时有做过题目的话基本上就OK。
然后顺利进入一面,面试官挺好的,比较有耐心,也不会专门往刁钻的地方提问。
开始时先让自我介绍,然后大概问了一点基本情况,学习成绩什么的,然后就开始问笔试时的一些题。
1. 第一个是最大子序列和问题:
a. 当时不记得动态规划怎么写了,就说了O(n^2)的解法:
int subMaxSum_1(int input[], int size)
{//对数组每一位,计算其向后累加和,累加过程中记录最大值,最终结果即为所求最大值
//O(n^2)
int subMax = 0;
for(int i = 0; i < size; i++)
{
int sum = 0;
for(int j = i; j < size; j++)
{
sum += input[j];
if(sum > subMax)
{
subMax = sum;
}
}
}
return (subMax > 0) ? subMax : 0 ;
}
b. 回去后把动态规划(O(n))的方法撸了出来,加深印象:
int subMaxSum_2(int input[], int size)
{//利用动态规划方法
//nAll[i] = max(input[i], nEnd[i], nAll[i-1])
//nAll为0~i的最大的一段数组和,nEnd是包含input[i]在内的最大一段数组和
//O(n)
int subMax = 0;
int nEnd = input[0];
int nAll = input[0];
for(int i = 1; i < size; i++)
{
nEnd = max(nEnd + input[i], input[i]);
nAll = max(nEnd, nAll);
}
return nAll;
}2. 第二个问题是最长相同子序列问题,当时好久没看算法,把这个给忘了,感觉要想出来可能还得思考一段时间,于是就说不太会,换个问题。回去后赶紧把这个问题撸出来,以防以后再问:
int subSequenceMax(char *str_1, char *str_2)
{ //动态规划方法,O(n^2)
int len_1 = strlen(str_1);
int len_2 = strlen(str_2);
int **maxLen;
maxLen = (int**) malloc(sizeof(int*) * (len_1 + 1));
for(int i = 0; i < len_1; i++)
{ //申请空间,需要注意用for循环分别申请
maxLen[i] = (int*) malloc(sizeof(int) * (len_2 + 1));
}
for(int i = 0; i <= len_1; i++)
{
for(int j = 0; j <= len_2; j++)
{
if(i == 0 || j == 0)
{ //对矩阵进行初始化
maxLen[i][j] = 0;
continue;
}
if(str_1[i - 1] == str_2[j - 1])
{ //如果检查到相同字符,则加1
maxLen[i][j] = maxLen[i - 1][j - 1] + 1;
}
else
{ //如果是不同的字符,矩阵内对应的值为前一情况中的最大值
maxLen[i][j] = max(maxLen[i - 1][j], maxLen[i][j - 1]);
}
}
}
for(int i = 0; i <= len_1; i++)
{
for(int j = 0; j <= len_2; j++)
{
cout << maxLen[i][j] << " " ;
}
cout << endl;
}
int result = maxLen[len_1][len_2];
return result;
}主要是推出来递推的表达式就搞定了~3. 换了个问题,就开始让我手写算法了,求1~100的素数,这题看似容易,实际上还有些要稍微深入讨论的问题...
a. 首先想到的就是,遍历and对每个数检查到其开根号的位置:void method_1(int n, int m)
{
for(int i = n; i <= m;)
{
bool flag = true;
for(int j = 2; j * j <= i; j++)
{ //这里原本写的是 j <= sqrt(i) + 1, 面试官说,实际上sqrt开销比较大,让我看看怎么更快处理这个地方
//当时就想着 i 开根号有什么更高效的方法,就没想出来,结果竟是 j * j 来替换,头脑没转过弯来啊hh,以后得记住喽
if(i % j == 0)
{
flag = false;
break;
}
}
//if(flag) cout << i << " ";
if(i % 2 == 0) i++;
else i += 2;
}
cout << endl;
} 这里面试官还问,为什么检查到开根号位置就行了,当时本来是有思路说出来的,结果突然想到16,开根号是4,但是又有2 * 8 = 16,突然就短路了......
实际上,如果一个数x = m * n 如果m和n都大于sqrt(x) 则m * n大于x,故肯定有一个因子小于sqrt(x),于是只需要检查到sqrt(x)就够了。
b. 然后面试官说,对于每个非素数都有一个性质,就是它定能分解成素数的乘积,于是利用这个性质再写这个算法,当时由于直接再原来写的算法上补写,写得比较乱,不过基本上是写对的,实际代码应如下:
void method_2(int n, int m)
{//利用非素数可以分解为素数乘积的性质,对每个数先采用已知大于1的素数进行测试
//若已知数已测完还未达到开方条件,则再依次加1进行判断
int *result = new int[m]; //记录已找到的素数,用于之后的检查
int count = 0;
for(int i = 1; i <= m; i += 2)
{
bool flag = true;
int j = 2;
for(int z = 1; z < count; z++)
{
j = result[z];
if(j * j > i)
{
break;
}
if(i % j == 0)
{
flag = false;
j = i;
break;
}
}
for(; j * j <= i; j++)
{
if(i % j == 0)
{
flag = false;
break;
}
}
if(flag) result[count++] = i;
}
for(int i = count - 1; i >= 0; i--)
{
if(result[i] < n)
{
break;
}
else
{
cout << result[i] << " ";
}
}
cout << endl;
delete result;
}代码实际跑了一下,检查1~10w的素数,确实第二个方法快了很多倍。
最后面试官的评价是:基础不错,学习能力不错,但实际经验太少,需要加强。
过了几天通知面试没过,又再过了几天打电话来问要不要去实习,当时很犹豫,因为没有offer......
四、厦门极致游戏,游戏研发(二面后,没过)
这个极致游戏的老板是当年搞出问道的人,前几年从吉比特出来自己搞了这个公司,目前发展得不错,虽然没有红爆半边天的游戏,但是今年也已经上市了......而且这公司关于加班的理念、制作游戏的理念也比较符合我个人理念,当时二面后就想着,如果能给offer就直接毫不犹豫签了,在这个地方肯定能好好做技术,以后发展机会大,而且开出的薪酬也不错,有6k~10k,福利很多,在厦门这待遇已经是很好了。
燃鹅没拿到offer,这就尴尬啦...
笔试的话也是比较基础的题,不过比较坑的是,有两个大部分:逻辑题,专业题。
逻辑题就是那种智力题,从几个人说的话中获取信息,判断出每个人是什么身份之类的。花了挺多时间在这部分,后来发现不太好做,做了大概3题就赶紧去做专业题了。
专业题不难,也都是些基础的东西,总之算法和数据结构、c/c++基础基本上都是必考的。
一面技术面,面试官主要是问个人做过的项目上的问题,我在简历上写了个Java分布式爬虫的项目,于是就开始追根究底......只要项目自己是有认真做,基本上没太大问题就是。然后也问到了虚函数,这时候对虚函数有过复习,但是没有实际上机去试试,结果...
项目之外的问题主要就是虚函数相关问题,问题其实都挺简单,但当时没答上来,吸取教训,把虚函数相关问题复习复习:
1. 虚函数:
在基类中冠以virtual的成员函数,它提供一种接口界面,允许在派生类中对基类的虚函数重新定义。其主要作用是实现多态。
(多态:是对于不同对象,接收相同消息时,产生不同的动作。)
2. 虚析构函数有什么用处:
一般基类的虚构函数都会声明为虚函数,这是为了防止内存泄露问题的发生。如果不声明为虚函数,当使用基类指向派生类的指针调用析构函数时,只会执行基类的析构,如此子类无法正确析构,导致内存泄露。这里要注意,纯虚析构函数需要给出定义。
3. 纯虚函数:
在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。作为接口而存在。纯虚函数一般不能直接调用。
例子: virtual void demo() = 0; 注意这里不用实现。
二面就是HR面了,感觉交谈得挺愉快的,有种这次能成的错觉......
最后总结,还是因为实际经验太少,有很多实战时的最基本的问题,比如虚析构函数作用这类问题都不了解。
得多撸代码才行啊!~
五、厦门飞鱼科技,游戏研发(一面未过)
飞鱼,就是开发了《保卫萝卜》的那个,待遇不错,不过没明说。不过据说加班比较多......
笔试题目基本上也没什么问题。
一面本来是技术面,然而进去后一个面试官直接就开玩手机,然后另一个让我自我介绍。
介绍完后,基本上就是根据简历上面写的项目问了问,也没怎么深入。
感觉就是看不上我,走个流程赶人吧,总之并没问什么技术问题......
目前比较需要记录的就是这几个了......接下来还得继续战斗,跑宣讲会,刷笔试......
给自己加油!

浙公网安备 33010602011771号