维护现有的 C 系统
阅读、安全地修改并扩展别人多年前编写的代码库,同时避免引入一个可能要到很久以后才会显现的内存错误。
大多数在迪拜招聘 C 开发工程师的企业,并不是从一张白纸开始一个新项目。它们通常已经有一个系统、一个驱动程序,或一个多年前用 C 写成、至今仍在运行的性能关键模块,而且仍然需要有人能够安全地在其中开展工作。C 语言由 ISO 和 IEC 通过工作组 WG14 制定标准,其当前发布的标准是 C23,正式编号为 ISO/IEC 9899:2024,在需要判断某个关于“正确” C 行为的说法是否成立时,这份标准是最接近权威依据的参考。
选择 C 而不是更高层语言的另一个原因则更为刻意:一项新工作确实需要对内存和硬件的直接控制,而不希望承受更高层语言带来的额外开销。这类工作所占的比例已经比过去小了不少,因为 C++ 和 Rust 如今能在多出安全保障的情况下覆盖大部分相同的领域,因此在确定项目范围时,明确说明这个项目究竟需要的是 C 本身,还是更适合用这两者之一来完成,非常值得做。
C 开发工程师负责的工作
具体的实际情况,而不是一份泛泛的系统编程职位描述。
阅读、安全地修改并扩展别人多年前编写的代码库,同时避免引入一个可能要到很久以后才会显现的内存错误。
将一个经过测量、明确存在的瓶颈用 C 重写,并从更高层语言中调用它,而不是重写整个应用。
直接与硬件或操作系统接口通信的代码,C 语言在大多数软件底层这一层依然是通用语言。
将一个 C 代码库从一个操作系统或处理器架构迁移到另一个,处理标准本身未覆盖的各种差异。
使用现代工具审查现有的 C 代码库,在缓冲区溢出和释放后使用等错误引发真正的事故之前找到它们。
为一个已经超出纯 C 所能安全维护范围的系统,有计划地迁移到 C++ 或 Rust,并作为独立的限定项目来规划。
先弄清楚项目实际属于以上哪一种,无论是在确定范围阶段还是在面试本身,都能省下不少时间。
值得关注的技能
围绕内存和未定义行为的纪律,因为这正是 C 与现代语言差异最大的地方。
| 技能或工具 | 良好水平的表现 | 为什么重要 |
|---|---|---|
| 手动内存管理 | 能准确说明自己代码中内存何时分配、何时释放,而不只是说“能运行” | C 语言中泄漏或重复释放的内存分配常常悄无声息,直到某一刻突然出问题 |
| 对未定义行为的了解 | 清楚 C 标准将哪些常见写法归为未定义行为,并避免依赖特定编译器的行为 | 在一个编译器上恰好能运行的代码,在另一个编译器上可能严重失败 |
| 调试与检测工具 | 在开发过程中就使用专门用于捕获内存错误的工具,而不只是崩溃之后才用调试器 | 许多 C 语言的 bug 在触发条件真正出现在生产环境之前都是不可见的 |
| 阅读陌生、缺乏文档的代码 | 能够熟练处理一个文档很少甚至没有文档的老旧 C 代码库 | 大多数 C 语言工作是维护已经存在的东西,而不是从零开始 |
| C 语言的构建系统 | 熟练掌握项目实际使用的构建工具,这一点在 C 语言世界里比在新生态中差异更大 | 一个无法构建项目的开发工程师无法安全地修改它 |
WG14 的 C 标准页面 是关于这门语言实际定义了什么的主要参考资料,一位遇到内存相关问题时会指向它、而不是凭习惯或口口相传的说法来回答的候选人,才是真正更强的人选。
与我们合作的方式
专职开发人员适合一个持续变化中的现有 C 系统,加入您的团队并持续处理维护和功能开发。限定项目适合一段界定清晰的工作,例如一个性能关键模块、一次平台移植,或一次内存安全审计,交付时附带文档。招聘支持适合正在搭建自己长期底层工程能力的企业。咨询服务适合在任何搭建工作开始之前,就一个老旧的 C 系统应该维护、用更安全的语言重写,还是直接退役做出决策。
评估候选人
直接针对内存纪律和处理陌生代码的从容程度的检验方式。
不要只满足于一句泛泛的“我们很谨慎”。询问这个 bug 具体是什么、如何发现的,以及做了什么让它不再复发。
请对方在不先运行代码的情况下,解释它做了什么,以及在哪些地方会谨慎对待改动。
一份具体的清单,例如有符号整数溢出或释放后使用,比一句含糊的“我们很小心”有力得多。
一个真实的回答会指出具体的检测工具或静态分析工具,而不只是说“充分测试”。
C 项目在构建方式上差异很大。请对方从零开始,讲一遍构建一个与您类似的项目的过程。
专门为遗留系统维护招聘的企业,应该把前两项检验放在优先位置。
认证
C 语言本身没有厂商认证,因此应以真实的内存纪律来判断候选人。
C 语言由一个 ISO 工作组维护,而不是单一厂商,因此不存在类似平台考试那样的官方认证体系。第三方培训课程确实存在,但它们更能说明的是应试准备,而不是生产环境中的判断力。
一个真实的内存 bug 故事、一份您能阅读的代码库,以及他们使用检测工具的习惯,比任何证书都更能说明他们将如何处理您的系统。
本角色属于我们 编程与软件开发 类别,是 迪拜招聘开发人员 的一部分。对于基于相同底层构建的面向对象系统,请查看我们的 C++ 开发工程师 页面;如需完整的嵌入式 Linux 或设备级搭建,我们的 嵌入式系统开发工程师 页面专门涵盖这一领域。对于新的、性能敏感的工作,一个内存安全的替代方案在我们的 Rust 开发工程师 页面上。
直接解答
主要有两个原因:现有系统已经用 C 写成,需要维护或扩展;或者一项新工作确实需要对内存和硬件的直接控制,而这是更高层语言无法提供的。
相关但不完全相同。在我们网站上,嵌入式工作指的是搭建完整的嵌入式 Linux 或设备级产品。C 开发工程师涵盖的是语言本身,包括从不涉及实体设备的性能关键模块和遗留系统维护。
这在很大程度上取决于它最初的文档和测试做得如何。维护遗留代码的 C 开发工程师默认应保持谨慎,因为 C 中的内存处理错误往往难以复现,而且可能后果严重。
除非有特定理由,例如已有的 C 代码库或非常受限的目标环境,否则通常不建议直接用纯 C。我们会在确定范围阶段如实说明,而不是出于习惯默认选择 C。
经常可以,因为这两种语言关系密切,尽管 C++ 增加了面向对象和其他 C 所没有的特性。如果您的项目特别是 C++,我们的 C++ 开发工程师页面对此有专门介绍。
资料来源
书面固定价格
已收到,我们正在为您撰写报价。
工作时间内您将在 45 分钟内收到。请查收确认邮件。