7.1 案例一:(面试题67)把字符串转换成整数
在第 1 章中,我们讨论了面试的流程。通常一轮面试是从面试官对照简历了解应聘者的项目经历及掌握的技能开始的。在介绍自己的项目经历时,应聘者可以参照STAR模型,着重介绍自己完成的工作(包括基于什么平台、用了哪些技术、实现了哪些算法等),以及最终对项目组的贡献。
接着进入重头戏——技术面试环节。在这一环节中,面试官会从编程语言、数据结构和算法等方面考查应聘者的基础知识是否扎实全面(详见第2章),并且很有可能会要求应聘者编程实现一两个函数。如果碰到的面试题很简单,则应聘者也不能掉以轻心,一定要从基本功能、边界条件和错误处理等方面确保代码的完整性和鲁棒性(详见第3章)。如果碰到的题目很难,则应聘者可以尝试画图让抽象的问题变得形象化,也可以尝试举几个具体的例子去分析隐含的规律,还可以尝试把大的问题分解成两个或者多个小问题再递归地解决小问题。这3种方法能够帮助应聘者形成清晰的思路,从而解决复杂的难题(详见第4章)。很多面试题都不止一种解决方案,应聘者可以从时间复杂度和空间复杂度两个方面选择最优的解法(详见第5章)。在面试过程中,面试官除了关注应聘者的编程能力,还会关注应聘者的沟通能力和学习能力,并有可能考查应聘者的知识迁移能力、抽象建模能力和发散思维能力(详见第6章)。
在面试结束前的几分钟,面试官会给应聘者机会问几个最感兴趣的问题。应聘者可以从当前招聘的项目及其团队等方面提出几个问题。不建议应聘者在技术面试的时候向面试官询问薪资情况,或者立即打听面试结果。
接下来是两个典型的面试案例,我们从中可以直观地感受到面试的整个过程。在第一个案例(详见7.1节)中,我们将看到面试过程中很多应聘者都犯过的错误;而在第二个案例(详见7.2节)中,我们将看到面试官所认可的表现。我们希望应聘者能够少犯甚至不犯错误,在面试过程中充分表现出自己的综合素质,同时也衷心祝愿每名应聘者都能拿到自己心仪的Offer。
7.1案例一:(面试题67)把字符串转换成整数
面试官:看你简历上写的是精通C/C++语言,这两门语言你用了几年?
应聘者:从大一算起的话,快六、七年了。
面试官:也是C/C++的老程序员了嘛(微笑),那先问一个C++的问题(递给应聘者一张A4纸,上面有一段打印的代码,如下面所示)。你能不能分析一下这段代码的输出?
class A
{
private:
int n1;
int n2;
public:
A(): n2(0), n1(n2 + 2)
{
}
void Print()
{
std::cout << "n1: " << n1 << ", n2: " << n2 << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.Print();
return 0;
}
应聘者:(看了一下代码,略作思考)n1是2,而n2是0。
面试官:为什么?
应聘者:在构造函数的初始化列表中,n2先被初始化为0,n2的值就是0了。接下来再用n2+2初始化n1,所以n1的值就是2。
[注:应聘者这个问题的回答是错误的,详见后面的“面试官点评”]
面试官:C++是按照在初始化列表中的顺序初始化成员变量的吗?
应聘者:(一脸困惑)不是这样吗?我不太清楚。
面试官心理:
对成员变量的初始化顺序完全没有概念就号称自己“精通”C++,也太言过其实了。算了,C++就不接着问了,看看你的编程能力。
面试官:没关系,我们换一道题目。能不能介绍一下C语言的库函数中atoi的作用?
应聘者:atoi用来把一个字符串转换成一个整数。比如,输入字符串"123",它的输出是数字123。
面试官:对的。现在就请你写一个函数StrToInt,实现把字符串转换成整数这个功能。当然,不能使用atoi或者其他类似的库函数。你看有没有问题?
应聘者:(嘴角出现一丝自信的笑容)没有问题。
应聘者马上开始在白纸上写出了如下代码:
int StrToInt(char* string)
{
int number = 0;
while(*string != 0)
{
number = number * 10 + *string - '0';
++string;
}
return number;
}
应聘者:(放下笔)我已经写好了。
面试官心理:
我出的题目有这么简单吗?你也太小看我了。
面试官:这么快?(稍微看了看代码)你觉得这代码有没有问题?仔细检查一下看看。
应聘者:(从头开始读代码)哦,不好意思,忘了检查字符串是空指针的情况。
应聘者拿起笔,在原来的代码上添加两行新的代码。修改之后的代码如下:
int StrToInt(char* string)
{
if(string == nullptr)
return 0;
int number = 0;
while(*string != 0)
{
number = number * 10 + *string - '0';
++string;
}
return number;
}
面试官:改好了?(看了一下新的代码)当字符串为空的时候,你的返回是0。如果输入的字符串是"0",那么返回是什么?
应聘者:也是0。
面试官:两种情况都得到返回值0,那么当这个函数的调用者得到返回值0的时候,他怎么知道是哪种情况?
应聘者:(脸上表情有些困惑)不知道。
面试官:你知道atoi是怎么区分的吗?
应聘者:(努力回忆,有些慌张)不记得了。
面试官:atoi是通过一个全局变量来区分的。如果是非法输入,则返回0并把这个全局变量设为一个特殊标记。如果输入是"0",则返回0,不会设置全局变量。这样,当atoi的调用者得到返回值0的时候,可以通过检查全局变量得知输入究竟是非法输入还是字符串"0"。
应聘者:哦。(拿起笔准备写代码)我马上修改。
面试官:等一下,除了空字符串,还有没有其他类型的非法输入?
应聘者:(陷入思考,额头上出现汗珠)如
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
《剑指Offer:名企面试官精讲典型编程题》剖析了50个典型的程序员面试题,从基础知识、代码质量、解题思路、优化效率和综合能力五个方面系统整理了影响面试的5个要点。全书分为7章,主要包括面试的流程,讨论面试流程中每一环节需要注意的问题;面试需要的基础知识,从编程语言、数据结构及算法三方面总结了程序员面试的知识点;高质量的代码、解决面试题的思路、优化时间和空间效率。