C/C++笔试和面试过程中难免会要手撕代码,那么手撕代码,面试官或者看试卷的人一般会看哪些点呢?我列举了一些我认为的点(码农适用):
算法正确这是最主要的点,如果算法都不对,就是直接0分了;代码逻辑要清晰明了,考虑问题要全面,逻辑一混乱,基本就是60分左右了;如果代码风格很丑,基本是不会看的,又或者很简单的一个题,写了一百多行代码,这也是不会看的;如果算法不是常规的算法,建议最好写出注释,不然有些面试官看不懂就直接GG了,变量命名一定要有含义,不要通篇都是a
, aa
, b
这种;STL/C++11, 这可以表现你的知识面的宽度,能用上肯定是加分的;最后一点,不要雷同!不要雷同!不要雷同!很多人都是拿来主义,网上一搜,Ctrl + C
, Ctrl + V
完事,很多博客上的代码不一定正确,且你会这么复制大法,别人也会,这么多试卷,那就有很多雷同的,这种情况是直接0分,所以说复制也要有态度。
手撕代码考察的就是上面的几点,其实手撕代码和OJ那种考察的侧重点不一样,OJ那种是结果导向,你的结果是正确的,我管你怎么来的,考察算法较多,这种OJ的题一般会比手撕代码难一些,而手撕代码考察的是的工程能力,因为招你进来做C/C++项目的,你给写了一个这么挫的代码,改都难改,所以手撕代码考察实践较多,做码农就要有做码农的觉悟,且只要你满足上面几点,即使你的代码有一些细节错误,也会给满分。
且,这种手撕代码的题一般都是要你补全一个函数,而且大部分会和字符串相关,因为字符串类的题目最考细节了,难度不大,但是能看出一个人的编程素养。
举个例子,实现一个函数,这个函数的作用是把IPv4类的点分式地址转化成一个无符号的32位整数,如果转化不了,请抛出异常。
不难吧,但是代码怎么写才是最简洁最高效的呢?先分析下这个过程该怎么做。
就是这三个步骤,用C++代码实现出来,补全这个函数ConvertIPv4ToUint32
。
std::uint32_t ConvertIPv4ToUint32(const std::string & address)
{
static const int NUM = 4;
int digit[NUM];
char skip[1 << 10];
int num = std::sscanf(address.c_str(), "%d.%d.%d.%d%s",
&digit[0], &digit[1], &digit[2], &digit[3], skip);
if (NUM == num) {
if (std::all_of(digit, digit + NUM, [] (int x) { return x >= 0 && x < 256; })) {
uint32_t ret = 0;
for (int i = 0; i < NUM; ret |= digit[i] << (8 * i), ++i) {}
return ret;
}
else
throw std::invalid_argument("out of range");
} else
throw std::invalid_argument("paste error");
}
上面这个代码还是比较简洁的,用到的几个点如下:
sscanf
的运用std::all_of
std::invalid_argument
异常这里提供一些测试用例,如果这些用例没问题,那就没什么问题了。
std::vector<std::string> arr
{
"1.2.3.4",
"255.255.255.255",
"3 3 3 3",
"256.255.255.255",
"x.x.x.x",
"0.-2.2.2",
"0.0x3.2.2",
"0.02.2.2",
"0.02.2.2.2",
"0.02.2.2a",
"ab.0.0.0.0",
"0.123..0"
};
for (auto & ele : arr) {
std::cout << ele << std::endl;
try {
printf("%x\n", ConvertIPv4ToUint32(ele));
} catch (const std::invalid_argument & e) {
std::cerr << e.what() << std::endl;
}
}
总结一下,没事的时候还是多动动手写写代码,多了解一些新的知识。Offer自然就到手了。