腾讯2021暑期C++天美工作室游戏开发实习面试题&面经
Posted 遥远的歌s
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了腾讯2021暑期C++天美工作室游戏开发实习面试题&面经相关的知识,希望对你有一定的参考价值。
前段时间投了腾讯互娱群下的天美工作室,结果10分钟不到就收到了面试通知,约到四天后的晚上,我甚是期待,奈何这次面试给我上了一课,足足面试了我三个半小时多,而且还凉凉了,真是身心疲惫呀。
首先面试一开始,面试官给我直接说我们先来作题,我心想怕是动态规划的题就凉凉,果然面试官给了我三道题,第一题就是动态规划,看了一眼果断进军第二题。
第一题、获得目标数的总和
给你一个非负的数组nums,和一个key值,你可以再nums中每两个数中间任意加入`-`或者`+`,
使得其运算可以得到目标数key,请你返回能得到目标数key的所有方法的总和。
首先想到深度优先,遍历nums,从开头开始+
,只要小于key并且没有达到数组尾部,就继续加,直到大于key返回上一层变为-
后继续向后+
,以此类推,但是结果时间超时。而且废了我20分钟,我立刻放弃此题写下一题。后来才知道动态规划可以解决。
我已经将第一题的思路写了一篇博客,欢迎大家提供不一样的思路动态规划01背包的拓展问题
第二题、LRU的模拟实现,要求查询,插入复杂度都是O(1)
题目链接LRU缓存
这道题我用单链表实现的,面试官看完代码就问我时间复杂度,很显然不是O(1),他不是很满意。下来我自己想了想结合大佬提供的思路,使用list和unordered_map来实现
数据结构
size_t cap;//缓存容量
list<pair<int,int>> cache;//缓存块链表
unordered_map<int, list<pair<int, int>>::iterator> mp;//用来标记key值再list中迭代器的位置
思路
put的时候判断key值在mp中是否存在,不存在,则将pair<int,int> (key,value)头插到到cache的头部,如果存在,则将其取出并且插入到cache的头部。
上述执行完,只需判断当前cache.size(),是否大于容量cap,如果大于,则对list进行尾删,同时将mp中对应的key删掉。
get的时候,同样先判断当前key值在mp中是否存在,不存在则依据题目要求返回-1,否则表示存在。
接下来从mp中获取其对应的迭代器,从而获得该结点的信息,然后将该结点从这个位置删掉,再将其头插到cache中即可,再更新mp中其对应的迭代器位置即可
class LRUCache
public:
LRUCache(int capacity)
:cap(capacity)
int get(int key)
auto it = mp.find(key);
if(it == mp.end()) return -1;
auto pos = it->second;//获取当前key值在cache中对应的位置
int res = pos->second;//获取value值
cache.push_front(pair<int,int> (pos->first,pos->second));//将新节点头插
cache.erase(pos);//删除旧节点
mp[key] = cache.begin();//更新key对应的迭代器位置
return res;//返回
void put(int key,int value)
auto it = mp.find(key);//从mp中查询key是否存在
//如果不存在,则表示要更新
if(it == mp.end())
//将key和value构成一个新节点头插到cache中
cache.push_front(pair<int,int> (key,value));
mp[key] = cache.begin();//将key以及cache中key对应的迭代器的位置插入到mp中
//表示存在
else
//获取key值当前在cache中的位置
auto pos = it->second;
cache.erase(pos);//删除该结点
cache.push_front(pair<int,int> (key,value));//构建新的检点头插到cache中
mp[key] = cache.begin();//更新mp中key在cache中国的迭代器的位置
//判断当前cache的大小是否超过cap
if(cache.size() > cap)
//超过则对cache进行尾删
mp.erase(cache.back().first);//先从mp中删除对应的key值
cache.pop_back();//再进行尾删
public:
size_t cap;
list<pair<int,int>> cache;
unordered_map<int, list<pair<int, int>>::iterator> mp;
;
第三题、有效的括号字符串
题目链接:有效的括号字符串
这个题还算友好
给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
任何左括号 ( 必须有相应的右括号 )。
任何右括号 ) 必须有相应的左括号 ( 。
左括号 ( 必须在对应的右括号之前 )。
* 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
一个空字符串也被视为有效字符串。
示例 1:
输入: "()"
输出: True
示例 2:
输入: "(*)"
输出: True
示例 3:
输入: "(*))"
输出: True
注意:
字符串大小将在 [1,100] 范围内。
写这道题快完的时候网断了,重新连接上面试后之前所有代码全没了,面试官直接让我从写,从新计时一小时(心态都崩了)
言归正传,这和我之前做的一个题很类似,只不过这道题 *
不仅可以代替(
和)
还能代替空格,首选用栈,写到一半发现有种情况没考虑直接从来,又耽误了很长时间,之后使用双栈搞定
思路
定义两个栈st1和st2分别用来存储(
和*
的下标,那么分为以下几种情况:
- 如果为
(
则其下标入栈st1,如果为*
则其下标入栈st2。 - 如果为
)
则优先从st1中判断是否存在(
的下标,存在则出栈,继续向下遍历字符串,如果st1为空则再判断st2中是否存在*
的下标,存在则出栈,再继续向下遍历。如果st1和st2都为空,表示没有(
或者*
与之匹配,返回false。 - 如果遍历完字符串后,st1为空,则返回true,否则就要和st2中的
*
进行匹配,当st1的栈顶元素小于st2的栈顶元素则st1和st2同时出栈,否则返回false。 - 最后返回st1是否为空即可
class Solution
public:
bool checkValidString(string s)
stack<int> st1,st2;
for(int i = 0;i<s.length();i++)
//如果是(或者*则入栈
if(s[i] == '(')
st1.push(i);
else if(s[i] == '*')
st2.push(i);
//是)则进行匹配
else
if(!st1.empty())
st1.pop();
else if(!st2.empty())
st2.pop();
else
return false;
//剩下的(和*进行匹配
while(!st1.empty() && !st2.empty())
if(st1.top() > st2.top())
return false;
st1.pop();
st2.pop();
return st1.empty();
;
到这,三道题我就写了两道,其中第一道没有得到完美答案,第二道没让面试官满意。接下来开始问基础知识。
以下罗列
1.同学你了解C++的多态吗?多态是如何实现的?
2.构造函数可以是虚函数吗?为什么?
3.析构函数可以是虚函数吗?为什么?
4.快速排序的原理是什么?(霍尔划分,挖坑法,前后指针能说的都说了)
5.快排如何优化?(随机数法,三数取中,加入插入排序,递归变为非递归等能说的也都说了)
6.给你5000W数量级的数据,如何快速定位到我要找到的数据?(哈希表,B+树)
7.如果一个机器存不下5000W数量级的数据,怎么办?(当时脑子有点秀逗,答了个插入外存条,面试官直接笑了,就跳过了这个问题,现在想想,应该是使用布隆过滤器)
8.C++中提供的强制类型转换有哪些,有什么区别?
9.有了解过LINUX操作系统吗?它有什么优点?
10.Linux下I/O多路复用机制有哪些?区别是什么?(epoll,poll,select它们之间的区别)
重点来了,问完上述问题,面试官给我来了一句:前面三道题你写的不是很理想,来我们加试50分钟,再给你两道题写。
我内心:?????还能加试????
于是硬质头皮答应了,又给了我两个题
第一个就是自己实现memcpy函数,这个主要就是注意内存重叠的问题,拷贝的思路都么没问题,但是不知当时怎么了,犯了一个致命错误,void类型我返回了一个char*类型,导致面试官就不再看我的代码,直接看下一道题。
最后一题是以逗号为分隔符反转字符转中的单词
例如
输入:hello world,you bless god
输出:world hello,god bless you
这个没什么难度,先以,
为分界位置全部反转一次,再以,
和空格为分界位再反转一次就行
void reverse_str(string& str,int left,int right)
while(left <= right)
char tmp = str[left];
str[left] = str[right];
str[right] = tmp;
left++;
right--;
void str_reverse(string& str)
int begin = 0,start = 0,end = 0,flag = 0;
for(int i = 0;i<str.length();i++)
if(str[i] == ' ' || str[i + 1] == '\\0')
if(str[i + 1] == '\\0')
end = i;
else
end = i - 1;
flag = start;
reverse_str(str,start,end);
start = i + 1;
if(str[i] == ',' || str[i + 1] == '\\0')
if(str[i + 1] == '\\0')
end = i;
else
end = i - 1;
if(flag != start)
reverse_str(str,start,end);
reverse_str(str,begin,end);
start = begin = i + 1;
else
reverse_str(str,begin,end);
start = begin = i + 1;
终于,面试官问我你还有什么要问我的吗?我就简单问了下工作环境以及工作量。就结束了历时三个半小时的面试,真的身心疲惫。
第二天看了眼面试流程,变灰了,就知道凉凉了,虽然没有过,但是还是学到了不少,希望今后能够面试顺利!!
以上是关于腾讯2021暑期C++天美工作室游戏开发实习面试题&面经的主要内容,如果未能解决你的问题,请参考以下文章