大道五十,天衍四十九,人遁其一!

# 写在前面

作为一个四非二本末流师范院校的工科专业的学生,给大厂投简历的都不如树叶落水,一丝波纹都没有.
大厂 HR 们一看院校就直接 pass 了,除非走内推,像我着这种大厂基本就没什么希望.
从 9 月 15 号开始投,直到现在还是 0 offer, 这还是我第一次面试 (╯_╰).
就感叹一下,下面的经历,诸位就当看个笑话就好.

# 面试经历

# hr 面

hr 给我打电话的时候,我正在做 智能涂鸦 的性格测试,做完之后发现有一个未接电话没当回事。当时以为是快递电话,因为前几天中通丢件了,说是要给我下午 5 点会打电话,当时差不多 5 点 (是真的巧). 然后我直接打回去了,显示的是杭州,我楞了一下 (因为一直都没有接到过面试).
电话通了之后 对面的小姐姐说:"您是?", 我愣了一下说了句:"是你们给我,打电话的". 然后对面就明白了,然后,然后就开始了猝不及防的 hr 面,以至于我最后连他们是哪个公司都不知道的情况下结束了 hr 面 (´。_。`).
最后我还是厚着脸皮问了是哪个公司つ﹏⊂.
值得庆幸的是 hr 也是个新手,大家都是第一次。所以也还好,真就是什么样的人遇上什么样的 hr (狗头)
不过总体来说 丙甲的 hr 还是很棒的,非常非常温柔和客气,非常 nice.
总体是问了 为什么走选择嵌入式,对嵌入式的看法,能不能接受杭州的环境,什么时候能实习以及安排了一下 技术面的时间

# 技术面

技术面总体感觉没有问什么特别细的东西,就大致问了问各个项目,可能也是我投的是实习的缘故.

这次技术面在项目上有几个地方把我问住了
第一个是 TCP/IP 协议有没有自定义协议,我愣了一下没反应过来说了个没有。我当时以为是说,有没有自己形成 类似于 http、COAP 之类的协议.
第二个是 KMP 算法,时间太久真的没想明白,就记得从下次不是一个个往后跳,连 next 数组都忘了
第三个是 状态机的问题,问我在垃圾桶识别的时候用什么控制,我当时以为问的是 轮询,前后台 和 RTOS, 结果我没有
第四个是 数字滤波算法,我一直以为 iir 能用电路实现,显然不能,不过 iir 可以用 FPGA 实现的,问了我为什么要用 iir, 我答了手头能实现和体现出来的效果就是这样的。感觉除了 认为 iir 可以硬件实现之外都么有什么问题
第五个是 PID 算法,问了一下 PID 和 位置式 PID 的区别,我当时第一反应是就是两个是一样的,后面他说还是有些不同的在积分环节上。我才回过神来,位置式 PID 是直接使用 PD 环的,不使用 积分环节,积分环节会导致

然后就问了一下 C 语言 的问题:
第一个是 static 加在全局变量前面的作用。我当时楞了一下,然后反应过来了是限制作用域,因为全局变量本身就是静态存储,加不加 static 并没有什么区别,但是在链接的时候,如果没有 static 那么这个在链接的时候就会和其他文件里的同名变量冲突
第二个是 #defineconst 的区别。这个还是比较简单的,最简单的一个就是 const 定义的常量在编译过程中实现的,在内存中存在空间的, #define 定义的常量在预编译过程中完成替换,在内存中没有空间。还有一些细节上的东西我当时没打上来
第三个是 memmovememcpy 的区别。这个真的是把我问懵了,因为用的少愣是想了很久了,这里主要是内存重叠的问题,主在 copy 过程中会出现 源地址 会和 起始地址重叠

整体来说,还是第一次面试的原因,过于紧张,基础知识不够牢固,对 c 库函数的不熟悉

# 知识点总结

# TCP/IP

# 网络模型

# ISO 七层网络模型:

名称作用典型服务
应用层所有能和用户交互产生网络流量的程序FTP、SMTP、HTTP
表示层用于处理两个系统中ASCII、JPEG
会话层向表示层 / 用户层进程提供建立连接并在连接上有序的传输数据.(也被称为同步)ADSP、ASP
传输层负责主机之间的通信,端到端的通信,传输单位:报文段 / 数据报TCP、UDP
网络层把分组从源端传输到目的端,分组交换网络的不同主机所提供的通信服务。单位是数据报IP、IPx、ICMP、ARP、OSPF
数据链路层把网络层数据组装成帧,单位为数据帧SDLC、HDLC、PPP、STP
物理层在物理介质上实现网络传输 单位 bitRJ45、802.3
ISO

# 五层网络模型

应用层、传输层、网络层、数据链路层、物理层

# TCP/IP 网络模型

TCP/IP

# KMP 算法

KMP 算法最大特点在于,利用以匹配完成的信息进行转跳
转跳方式依赖于 next 数组, next 实现的方法是通过 计算最大真前缀长度实现的.
具体可以参考这篇博客传送门

# IIR 应用

人体心电信号中常带有工频干扰 (50HZ)、基线漂移 (频率低于 0.5Hz) 和肌电干扰等各种噪声

# 基线漂移

基线漂移一般由于信号采集时呼吸及人体移动造成的,表现为低频率的缓慢变化噪声,其频率一般小于 0.5Hz.
基线滤波的一个主要问题是滤波后会对 ST 段产生影响,由于基线频率与 ST 段的频率很接近,如果滤波器选择不好的话,有可能会导致 ST 段发生改变.
由于 ST 段是判断心肌梗死,心肌缺血等疾病的主要参数之一,滤波导致的 ST 段改变是不能接受的
美国心脏协会 (AHA) 推荐在使用非线性相移的 IIR 滤波器时,其截止频率最高为 0.05Hz, 使用具有线性相移的 FIR 滤波器时,截止频率最高可以到 0.67Hz, 对应 40 的心率

# 零相位的基线滤波

在使用 IIR 实现线性相位的滤波器应用中,有一类特殊的滤波器 — 零相位滤波器.
该滤波器通过前向和后向两次滤波,实现零相移,保证了 ST 段不失真。相对于 FIR 的高阶次导致较多运算量来说,零相移滤波器能实现较低的运算次数。但零相移也有一个较为致命的缺点,由于存在后向滤波,所以需要全部数据采集完成后,才可以进行第二次滤波,这样导致了在实时环境中无法使用

# 肌电干扰

肌电干扰属于高频信号,一般在实际中,采用截止频率为 20Hz、30Hz 和 40Hz 的低通滤波器进行滤除

# static 用法

限制作用域,存储方式变为静态存储

  1. 修饰全局变量,限制作用域。在链接过程中,多文件中的重名变量不会冲突.
  2. 修饰局部变量,延长生命周期,存储方式变为静态存储只进行一次初始化.
  3. 修饰函数,限制函数作用域,局限在文件内部。在连接过程中避免和多文件中同名函数冲突

# #defineconst 的区别

  1. const 定义的常量在程序运行过程中只有一份拷贝 (因为它是全局的只读变量,存放在静态区), 而 #define 定义的宏常量在内存中有若干个拷贝 (没有存空间)
  2. #define 宏是在预编译阶段进行替换,而 const 修饰的只读变量是在编译的时候确定其值
  3. #define 宏没有类型,而 const 修饰的只读变量具有特定的类型
  4. #define 不能被调试, const 可以被调试

# memmovememcpy 的区别

首先 memcpymemmove 都是 c 语言库函数,位于 string.h 中的函数.
其函数原型分别为

void *memcpy(void *dst, const void *src, size_t count);
void *memmove(void *dst, const void *src, size_t count);

作用都是拷贝一段内存的内容,到目的地址。区别在于,在内存重叠时, memmove 可以保证数据的正确复制,而 memcpy 不可以
情况如图
memmove
对于第一种情况 memcpy 可以完美解决,但是对于后面这两种 memcpy 就无法保证复制结果.
所以 memcpy 实现方法因该如下:

void* my_memcpy(void* dst, const void* src, size_t n)
{
    char *tmp_d = (char*)dst;
    char *tmp_s = (char*)src;
 
    while(n--) {
        *tmp_d++ = *tmp_s++;
    }
    return dst;
}

对 其进行分类讨论则可得到 memmove

void* my_memmove(void* dst, const void* src, size_t n)
{
    char *tmp_d = (char*)dst;
    char *tmp_s = (char*)src;
    if (tmp_d > tmp_s && tmp_s+n > tmp_d)
    { // 内存重叠
      tmp_d = tmp_d+n-1;
      tmp_s = tmp_s+n-1;
      while (n--){ // 先将回被重叠的地方存入目的地址
        *tmp_d-- = *tmp_s--;
      }
    }
    else
    { 
      while(n--) {
          *tmp_d++ = *tmp_s++;
      }
    }
    return dst;
}

大道五十,天衍四十九,人遁其一!

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

黑羊 支付宝

支付宝