面试真题 | 华为[20241023]

@[toc]

一面技术面相关问题

1. 硬件改进的具体内容是什么?

  • 深入询问:你如何确定硬件改进的方向?改进后带来了哪些具体的性能提升或成本节约?

在嵌入式系统开发中,硬件改进是一个综合性的过程,它涉及对现有硬件架构、组件、连接方式以及物理布局等方面的优化或升级,旨在提升系统的性能、可靠性、能效比或降低成本。以下是对硬件改进具体内容的深入解析,并附带对面试官可能提出的进一步问题的详细回答。

硬件改进的具体内容

  1. 组件升级

    • 处理器升级:选择更高性能的CPU或MCU,以提高系统的数据处理能力和实时响应速度。
    • 存储扩展:增加存储容量,如RAM和Flash,以支持更复杂的应用程序和更大的数据集。
    • 外设增强:添加或升级传感器、通信接口(如Wi-Fi、蓝牙、以太网)、显示器等外设,以满足特定的应用需求。
  2. 架构设计优化

    • 总线结构优化:改进系统总线架构,减少数据传输延迟,提高系统整体性能。
    • 电源管理优化:采用更高效的电源管理方案,如动态电压调节(DVS)、低功耗模式等,以降低系统功耗。
    • 热设计优化:改进散热设计,确保系统在长时间高负荷运行下的稳定性和可靠性。
  3. 物理布局与连接改进

    • PCB布局优化:优化PCB布局和布线,减少信号干扰和损耗,提高系统稳定性和可靠性。
    • 连接器与线缆改进:选择更高质量的连接器和线缆,提高数据传输的可靠性和稳定性。
    • 封装与集成度提升:通过采用更先进的封装技术和提高集成度,减小系统体积和重量,降低成本。
  4. 安全与可靠性提升

    • 硬件加密:添加硬件加密模块,提高数据传输和存储的安全性。
    • 冗余设计:采用冗余电源、冗余通信通道等冗余设计,提高系统的容错能力和可靠性。

深入询问及回答

面试官追问1:你如何确定硬件改进的方向?

回答: 确定硬件改进的方向通常涉及以下几个步骤:

  • 需求分析:首先,我们需要明确系统当前存在的问题和未来的需求。这包括性能瓶颈、功耗问题、可靠性需求等。
  • 市场调研:通过市场调研,了解当前市场上同类产品的硬件配置和性能表现,以及潜在的技术趋势。
  • 成本效益分析:评估不同改进方案的成本和预期效益,包括硬件成本、开发成本、测试成本以及可能带来的性能提升或成本节约。
  • 技术可行性评估:结合团队的技术能力和资源,评估不同改进方案的技术可行性和实施难度。

面试官追问2:改进后带来了哪些具体的性能提升或成本节约?

回答: 硬件改进后可能带来的具体性能提升或成本节约包括:

  • 性能提升:如处理器升级后,系统的数据处理能力和实时响应速度显著提高;存储扩展后,系统能够支持更复杂的应用程序和更大的数据集。
  • 能效比提升:通过优化电源管理方案,系统的功耗显著降低,能效比提高。
  • 成本节约:如通过提高集成度和优化PCB布局,减小了系统体积和重量,降低了制造成本;通过采用更高效的散热设计,减少了散热设备的投入和维护成本。
  • 可靠性提升:通过冗余设计和硬件加密等措施,提高了系统的容错能力和安全性,降低了因系统故障或数据泄露导致的潜在损失。

综上所述,硬件改进是一个综合性的过程,需要综合考虑系统需求、市场趋势、成本效益和技术可行性等因素。通过合理的改进方案和实施策略,可以显著提升系统的性能、可靠性和能效比,同时降低成本。

2. 在维护前任师兄的代码时,你遇到了哪些挑战?

  • 深入询问:你是如何理解并接手这些代码的?有没有发现潜在的bug或性能瓶颈,并进行了优化?

问题回答

在维护前任师兄的代码时,我遇到了多方面的挑战,这些挑战不仅涉及技术层面,还包括沟通和团队协作等方面。以下是我对这些挑战的详细阐述:

技术层面的挑战

  1. 代码可读性:前任师兄的代码可能采用了特定的编程风格或命名规范,这对我来说是一个挑战。为了理解代码,我花费了大量时间阅读代码注释、文档和代码本身,以熟悉其结构和逻辑。

  2. 代码结构:如果代码结构复杂且缺乏清晰的模块划分,我将难以快速定位和理解特定功能。在这种情况下,我会通过重构代码、添加注释和文档来提高代码的可读性和可维护性。

  3. 技术栈差异:如果前任师兄使用的技术栈与我的经验有所不同,我需要花时间学习新的技术。这包括编程语言、框架、库和工具等。

  4. 潜在问题:在接手代码后,我通过单元测试、代码审查和性能测试等手段,发现了潜在的bug和性能瓶颈。例如,某些算法可能不够高效,或者内存管理存在漏洞。针对这些问题,我进行了优化和修复,以提高代码的健壮性和性能。

沟通和团队协作的挑战

  1. 沟通障碍:如果前任师兄已经离职或无法联系,我可能无法直接询问代码的细节或设计思路。在这种情况下,我会通过查阅文档、代码注释和与团队成员沟通来获取信息。

  2. 团队协作:在维护代码的过程中,我需要与团队成员紧密合作,以确保代码的质量和进度。这包括与项目经理、测试人员和其他开发人员等保持沟通,共同解决问题。

深入理解并接手代码

为了理解并接手前任师兄的代码,我采取了以下措施:

  1. 阅读文档和注释:我首先阅读了项目的文档和代码注释,以了解项目的背景、需求和设计思路。

  2. 代码审查:我通过代码审查工具或手动审查代码,以了解代码的结构、逻辑和潜在问题。

  3. 单元测试:我编写了单元测试来验证代码的功能和性能,以确保代码的正确性和稳定性。

  4. 重构和优化:在理解代码的基础上,我对代码进行了重构和优化,以提高其可读性和性能。

面试官追问及回答

追问1

你能分享一个你发现并修复潜在bug或性能瓶颈的具体案例吗?

回答

当然可以。在接手前任师兄的代码时,我发现了一个内存泄漏的问题。这个问题导致系统在长时间运行后变得非常缓慢,甚至崩溃。通过调试和分析代码,我发现了一个未释放的内存块。在修复这个问题后,系统的性能和稳定性得到了显著提高。

追问2

在重构代码时,你是如何确保不会引入新的bug的?

回答

在重构代码时,我采取了以下措施来确保不会引入新的bug:

  1. 单元测试:我编写了详细的单元测试来验证代码的功能和性能。在重构过程中,我不断运行这些测试以确保代码的正确性。

  2. 代码审查:我邀请团队成员对重构后的代码进行审查,以发现潜在的问题和漏洞。

  3. 逐步重构:我采用了逐步重构的方法,每次只修改一小部分代码,并确保修改后的代码仍然能够正确运行。这样可以降低引入新bug的风险。

  4. 持续集成:我使用了持续集成工具来自动构建和测试代码。这可以及时发现并修复在重构过程中引入的问题。

追问3

在维护前任师兄的代码时,你是如何与团队成员保持沟通的?

回答

在维护前任师兄的代码时,我通过以下方式与团队成员保持沟通:

  1. 定期会议:我参加了项目组的定期会议,与项目经理、测试人员和其他开发人员等分享进度、讨论问题和解决方案。

  2. 即时通讯工具:我使用了即时通讯工具(如Slack、微信等)与团队成员保持实时沟通,以便及时解决问题和协调工作。

  3. 代码审查平台:我使用了代码审查平台(如GitHub Pull Requests、GitLab Merge Requests等)来提交和审查代码,以便团队成员能够了解我的工作进展并提供反馈。

  4. 文档和注释:我编写了详细的文档和注释来解释代码的结构、逻辑和潜在问题,以便团队成员能够更容易地理解和维护代码。

3. 在嵌入式系统中,内存泄漏通常有哪些原因?

  • 深入询问:你能否列举一些具体的场景或代码示例来说明内存泄漏的发生?

在嵌入式系统中,内存泄漏是一个严重的问题,它指的是程序中动态分配的内存没有被正确释放,导致该内存无法再次被使用,最终造成系统内存资源的浪费和耗尽。内存泄漏通常有以下几方面的原因:

一、内存泄漏的主要原因

  1. 资源管理不当

    • 由于嵌入式系统的资源有限,开发人员必须非常谨慎地管理内存分配和释放。如果没有正确释放已分配的内存,这些内存块将一直被占用,直到系统重新启动或重置。
  2. 内存指针的错误操作

    • 在嵌入式系统中,内存通常通过指针来访问和管理。如果指针操作不正确,可能会导致内存泄漏。例如,在动态分配内存后,如果忘记释放指针,内存将无法再次使用。
    • 指针操作的错误也可能导致访问无效的内存地址,进而引发系统异常或崩溃。
  3. 未初始化内存

    • 使用未初始化的内存可能导致不可预测的行为,包括内存泄漏。未初始化的内存可能包含无效的指针或数据,这些指针或数据在后续的内存操作中可能导致内存泄漏。
  4. 内存覆盖

    • 内存覆盖是指向已经释放的内存区域写入数据。这种行为可能导致内存管理混乱,从而引发内存泄漏。

二、内存泄漏的具体场景或代码示例

  1. 动态内存分配未释放
void example_function() {
    int *ptr = (int *)malloc(sizeof(int));
    *ptr = 42;
    // 忘记释放内存,导致内存泄漏
    // free(ptr);
}

在这个示例中,malloc函数动态分配了一块内存给指针ptr,但在函数结束时没有调用free函数来释放这块内存,导致内存泄漏。

  1. 指针重新赋值导致内存泄漏
void example_function() {
    int *ptr1 = (int *)malloc(sizeof(int));
    int *ptr2 = ptr1;
    // 忘记释放ptr1指向的内存,导致内存泄漏
    // 注意:此时释放ptr2也不会有问题,但关键是要确保有一个指针能正确指向并释放这块内存
    // free(ptr1); 或 free(ptr2);
}

在这个示例中,ptr1ptr2都指向了同一块动态分配的内存。如果后续代码中只释放了ptr2(或未释放任何指针),而忘记了ptr1也指向了这块内存,那么这块内存就会被泄漏。

  1. 内存池使用不当

在某些情况下,嵌入式系统可能会使用内存池来管理内存。如果内存池的使用不当,例如没有正确地从内存池中释放内存,或者内存池本身存在缺陷,都可能导致内存泄漏。

三、面试官追问及答案

追问1:在嵌入式系统中,如何检测和定位内存泄漏?

答案

  • 代码审查:通过代码审查来查找可能的内存泄漏点。这需要对代码有深入的理解,并熟悉常见的内存泄漏模式和错误。
  • 内存分析工具:使用内存分析工具(如Valgrind、AddressSanitizer等)来检测内存泄漏。这些工具可以在运行时监控内存的使用情况,并报告内存泄漏的位置和大小。
  • 日志记录:在代码中添加日志记录,记录内存分配和释放的操作。通过分析日志,可以定位内存泄漏的位置。

追问2:在嵌入式系统中,如何预防内存泄漏?

答案

  • 规范内存管理:确保每次动态分配内存后都有相应的释放操作,避免遗漏。
  • 使用智能指针或内存管理库:在支持C++的嵌入式系统中,可以使用智能指针(如std::shared_ptrstd::unique_ptr)来自动管理内存生命周期。对于不支持C++的系统,可以考虑使用专门的内存管理库来简化内存管理。
  • 避免使用全局变量和静态变量:全局变量和静态变量的生命周期与程序一致,它们占用的内存会在整个程序运行期间一直存在。因此,应尽量避免使用全局变量和静态变量来存储动态分配的内存。
  • 定期测试和验证:定期对系统进行测试和验证,以确保内存管理的正确性和稳定性。通过模拟长时间运行和大量内存分配的场景,可以发现潜在的内存泄漏问题。

综上所述,嵌入式系统中的内存泄漏问题是一个需要高度重视的问题。通过深入理解内存泄漏的原因和场景、使用有效的检测和定位工具、以及采取预防措施来减少内存泄漏的风险,可以提高嵌入式系统的稳定性和可靠性。

4. C++的内存管理机制相比C有哪些改进?

  • 深入询问:你能否解释一下智能指针(如std::unique_ptrstd::shared_ptr)的工作原理和适用场景?

问题回答

C++的内存管理机制相比C语言有了显著的改进,主要体现在以下几个方面:

  1. 自动内存管理

    • C语言需要程序员手动管理内存的分配和释放,这包括使用malloccallocreallocfree等函数。这种手动管理方式容易出错,如内存泄漏、野指针等问题。
    • C++引入了自动内存管理的概念,通过构造函数和析构函数来管理对象的生命周期。当对象超出作用域或被显式删除时,析构函数会被自动调用,从而释放对象占用的内存。这种方式减少了程序员的工作量和出错的可能性。
  2. 内存泄漏的减少

    • 在C语言中,如果程序员忘记释放已分配的内存,或者由于某些逻辑错误导致内存无法被正确释放,就会发生内存泄漏。
    • C++通过引入智能指针(如std::unique_ptrstd::shared_ptr)等机制,可以更有效地管理动态内存,减少内存泄漏的风险。智能指针能够自动管理其所指向对象的生命周期,当智能指针不再需要指向某个对象时,它会自动释放该对象占用的内存。
  3. 内存管理的灵活性

    • C语言的内存管理相对简单,但缺乏灵活性。程序员需要手动跟踪每一块内存的使用情况,这在实际开发中往往非常繁琐。
    • C++提供了更丰富的内存管理选项,包括但不限于自动内存管理、手动内存管理以及智能指针等。这些选项使得程序员可以根据具体的应用场景选择最合适的内存管理方式。
  4. 异常处理

    • C语言不支持异常处理机制,当内存分配失败时,程序员通常需要通过返回值来判断是否成功,并手动处理错误情况。
    • C++支持异常处理机制,当内存分配失败时,可以抛出异常并由相应的异常处理代码进行处理。这种方式使得代码更加简洁、易读,并提高了程序的健壮性。

深入询问及回答

面试官追问:你能否解释一下智能指针(如std::unique_ptrstd::shared_ptr)的工作原理和适用场景?

回答

智能指针是C++标准库提供的一种用于自动管理动态内存分配的类模板。它们通过封装原始指针并提供额外的功能来简化内存管理过程。以下是std::unique_ptrstd::shared_ptr的工作原理和适用场景:

  1. std::unique_ptr

    • 工作原理std::unique_ptr是一种独占所有权的智能指针,它确保同一时间内只有一个std::unique_ptr实例可以指向某个对象。当std::unique_ptr被销毁或重新赋值时,它所管理的对象也会被自动销毁(调用析构函数)。
    • 适用场景std::unique_ptr适用于那些需要确保唯一所有权的场景,例如动态分配的单例对象或临时对象。由于它不允许复制操作,因此可以避免多个指针指向同一对象而导致的潜在冲突和内存泄漏问题。
  2. std::shared_ptr

    • 工作原理std::shared_ptr是一种共享所有权的智能指针,它允许多个std::shared_ptr实例共同指向同一个对象。每个std::shared_ptr实例都有一个内部的引用计数器来跟踪指向该对象的std::shared_ptr数量。当最后一个std::shared_ptr被销毁或重新赋值时,对象才会被自动销毁。
    • 适用场景std::shared_ptr适用于那些需要共享所有权的场景,例如对象需要在多个模块或类之间共享时。通过使用std::shared_ptr,可以确保对象在不再需要时会被自动销毁,从而避免内存泄漏问题。同时,由于std::shared_ptr支持复制和赋值操作,因此可以方便地传递和共享对象。

综上所述,智能指针通过提供自动内存管理和所有权管理机制来简化C++中的动态内存管理过程。在实际开发中,应根据具体的应用场景选择合适的智能指针类型以确保程序的正确性和健壮性。

5. 给你一个字符串,如何高效地提取出合法的MAC地址?

  • 深入询问:你能否设计一个算法,在O(n)时间复杂度内完成MAC地址的提取?如果字符串中包含多个MAC地址格式,你如何处理?

回答

问题:给你一个字符串,如何高效地提取出合法的MAC地址?

在提取合法的MAC地址时,我们需要了解MAC地址的标准格式。MAC地址通常由6组两位十六进制数组成,各组之间用冒号(:)、连字符(-)或点(.)分隔(虽然点分隔通常不用于MAC地址,但这里为了全面考虑也提及)。一个合法的MAC地址示例为00:1A:2B:3C:4D:5E00-1A-2B-3C-4D-5E

提取步骤

  1. 正则表达式匹配:首先,我们可以使用正则表达式来匹配字符串中的MAC地址。正则表达式可以灵活地定义MAC地址的格式,包括不同的分隔符和十六进制数的范围。

    对于冒号和连字符分隔的MAC地址,正则表达式可以定义为:

    ([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})
    

    这个正则表达式匹配了6组两位十六进制数,各组之间用冒号或连字符分隔。

  2. 遍历字符串:使用正则表达式在字符串中进行匹配,找到所有符合条件的子串。这可以通过编程语言中的正则表达式库来实现,如Python的re模块。

  3. 验证和提取:对于每个匹配到的子串,我们可以进一步验证其是否符合MAC地址的完整格式,并提取出来。

代码示例(Python)

import re

def extract_mac_addresses(input_string):
    # 定义正则表达式模式
    mac_pattern = re.compile(r'([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})')
    
    # 查找所有匹配的MAC地址
    matches = mac_pattern.findall(input_string)
    
    # 提取完整的MAC地址
    mac_addresses = [''.join(match) for match in matches]
    # 由于findall返回的是元组列表,每个元组包含一个MAC地址的各部分,
    # 所以我们需要将元组中的部分拼接成完整的MAC地址。
    # 注意:这里假设输入字符串中的MAC地址格式正确,没有进一步验证。
    # 如果需要更严格的验证,可以在拼接后对MAC地址进行额外检查。
    
    # 由于findall可能返回重复的MAC地址(如果输入字符串中有多个相同的MAC地址),
    # 可以使用集合来去重,但这里为了保留原始顺序和可能的重复项,我们不做去重。
    
    return mac_addresses

# 示例使用
input_string = "Here are some MAC addresses: 00:1A:2B:3C:4D:5E, 00-1A-2B-3C-4D-5F, and maybe 001A2B3C4D5G (invalid)."
mac_addresses = extract_mac_addresses(input_string)
print(mac_addresses)  # 输出: ['00:1A:2B:3C:4D:5E', '00-1A-2B-3C-4D-5F']

深入询问

追问1:你能否设计一个算法,在O(n)时间复杂度内完成MAC地址的提取?

答案: 是的,上述算法可以在O(n)时间复杂度内完成MAC地址的提取,其中n是输入字符串的长度。这是因为正则表达式匹配过程会遍历整个输入字符串一次(或多次,但每次遍历都是线性的),并且对于每个匹配到的子串,拼接操作也是线性的。因此,总的时间复杂度是线性的。

然而,需要注意的是,正则表达式的编译时间(即构建正则表达式对象的时间)通常不计入算法的时间复杂度分析中,因为它是一个预处理步骤,与输入字符串的长度无关。此外,如果输入字符串中包含大量的MAC地址或非常长的MAC地址(虽然这在实际应用中很少见),则可能需要考虑正则表达式匹配过程中的回溯和状态空间开销。但在一般情况下,上述算法是高效的。

追问2:如果字符串中包含多个MAC地址格式,你如何处理?

答案: 如果字符串中包含多个MAC地址格式(例如,既有冒号分隔的,又有连字符分隔的),上述算法已经能够处理这种情况。正则表达式模式已经定义了两种分隔符(冒号和连字符),因此它可以匹配这两种格式的MAC地址。在提取过程中,算法会遍历整个输入字符串,并找到所有符合条件的子串。然后,这些子串会被拼接成完整的MAC地址,并返回给调用者。

如果未来需要支持更多的MAC地址格式(例如,点分隔的或其他非标准格式),可以相应地修改正则表达式模式来包含这些格式。但是,请注意,点分隔通常不用于MAC地址表示,因此在修改正则表达式时需要谨慎考虑是否要包含这种格式。

综上所述,上述算法可以高效地提取出输入字符串中所有符合条件的MAC地址,并且具有O(n)的时间复杂度。同时,它也能够处理包含多种MAC地址格式的输入字符串。

二面技术面相关问题

6. C++相比C的优势主要体现在哪些方面?

  • 深入询问:你能否举例说明C++中的面向对象编程、模板元编程等特性在嵌入式开发中的应用? C++相比C的优势主要体现在以下几个方面:

C++相比C的优势

  1. 面向对象编程

    • C++是一种面向对象的编程语言,支持封装、继承和多态等特性。这些特性使得C++能够更好地组织代码,提高代码的可读性和可维护性。
    • 在嵌入式开发中,面向对象编程有助于将硬件抽象为对象,通过类和对象来管理硬件资源和操作,从而简化硬件编程的复杂性。
  2. 强大的标准库

    • C++拥有比C语言更为丰富和强大的标准库,提供了许多容器、算法和迭代器等工具,可以大大提高开发效率。
    • 嵌入式开发中,C++标准库中的STL(Standard Template Library)等组件可以方便地用于数据处理和算法实现,减少重复劳动。
  3. 模板元编程

    • C++支持模板和泛型编程,可以实现代码的复用和泛化。模板元编程允许在编译时进行计算和代码生成,提高了代码的灵活性和效率。
    • 在嵌入式开发中,模板元编程可以用于实现硬件资源的抽象和配置,以及优化代码结构和性能。
  4. 异常处理机制

    • C++支持异常处理机制,提供了一种更加优雅的错误处理方式。虽然在嵌入式开发中,异常处理通常会被关闭以减少代码体积,但其存在为开发者提供了一种处理错误的备选方案。
  5. 类型安全

    • C++在类型检查方面比C更为严格,有助于在编译阶段发现潜在的类型错误,提高代码的健壮性。

深入询问及回答

面试官追问:你能否举例说明C++中的面向对象编程、模板元编程等特性在嵌入式开发中的应用?

回答

  1. 面向对象编程在嵌入式开发中的应用

    • 在嵌入式开发中,C++的面向对象编程特性可以用于将硬件资源抽象为对象。例如,可以使用类和对象来表示GPIO(通用输入输出)端口、UART(通用异步收发传输器)等硬件资源。
    • 通过面向对象的方式,可以方便地封装硬件资源的初始化、配置和操作等函数,使得硬件编程更加直观和易于维护。
    • 此外,面向对象编程还支持继承和多态等特性,可以用于实现不同硬件平台之间的代码复用和扩展。
  2. 模板元编程在嵌入式开发中的应用

    • 在嵌入式开发中,C++的模板元编程特性可以用于实现代码的泛型化和优化。例如,可以使用模板来实现一个通用的环形缓冲区,该缓冲区可以存储不同类型的数据,并自动根据数据类型和缓冲区大小进行计算和优化。
    • 模板元编程还可以用于实现硬件资源的抽象和配置。例如,可以使用模板来定义一个通用的硬件寄存器访问类,该类可以根据不同的寄存器地址和类型进行实例化,从而简化硬件寄存器的访问和操作。

综上所述,C++相比C在面向对象编程、标准库、模板元编程等方面具有显著优势。这些优势使得C++在嵌入式开发中能够更好地应对复杂性和提高开发效率。同时,通过合理利用C++的特性,可以实现更加高效、可靠和可维护的嵌入式系统。

7. 你使用过C++11/14/17/20中的哪些新特性?

  • 深入询问:你能否详细解释一下你使用过的新特性,并举例说明它们在实际开发中的好处?

问题回答

在嵌入式开发中,C++11/14/17/20引入了许多新特性,这些特性极大地提升了代码的安全性、可读性和性能。以下是我使用过的一些关键新特性:

  1. C++11特性

    • auto关键字:用于自动类型推导,减少了类型声明的冗余,特别是在处理复杂类型时。
    • nullptr:替代了NULL,提供了更好的类型安全性,避免了与整数0的混淆。
    • 范围for循环:简化了数组和容器的遍历,使代码更加简洁。
    • lambda表达式:允许在代码中定义匿名函数对象,便于实现回调函数和算法操作。
    • 智能指针(如std::unique_ptrstd::shared_ptr):自动管理内存,减少了内存泄漏的风险。
  2. C++14特性

    • 二进制字面量通用字面量:提供了更直观的数值表示方式,便于处理二进制数据和自定义数值类型。
    • lambda捕获初始化:允许在捕获列表中使用初始化表达式,增加了lambda表达式的灵活性。
  3. C++17特性

    • 结构化绑定:允许从元组、结构体或数组等复合类型中直接解包多个值,简化了代码。
    • std::optional:表示一个可能包含值的对象,或者不包含值(为空)。它提供了一种更安全的处理可选值的方式。
    • std::variantstd::visit:提供了类型安全的联合体(union)和访问者模式实现,便于处理多种类型的数据。
  4. C++20特性

    • 概念(Concepts):提供了对模板参数的约束,增强了模板的可用性和安全性。
    • 协程:允许编写异步代码,但看起来像是同步的,简化了异步编程的复杂性。
    • std::span:提供了一个安全的、轻量级的视图,用于访问连续的内存区域,如数组或容器的部分。

深入询问及回答

面试官追问:你能否详细解释一下你使用过的新特性,并举例说明它们在实际开发中的好处?

回答

  1. auto关键字

    • 解释auto关键字用于自动类型推导,编译器会根据初始化表达式自动推断变量的类型。

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

ARM/Linux嵌入式真题 文章被收录于专栏

让实战与真题助你offer满天飞!!! 每周更新!!! 励志做最全ARM/Linux嵌入式面试必考必会的题库。 励志讲清每一个知识点,找到每个问题最好的答案。 让你学懂,掌握,融会贯通。 因为技术知识工作中也会用到,所以踏实学习哦!!!

全部评论

相关推荐

昨天 22:07
吉林大学
华为 结构与材料工程师终端 30+
点赞 评论 收藏
分享
想着0919之后应该下手会注意分寸的,0925因为信息忘了同意没做,想着0927做了国庆后开面,好家伙,和图刚上了,一题没做出来,连第二题输出-1骗分都骗的比别人少,道心破碎
厕所风好大:我也是。150分及格线,我想着先做200分的第二题。结果做了一个多小时道心破碎,回过头去做第一题,然后最后慌了没做出来,太难了,这是说的leetcode中等题?
投递华为等公司10个岗位 >
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务