ARM/Linux嵌入式面经(六):华为

面试一共四面,面试岗位为嵌入式工程师。华为的面试官本次体验还是蛮好的,技术强,也比较温柔。下面开始进入正题吧~~~

【一面】资格面

主要是问了有以下几点:

  • 简历

好奇我的专业,然后问我学过哪些学科。

  • 项目

当时抓我的项目,一个无线传感器网络的项目。没有问技术,主要问了:

+ 做了多久
+ 在项目中处于什么角色,负责哪部分的工作。
+ 遇到了什么困难?
  • 规划

问了职业规划

  • 家庭

家庭成员,哪里人,打算在哪里定居。

  • 你在网上看到过华为od的负面消息吗,你什么想法?

不怎么了解,平时不怎么八卦,规避了这个问题。

其实这里更好的时候发表一些客观正向的评价,不表现的我谄媚,但是我也不直言。

关于面试中很主观的问题,后面我会写两篇专门讲简历项目和HR面加入本专栏。再找几个案列,梳理成模版,让你一次性搞定。这里先行跳过。

【二面】技术面

# 自我介绍
# 介绍项目
# 全都是自己从零开始构建的吗, 软件硬件
# 软件算法, 视觉有用到分割吗, 介绍一下
# 项目中遇到什么困难, 队友他们怎么分工
# 遇到了新的东西时怎么去学习
# 学的什么专业课, 有学过操作系统,数据结构与算法,计组原理这种么
# 系统里用到了什么数据结构

这些都是有好用的模版的,等我统一给你整一个~~~

裸机中断会同时发生怎么办

知识

裸机中断是指在没有操作系统支持的情况下,直接由硬件产生的中断。当两个或更多的中断同时发生时,裸机系统需要有一种机制来处理这种情况,以确保系统的稳定性和数据的一致性

处理裸机中断同时发生的情况,通常涉及中断优先级的管理和中断服务程序的编写。以下是一些常见的处理方法:

  • 中断优先级管理:裸机系统通常会为每个中断分配一个优先级。当中断同时发生时,系统会首先响应优先级最高的中断。这通常通过硬件中断控制器实现,该控制器能够检测并排序多个同时发生的中断。
  • 中断嵌套:在某些情况下,一个中断服务程序可能在处理过程中被另一个更高优先级的中断打断。这称为中断嵌套。系统需要能够保存当前中断的上下文,以便在处理完高优先级中断后能够恢复并继续处理低优先级中断。
  • 中断屏蔽:为了避免中断之间的冲突,系统可以使用中断屏蔽技术来暂时禁用某些中断。这通常是在处理一个关键任务时使用的,以确保该任务不会被其他中断打断。
  • 中断服务程序的设计:编写中断服务程序时,需要特别注意其执行时间和对系统资源的使用。长时间运行或消耗大量资源的中断服务程序可能会导致系统响应变慢或出现其他问题。
  • 软件同步机制:在某些情况下,可能需要使用软件同步机制(如信号量、互斥锁等)来确保在中断处理过程中数据的一致性和完整性。

需要注意的是,裸机中断处理通常与具体的硬件平台和处理器架构密切相关。因此,在设计裸机中断处理机制时,需要深入了解目标硬件的中断特性和处理器架构。

最后,对于复杂的裸机系统,可能需要考虑使用更高级的中断管理策略,如中断向量表、中断服务例程表等,以更好地管理和处理多个同时发生的中断。

回答

当面试官问到裸机中断可能同时发生时,你可以按照以下步骤来回答:

  • 首先,你可以简要解释一下裸机中断的基本概念。裸机中断是指在没有操作系统支持的情况下,硬件直接对CPU发出中断请求,CPU在接收到中断请求后会暂停当前正在执行的程序,转而处理中断服务程序。

  • 接下来,针对中断可能同时发生的情况,你可以强调中断优先级的概念。在系统中,不同的中断源通常会被赋予不同的优先级,以便在多个中断同时发生时,CPU能够按照优先级顺序来处理它们。你可以解释,通过设置中断优先级,可以确保关键的中断请求得到优先处理,避免系统崩溃或数据丢失等问题。

  • 然后,你可以提及中断嵌套的概念。在某些情况下,即使设置了中断优先级,也可能出现高优先级中断在处理过程中被更低优先级中断打断的情况,这就是中断嵌套。你可以解释,中断嵌套机制允许CPU在处理一个中断的同时,响应另一个更高优先级的中断请求,提高了系统的响应速度和灵活性。

  • 此外,你还可以提到中断屏蔽的概念。在某些情况下,为了避免中断的干扰,可以使用中断屏蔽技术来暂时屏蔽某些中断源。这可以在关键代码段执行时确保不受中断的干扰,提高系统的稳定性和可靠性。

  • 最后,你可以强调在实际应用中,需要根据系统的具体需求和硬件特性来合理设计和配置中断处理机制。这包括选择适当的中断优先级、使用中断嵌套和中断屏蔽等技术来确保系统的正常运行和高效响应。

  • 总之,在回答面试官关于裸机中断可能同时发生的问题时,你可以从中断优先级、中断嵌套、中断屏蔽等方面来阐述你的理解和解决方案。同时,结合实际应用中的需求和硬件特性进行具体分析,展示你的专业素养和实践能力。

中断处理不完怎么办

当面试官询问关于中断处理不完的情况时,他们可能想了解你对系统稳定性、性能优化以及异常处理的理解。以下是一个建议的回答框架:

当面临中断处理不完的情况时,我会首先分析原因,并尝试从以下几个方面进行解决:

  • 优化中断处理流程:我会仔细审查中断处理代码,查找是否存在可以优化的地方,比如减少不必要的操作、使用更高效的数据结构或算法。通过优化代码,可以提高中断处理的效率,减少处理时间。

  • 提高系统性能:如果中断处理不完是因为系统性能不足,我会考虑提升硬件性能,比如使用更高主频的CPU、增加内存等。同时,我也会检查系统配置,确保系统资源得到合理分配,避免资源浪费。

  • 优先级管理:对于不同优先级的中断,我会实施优先级管理策略。高优先级的中断应该得到优先处理,以确保关键任务能够及时响应。对于低优先级的中断,可以考虑采用延迟处理或合并处理的方式,以减轻系统负担。

  • 中断合并与去抖:在某些情况下,可以通过中断合并和去抖技术来减少中断的数量。合并多个相似的中断可以减少处理次数,而去抖技术则可以消除由于噪声或误触导致的频繁中断。

  • 使用中断线程化:如果硬件和操作系统支持,我可以考虑使用中断线程化技术。通过为中断分配专门的线程来处理,可以充分利用多核处理器的优势,提高中断处理的并行度。

  • 监控与日志分析:我会建立有效的监控机制,实时观察中断处理情况。同时,通过日志分析,可以定位到中断处理中的瓶颈和问题,从而进行有针对性的优化。

有时候可能答案是错误的,但是面试官在乎的是你结构性的思考力。逻辑、思路与知识作伴。

讲讲MMU了解吗?

当面试官问你是否了解MMU(Memory Management Unit,内存管理单元)时,你可以按照以下结构来回答:

简要介绍MMU:

MMU是计算机系统中的硬件单元,负责处理内存访问请求包括虚拟地址到物理地址的转换、内存保护(防止一个进程访问另一个进程的内存)、内存分页或分段等功能。

MMU的作用:

解释MMU如何帮助操作系统实现虚拟内存管理,使每个进程拥有独立的地址空间。

讲述MMU如何通过地址转换机制,使得有限的物理内存能够被多个进程有效利用。

提到MMU对于提高系统安全性和稳定性的重要性,如防止非法内存访问。 MMU与操作系统、CPU的关系:

解释MMU是如何与操作系统和CPU协同工作的。操作系统负责内存管理的策略和调度,而MMU则负责执行这些策略,将虚拟地址转换为物理地址。 提到MMU是现代CPU架构中的一部分,对于实现高级内存管理功能至关重要。

你对MMU的深入了解:

如果你对MMU有深入的了解,可以谈论一些具体的实现细节,如页表结构、TLB(Translation Lookaside Buffer,转换后备缓冲器)的作用、内存保护机制等。

如果你在项目或学习中涉及到过MMU的使用或配置,可以分享相关经验和见解。

你对MMU的学习态度:

如果面试官的问题超出了你的现有知识范围,你可以表达你对学习新知识的积极态度,并承诺在需要时会深入研究相关内容。

记住,如果不知道,可以稍作思考,大胆承认自己暂时不了解,表示自己下去一定好好补习一下。记住不要让空气突然的安静~~~

下面是一个示例回答:

"我对MMU有一定的了解。MMU是计算机系统中的关键硬件组件,它负责处理内存访问请求,特别是虚拟地址到物理地址的转换。通过MMU,操作系统能够实现虚拟内存管理,为每个进程提供独立的地址空间,从而提高内存的利用率和系统的安全性。

MMU与操作系统和CPU紧密协作,操作系统负责内存管理的策略和调度,而MMU则负责执行这些策略。在现代CPU架构中,MMU扮演着至关重要的角色,它使得高级内存管理功能得以实现。

回答至此,如果你很了解MMU,继续讲一个细节点。

如果不熟,那么下面可以作为你的结尾:

我对MMU的具体实现细节还需要进一步学习,但我非常愿意投入时间和精力去深入了解它。我相信通过不断学习和实践,我能够掌握MMU的相关知识,并将其应用到实际工作中。"

这样的回答既展示了你对MMU的基本了解,又表达了你愿意学习和成长的积极态度。

有没有做过linux驱动开发?

这个问题我觉得只有两种回答:

  • 一:如果你确实有Linux驱动开发的经验

你可以这样说:"是的,我有过Linux驱动开发的经验。在之前的项目中,我负责开发了XXX设备的驱动程序,并成功将其集成到了Linux内核中。我熟悉Linux内核的架构和工作原理,能够熟练使用内核提供的API进行驱动开发。同时,我也具备调试和优化驱动性能的能力,确保驱动的稳定性和高效性。"

  • 二:如果你没有Linux驱动开发的经验,但有相关的技能或兴趣

你可以这样回答:"虽然我没有直接做过Linux驱动开发,但我对Linux系统有一定的了解,熟悉C语言和操作系统原理。我对驱动开发非常感兴趣,并且愿意投入时间和精力去学习相关知识。我相信,凭借我的学习能力和对技术的热情,我能够迅速掌握Linux驱动开发的技能。"

  • 如果你是第一个,那你就正常表达回忆之前的经历就好。(建议做嵌入式可以找个小项目练练手)
  • 如果你是第二个,就表达自己虽然没有做过,但是会什么相关的知识,表达你做驱动开发也有先天的优势。同时也把面试官引向了你擅长的空间,岂不美哉。

手撕算法两道

两数之和

解题思路: 题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

int* twoSum(int* nums, int numsSize, int target) {
    int i,j;
    int *result=NULL;
    for(i=0;i<numsSize-1;i++)
    {
        for(j=i+1;j<numsSize;j++)
        {
            if(nums[i]+nums[j]==target)
            {
                 result=(int*)malloc(sizeof(int)*2);
                 result[0]=i;
                 result[1]=j;
                 return result;
            }
        }
    }
    return result;
}

两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    struct ListNode *head = NULL, *tail = NULL;
    int carry = 0;
    while (l1 || l2) {
        int n1 = l1 ? l1->val : 0;
        int n2 = l2 ? l2->val : 0;
        int sum = n1 + n2 + carry;
        if (!head) {
            head = tail = malloc(sizeof(struct ListNode));
            tail->val = sum % 10;
            tail->next = NULL;
        } else {
            tail->next = malloc(sizeof(struct ListNode));
            tail->next->val = sum % 10;
            tail = tail->next;
            tail->next = NULL;
        }
        carry = sum / 10;
        if (l1) {
            l1 = l1->next;
        }
        if (l2) {
            l2 = l2->next;
        }
    }
    if (carry > 0) {
        tail->next = malloc(sizeof(struct ListNode));
        tail->next->val = carry;
        tail->next->next = NULL;
    }
    return head;
}

【三面】 交叉面

# 专业课有哪些
# 竞赛
# 实习的企业没留下转正吗, 毕业后实习的?
# 有没有总结过技术栈, 优势有哪些, 哪块技术更深
# mcu用过哪些型号
# mcu用过的外设
# 项目xx展开介绍一下
# xx用到哪些第三方软件
# 多大队伍
# 有没有用到OpenCV
# 为什么要用神经网络, 有什么好处呢
# 训练在哪做的
# 实习项目做的也都是mcu的开发吗
# 感觉对Linux开发感觉怎么样

裸跑还是有RTOS, 你觉得有啥区别

当面试官询问裸跑(裸机运行)与RTOS(实时操作系统)之间的区别时,可以从以下几个方面进行回答:

资源占用与性能:

  • 裸跑:裸机运行意味着应用程序直接运行在硬件之上,没有操作系统的介入。这种方式资源占用非常低,因为无需为操作系统分配内存或处理时间。因此,它通常能够提供更好的实时性能和更高的效率。
  • RTOS:实时操作系统为应用程序提供了一套丰富的功能和服务,如任务调度、内存管理、中断处理等。这些功能虽然方便,但也占用了一定的系统资源。RTOS的性能通常低于裸机运行,但其在复杂性和可维护性方面提供了显著的优势。

任务管理与调度:

  • 裸跑:在裸机环境中,任务的管理和调度通常需要程序员手动实现。这增加了开发的复杂性和工作量,但对于一些简单的应用来说可能足够。
  • RTOS:RTOS提供了任务调度和管理的机制,使得开发者可以更容易地创建多任务应用。它支持任务的优先级调度、时间片轮转等策略,有助于确保实时任务的执行。

开发与维护:

  • 裸跑:裸机开发通常更底层,需要开发者对硬件有更深入的了解。维护和调试也可能更加困难,因为缺乏高级别的抽象和工具支持。
  • RTOS:RTOS提供了一套丰富的API和工具,使得开发更加便捷。同时,由于RTOS的标准化和模块化设计,维护和升级也变得更加容易。

应用场景:

  • 裸跑:通常适用于资源受限、对性能要求极高的场景,如一些嵌入式系统或微控制器应用。
  • RTOS:适用于需要多任务处理、复杂功能且对实时性有一定要求的场景,如工业自动化、医疗设备、航空航天等。

在回答时,可以结合具体的项目经验或案例来进一步说明这些区别,以及在实际应用中如何根据需求选择合适的方案。同时,展现出对两种方案的深入理解和实际应用能力,有助于提升面试官对你的评价。

上到Linux后有什么新的感觉呢

iic和spi的区别是什么

手撕两道

最接近的三数之和

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

int comp(const void *a, const void *b) { return *(int *)a - *(int *)b; }
int threeSumClosest(int *nums, int numsSize, int target) {
    int n = numsSize;
    qsort(nums, n, sizeof(int), comp);
    int best = 1e7;

    // 根据差值的绝对值来更新答案

    // 枚举 a
    for (int i = 0; i < n; ++i) {
        // 保证和上一次枚举的元素不相等
        if (i > 0 && nums[i] == nums[i - 1]) {
            continue;
        }
        // 使用双指针枚举 b 和 c
        int j = i + 1, k = n - 1;
        while (j < k) {
            int sum = nums[i] + nums[j] + nums[k];
            // 如果和为 target 直接返回答案
            if (sum == target) {
                return target;
            }
            if (abs(sum - target) < abs(best - target)) {
                best = sum;
            }
            if (sum > target) {
                // 如果和大于 target,移动 c 对应的指针
                int k0 = k - 1;
                // 移动到下一个不相等的元素
                while (j < k0 && nums[k0] == nums[k]) {
                    --k0;
                }
                k = k0;
            } else {
                // 如果和小于 target,移动 b 对应的指针
                int j0 = j + 1;
                // 移动到下一个不相等的元素
                while (j0 < k && nums[j0] == nums[j]) {
                    ++j0;
                }
                j = j0;
            }
        }
    }
    return best;
}

那四个数呢?

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n a、b、c 和 d 互不相同 nums[a] + nums[b] + nums[c] + nums[d] == target 你可以按 任意顺序 返回答案 。

int comp(const void* a, const void* b) {
    return *(int*)a - *(int*)b;
}

int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) {
    int** quadruplets = malloc(sizeof(int*) * 1001);
    *returnSize = 0;
    *returnColumnSizes = malloc(sizeof(int) * 1001);
    if (numsSize < 4) {
        return quadruplets;
    }
    qsort(nums, numsSize, sizeof(int), comp);
    int length = numsSize;
    for (int i = 0; i < length - 3; i++) {
        if (i > 0 && nums[i] == nums[i - 1]) {
            continue;
        }
        if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
            break;
        }
        if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
            continue;
        }
        for (int j = i + 1; j < length - 2; j++) {
            if (j > i + 1 && nums[j] == nums[j - 1]) {
                continue;
            }
            if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                break;
            }
            if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
                continue;
            }
            int left = j + 1, right = length - 1;
            while (left < right) {
                long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
                if (sum == target) {
                    int* tmp = malloc(sizeof(int) * 4);
                    tmp[0] = nums[i], tmp[1] = nums[j], tmp[2] = nums[left], tmp[3] = nums[right];
                    (*returnColumnSizes)[(*returnSize)] = 4;
                    quadruplets[(*returnSize)++] = tmp;
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    left++;
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }
                    right--;
                } else if (sum < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }
    }
    return quadruplets;
}

机试是真的挺难的,但是面试的时候手撕,都还是蛮中等的。

【四面】主管面

主要考察你怎么应对压力和解决问题

# 在学校里面有什么嵌入式相关的经验呢
# 整个方案设计是从无到有吗
# 前面押题吗
# 发挥了什么样的作用呢, 作为队长
# 有意外吗, 怎么解决的
# 比赛紧张期间怎么解决的问题
# 花多长时间解决了
# 中间有目标调整吗
# 换一个方案, 队友认同?
# 他们有擅长的方向吗
# 你觉得哪些技术因素最重要
# 休息了多长时间
# 队友都自愿的吗
# 竞赛对保研有什么帮助吗
# 谈谈期望的薪酬, 怎么考虑的
# 什么时候去报道
# 平时碰到事情容不容易着急
# 碰到上网查一查搞不定, 比较有挑战, 怎么去克服
# 自己摸索还是
# 没有很焦急的ddl
# 团队合作这块有没有相关的经历
# 从头到尾都没有问题吗
# 修改的方案是怎么定下来的呢
# 对未来多人项目怎么样共同工作
# 压力大怎么释放压力呢
# 在深圳哪
# 反问

非技术面,后面我会统一放一起,提供一个中肯好使的模版,因为每家公司的风格和文化不一样,对于同一个主观问题,可能想要的结果也不一样,所以等后面咱们好好分析一下。

面试题目来源:区欠皇

*************************

ARM/Linux嵌入式面试集 文章被收录于专栏

让实战与真题助你offer满天飞!!! 华为、OPPO、大疆、Vivo、小米、海康、大华等大厂嵌入式工程师面试真题与经验。 每周两更,共计100篇! 励志做最全ARM/Linux嵌入式面试经验与题库。 励志讲清每一个知识点,找到每个问题最好的答案。 让你学懂,掌握,融会贯通。订阅即赠送学习笔记、简历模板、面试提纲模板【正在精心完善丰富中】。同时不定期更新内推招聘机会。

全部评论

相关推荐

11 49 评论
分享
牛客网
牛客企业服务