# 字节跳动客户端开发0基础 一面凉经

作者：loveNicole\
链接：[https://www.nowcoder.com/discuss/492579](https://www.nowcoder.com/discuss/492579)\
来源：牛客网\
\
写在之前：本人是[算法](https://app.gitbook.com/jump/super-jump/word?word=%E7%AE%97%E6%B3%95)转开发，看[客户端](https://app.gitbook.com/jump/super-jump/word?word=%E5%AE%A2%E6%88%B7%E7%AB%AF)无基础无经验就投递了字节[客户端](https://app.gitbook.com/jump/super-jump/word?word=%E5%AE%A2%E6%88%B7%E7%AB%AF)开发，这次面试面试官全程黑脸，体验极差，我好菜啊\
&#x20;问的问题及本人回答以及面试官评价如下： 1、设计一个聊天[客户端](https://app.gitbook.com/jump/super-jump/word?word=%E5%AE%A2%E6%88%B7%E7%AB%AF) 我：我没有[客户端](https://app.gitbook.com/jump/super-jump/word?word=%E5%AE%A2%E6%88%B7%E7%AB%AF)开发经验 面试官：（摇头） 2、进程拥有的资源 答：

1. &#x20;虚拟地址空间
2. &#x20;一个全局唯一的进程ID (PID)
3. &#x20;一个可执行映像(image)，也就是该进程的程序文件在内存中的表示
4. &#x20;一个或多个线程
5. &#x20;一个位于内核空间中的名为EPROCESS(executive process block，进程执行块)的数据结构，用以记录该进程的关键信息，包括进程的创建时间、映像文件名称等。
6. &#x20;一个位于内核空间中的对象句柄表，用以记录和索引该进程所创建/打开的内核对象。操作系统根据该表格将用户模式下的句柄翻译为指向内核对象的指针。
7. &#x20;一个位于描述内存目录表起始位置的基地址，简称页目录基地址(DirBase)，当CPU切换到该进程/任务时，会将该地址加载到CR3寄存器，这样当前进程的虚拟地址才会被翻译为正确的物理地址。
8. &#x20;一个位于用户空间中的进程环境块(Process Environment Block， PEB)。
9. &#x20;一个访问权限令牌(access token)，用于表示该进程的用户、安全组，以及优先级别。

\
&#x20;面试官：（摇头） 3、操作系统如何实现系统调用

&#x20;答：在硬件设计上，通过区分内核态和用户态来把内核程序和用户程序隔离开，CS寄存器最低的两位为0即是内核态，为3是用户态

&#x20;但是系统调用的代码是处在内核态的，所以就需要提供一种方法来能够让用户程序进入内核态来实现系统调用

&#x20;在X86里，INT指令就是硬件用来提供由用户态进入内核态的方法，所以系统调用的实现就可以变为：

* &#x20;由用户程序发起一个INT指令，指明要调用的服务
* &#x20;在操作系统里写出相应的中断处理
* &#x20;由操作系统根据用户指明要调用的服务取执行相应的代码

&#x20;面试官：（不对） 答：我不清楚了 4、C++异常机制 C++ 通过 throw 语句和 try...catch 语句实现对异常的处理。throw 语句的语法如下：

```cpp
throw  表达式;
```

\
&#x20;该语句拋出一个异常。异常是一个表达式，其值的类型可以是基本类型，也可以是类。\
\
&#x20;try...catch 语句的语法如下：

```cpp
try {
    语句组
}
catch(异常类型) {
    异常处理代码
}
...
catch(异常类型) {
    异常处理代码
}
```

\
\
catch 可以有多个，但至少要有一个。\
\
&#x20;把 try 和其后{} 中的内容称作“try块”，把 catch 和其后{} 中的内容称作“catch块”。\
\
&#x20;try...catch 语句的执行过程是：

*
* &#x20;执行 try 块中的语句，如果执行的过程中没有异常拋出，那么执行完后就执行最后一个 catch 块后面的语句，所有 catch 块中的语句都不会被执行；
* &#x20;如果 try 块执行的过程中拋出了异常，那么拋出异常后立即跳转到第一个“异常类型”和拋出的异常类型匹配的 catch 块中执行（称作异常被该 catch 块“捕获”），执行完后再跳转到最后一个 catch 块后面继续执行。

&#x20;面试官：不对，这个大家都懂，底层机制\
&#x20;5、多态机制 答： 多态分为静态多态和动态多态

&#x20;静态多态是在编译期间完成，根据函数参数实参判断需要调用的函数。以此形成了函数重载技术和泛型编程。 动态多态则是利用虚函数实现了运行时的多态，也就是说在系统编译的时候并不知道程序将要调用哪一个函数，只有在运行到这里的时候才能确定接下来会跳转到哪一个函数的栈帧。\
&#x20;面试官：不对，底层实现 我：虚函数、虚函数表、虚指针\~巴拉巴拉 面试官：摇头+叹气 我： 函数重载、重写\~巴拉巴拉 面试官：沉默 6、代码： 宏定义返回较大值 函数指针做形参，返回int 一条直线线段覆盖\
&#x20;面试还没结束，短信说已挂，我好菜啊\
&#x20;发帖给接下来面的同学一点准备，避免遇到手忙脚乱，我被面试劝退，祝大家顺利\~
