三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)

三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)

文章目录

  • 个人情况
    • 目前工作
    • 在校经历
  • 就业经验及避坑
    • 如何选
      • 公司前景、工作环境、薪资待遇、工作内容
      • 警惕两方协议、补充三方协议、竞业协议、培训协议和违约金
        • 三方违约金
        • 竞业协议
        • 培训协议
        • 两方协议、补充条款
      • 大厂和小厂的区别
      • 外包公司避坑
      • 垃圾桶里不一定有垃圾,但是垃圾一般都在垃圾桶里
    • 如何被选
      • 自我定位:想做啥、怎么做、能不能做、好不好做
      • 简历:突出重点,去掉废话
      • 面试:实事求是,敢于表现
      • 喊薪:双向选择,价高者得
  • 附录:压缩字符串、大小端格式转换
    • 压缩字符串
      • 浮点数
      • 压缩Packed-ASCII字符串
    • 大小端转换
      • 什么是大端和小端
      • 数据传输中的大小端
      • 总结
      • 大小端转换函数

个人情况

目前工作

我目前工作岗位为嵌入式软件工程师(雷达射频方向)
去年本科毕业以后到现在也才工作一年
当时拿到最高的offer就是长江存储在上海17500的岗位
还拿到了华为海思、法雷奥等大厂offer
但是我没去 没去的原因下文会说
我选择了武汉的一家做雷达的小企业 算上项目奖 年薪能拿到30
我刚进公司也只是从事MCU开发 目前逐渐往雷达信号处理和算法上面转
(以上这些可以从我CSDN发的文章上面看到我在做什么)
目前我主要从事的工作有:

MCU、DSP,及嵌入式相关开发
毫米波雷达开发
433MHz无线通信开发
激光雷达开发
传感器、电源管理、EEPROM等

这一年里 总计软件开发16次 硬件设计2次 代码贡献量2w余行

主要参与的几个大项目就是ADuCM4050、STM32L4的HART协议物位计、IWR6843AOP毫米波雷达、AT32雷达尾灯
CSDN上有我的部分通用代码开源

在校经历

我三本本科毕业
专业为光电信息科学与工程
我四级没过(342) 电路理论 大学英语2重修 线代挂科
但是我喜欢自行开发项目
所有在校的项目的成绩都为优
毕设全院第一校一等 4.5万字查重0.1% 毕业以后申请软著并发表期刊(是一个业内没人做的创新设备 所以我的毕设属于研究与设计 最后硬件方面也只是做了个demo展示品)
无实习、竞赛、班干经历 无考级、专利软著证书 无评优 绩点2.21垫底
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第1张图片
这是我的当时的成绩单和我的自我评价
我的简历上的项目则是这样的:
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第2张图片
其中 那个机创省赛 是长江大学表白墙上面的一个人 问有没有会树莓派的 我家就在长江大学旁边 所以我就去了 然后拿钱

就业经验及避坑

如何选

公司前景、工作环境、薪资待遇、工作内容

这一点仁者见仁智者见智 你喜欢你也可以去一些环境不太好 特别卷的公司 但注意看公司发展 尤其是招人时的码龄构成
如果每年都招好几千人的应届生 年年如此 但公司又没有年年扩张 那就说明这个公司留不住人 并且可能是个大学生都能进 没啥技术要求 对个人成长不太好

一般来说 国企待遇垫底 欧美外资待遇最高
在武汉这种大学生特别多的城市来说 央企国企卷的不能再卷了 别人5000块钱能招一个大学生 为什么要给你6000?
比如烽火旗下公司 华工控股旗下公司
我有个烽火的朋友 他们加班没有加班费 如果级别高一点 到晚上九点半有打车补助 他的领导曾经说过 要感谢领导给他们加班的机会(那时候烽火在裁员)

再就是看公司产业 嵌入式行业比如PLC这种 属于过时了但又垮不了的 就别期望太高工资了

警惕两方协议、补充三方协议、竞业协议、培训协议和违约金

三方违约金

首先 如果是走校招 违约金不得超过5000
另外 作为三方协议 学校也起到监管作用 理论上 如果觉得这家公司不太行 可以直接找老师取消三方协议即可 只需要操作一下就行了

竞业协议

竞业协议必须要给竞业费才能生效(有的公司发工资的时候 工资构成里面有竞业费)
并且在竞业协议生效期间 无论是在职还是离职 公司都必须给竞业费 不然就可以不履行竞业协议
比如签两年竞业协议 要求离职以后两年内不得从事相关行业 在职期间假设每个月给你200竞业费 那么离职两年后 每个月还是得给你200竞业费

培训协议

培训协议则必须要有完整的培训制度 包括但不限于公司内部培训和统一找第三方培训机构的培训
如果培训协议要求离职给违约金 那么必须能够开具相关用于此员工培训的所有开销发票 才能主张违约金赔偿

两方协议、补充条款

上文说到 我本科毕业最高的offer就是长江存储在上海的17500的岗位
我相信这个数字大部分本科生都拿不到
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第3张图片
我当时没去的一个重要原因 就是岗位上面写的是嵌入式软件开发及测试 我当心学不到东西
当时我还在签约群里面问 我说这个该不会是外包吧?
在签约群里 三本学校人数跟清北一样多 所以不要觉得自己就比别人差

然后我就没去 (而且22年底他们一波裁员)但是写这篇文章的时候 又拿出来看 我才发现种种端倪

首先就是年终奖这一条 我问了一下 3、4月发年终奖 按这个offer的写法 过年期间离职的话 上一年的年终奖估计就没了

再就是 如果你要签约的话(无论是纸质三方还是网签) 都要签一个两方协议和补充条款
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第4张图片
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第5张图片
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第6张图片
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第7张图片

违约金我就不提了
但是对于考公考研这些 本来就是秋招找工作的学生哪能知道自己能不能考上 而且所有学校的三方协议上面都规定了这些不算违约 那么问题就来了

长江存储要求 就业补充协议 覆盖原本的三方协议!!!


就业补充协议直接替代了原本三方协议中的《违约责任》部分

大厂和小厂的区别

大厂的话 去了以后基本上就是负责某一部分 某一模块
拿嵌入式来说的话
做ST的 可能就一直做ST 甚至可能只做通信部分或者外设部分
做Linux的 可能就一直做Linux
接触的面比较少 而应届生就应该多学多看
相反 小厂就是啥都可能做
比如我一开始写ADuCM4050 后面就写STM32L4和HART协议下位机去了
再后面又开始做雷达DSP 其实这对我的提升很大

大厂可能就是规章制度比较完善 转岗都要申请 但是小厂的话 没那么多规章制度 比如我们公司现在都不加班 也不打开 说的是965 但是我每次9.30来 16.30走 只要你完成相应的工作就OK了

外包公司避坑

互联网太多外包了
除了我上面提到的 留不住人的公司外
还有那种靠接项目活的公司(没有自己的产品)
也就是接其他公司的项目 一次性做完 拿到经费就再做下一个
这种公司没有一套自己的核心产业 大多比较杂 并且没有自己的想法 都是为了甲方服务

垃圾桶里不一定有垃圾,但是垃圾一般都在垃圾桶里

首先 一上来就是心理测试 面试不进行技术面的 一定不是好公司
也不是说大厂 国企一定就不好 也有比较好的
而且大厂的话 可以作为一个跳板 只不过是摔还是跳的更高就不得而知了
不要想着自己去了就一定能做到最好(跟你一起进去的人 很多也是这样的想法)
一个公司的环境、结构 是一个人改变不了的 敬而远之就好了

如何被选

自我定位:想做啥、怎么做、能不能做、好不好做

要明白自己的优缺点 和擅长的领域
也要结合当下情况来分析
比如我当时找工作的时候 我最想做的就是光电行业相关的 再就是计算机视觉 最后才是嵌入式
但是第一个工资太低了 第二个大多要求研究生
所以后面我就转嵌入式了

另外 也要根据自己的意愿来定位 比如你就像躺平 那么就直接大厂就好了

简历:突出重点,去掉废话

简历这个是个大坑
很多人虽然没什么经历 但是就非要凑字数 其实反而有副作用
首先 像计算机二级 驾照 普通话证书 教师资格证这种 对于互联网完全没用 这就是给非互联网专业的人考的 写了就掉价
其次 什么当了班长这些也没啥用 技术人不需要会拍马屁
所以最重要的就是 做了什么项目 会哪些技术 在项目中充当什么角色 是不是自己独立开发完成 自学能力怎么样
三本应届生武汉年薪30w的互联网就业经验与避坑浅谈(毕业工作一年的嵌入式软件工程师经验分享)_第8张图片
这是我当时的简历 背面还有一个项目详情

面试:实事求是,敢于表现

面试不要作假 明明自己不会 非要说自己的会(伪造简历的更不用说了)
不要想着滥竽充数 班门弄斧 面试官比你懂的多了(其实我工作一年以后 也在作为第一轮技术面试官进行应届生面试筛选 回头看 其实很多小伎俩都很拙劣)

其次就是要善于表现自己的优点
比如你适合管理 那么就突出你在项目中的管理、调度等等
比如你适合研发 就得展现自己做项目时的思路、技术

喊薪:双向选择,价高者得

提前了解一下工资构成 如果是福利待遇特别高 项目奖特别多的 那么基本工资少一点也无所谓
但是 喊薪时的期望工资 还是算上总体来说比较好
尽量高一点
比如你手上有一个8000的offer 那么下次你面试就直接10k-12k

附录:压缩字符串、大小端格式转换

压缩字符串

首先HART数据格式如下:
在这里插入图片描述
在这里插入图片描述
重点就是浮点数和字符串类型
Latin-1就不说了 基本用不到

浮点数

浮点数里面 如 0x40 80 00 00表示4.0f

在HART协议里面 浮点数是按大端格式发送的 就是高位先发送 低位后发送

发送出来的数组为:40,80,00,00

但在C语言对浮点数的存储中 是按小端格式来存储的 也就是40在高位 00在低位
浮点数:4.0f
地址0x1000对应00
地址0x1001对应00
地址0x1002对应80
地址0x1003对应40

若直接使用memcpy函数 则需要进行大小端转换 否则会存储为:
地址0x1000对应40
地址0x1001对应80
地址0x1002对应00
地址0x1003对应00

大小端转换:

void swap32(void * p)
{
   uint32_t *ptr=p;
   uint32_t x = *ptr;
   x = (x << 16) | (x >> 16);
   x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);

   *ptr=x;
}

压缩Packed-ASCII字符串

本质上是将原本的ASCII的最高2位去掉 然后拼接起来 比如空格(0x20)
四个空格拼接后就成了
1000 0010 0000 1000 0010 0000
十六进制:82 08 20
对了一下表 0x20之前的识别不了
也就是只能识别0x20-0x5F的ASCII表
在这里插入图片描述

压缩/解压函数后面再写:

//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_ASCII_to_Pack(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
   if(str_len%4)
   {
      return 0;
   }
	 
   uint8_t i=0;
   memset(buf,0,str_len/4*3);	  
   for(i=0;i<str_len;i++)
   {
      if(str[i]==0x00)
      {
         str[i]=0x20;
      }
   }

   for(i=0;i<str_len/4;i++)
   {
      buf[3*i]=(str[4*i]<<2)|((str[4*i+1]>>4)&0x03);
      buf[3*i+1]=(str[4*i+1]<<4)|((str[4*i+2]>>2)&0x0F);
      buf[3*i+2]=(str[4*i+2]<<6)|(str[4*i+3]&0x3F);
   }

   return 1;
}

//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_Pack_to_ASCII(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
   if(str_len%4)
   {
      return 0;
   }

   uint8_t i=0;

   memset(str,0,str_len);

   for(i=0;i<str_len/4;i++)
   {
      str[4*i]=(buf[3*i]>>2)&0x3F;
      str[4*i+1]=((buf[3*i]<<4)&0x30)|(buf[3*i+1]>>4);
      str[4*i+2]=((buf[3*i+1]<<2)&0x3C)|(buf[3*i+2]>>6);
      str[4*i+3]=buf[3*i+2]&0x3F;
   }

   return 1;
}


大小端转换

在串口等数据解析中 难免遇到大小端格式问题

什么是大端和小端

所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

简单来说:大端——高尾端,小端——低尾端

举个例子,比如数字 0x12 34 56 78在内存中的表示形式为:

1)大端模式:

低地址 -----------------> 高地址

0x12 | 0x34 | 0x56 | 0x78

2)小端模式:

低地址 ------------------> 高地址

0x78 | 0x56 | 0x34 | 0x12

可见,大端模式和字符串的存储模式类似。

数据传输中的大小端

比如地址位、起止位一般都是大端格式
如:
起始位:0x520A
则发送的buf应为{0x52,0x0A}

而数据位一般是小端格式(单字节无大小端之分)
如:
一个16位的数据发送出来为{0x52,0x0A}
则对应的uint16_t类型数为: 0x0A52

而对于浮点数4.0f 转为32位应是:
40 80 00 00

以大端存储来说 发送出来的buf就是依次发送 40 80 00 00

以小端存储来说 则发送 00 00 80 40

由于memcpy等函数 是按字节地址进行复制 其复制的格式为小端格式 所以当数据为小端存储时 不用进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x00,0x00,0x80,0x40};
   memcpy(&dat,buf,4);
   float f=0.0f;
   f=*((float*)&dat); //地址强转
   printf("%f",f);

或更优解:

   uint8_t buf[]={0x00,0x00,0x80,0x40};   
   float f=0.0f;
   memcpy(&f,buf,4);

而对于大端存储的数据(如HART协议数据 全为大端格式) 其复制的格式仍然为小端格式 所以当数据为小端存储时 要进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
   memcpy(&dat,buf,4);
   float f=0.0f;
   swap32(&dat); //大小端转换
   f=*((float*)&dat); //地址强转
   printf("%f",f);

或:

uint8_t buf[]={0x40,0x80,0x00,0x00};
   memcpy(&dat,buf,4);
   float f=0.0f;
   swap32(&f); //大小端转换
   printf("%f",f);

或更优解:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
   float f=0.0f;
   dat=(buf[0]<<24)|(buf[0]<<16)|(buf[0]<<8)|(buf[0]<<0)
   f=*((float*)&dat);

总结

固 若数据为小端格式 则可以直接用memcpy函数进行转换 否则通过移位的方式再进行地址强转

对于多位数据 比如同时传两个浮点数 则可以定义结构体之后进行memcpy复制(数据为小端格式)

对于小端数据 直接用memcpy写入即可 若是浮点数 也不用再进行强转

对于大端数据 如果不嫌麻烦 或想使代码更加简洁(但执行效率会降低) 也可以先用memcpy写入结构体之后再调用大小端转换函数 但这里需要注意的是 结构体必须全为无符号整型 浮点型只能在大小端转换写入之后再次强转 若结构体内采用浮点型 则需要强转两次

所以对于大端数据 推荐通过移位的方式来进行赋值 然后再进行个别数的强转 再往通用结构体进行写入

多个不同变量大小的结构体 要主要字节对齐的问题
可以用#pragma pack(1) 使其对齐为1
但会影响效率

大小端转换函数

直接通过对地址的操作来实现 传入的变量为32位的变量
中间变量ptr是传入变量的地址

void swap16(void * p)
{
   uint16_t *ptr=p;
   uint16_t x = *ptr;
   x = (x << 8) | (x >> 8);

   *ptr=x;
}

void swap32(void * p)
{
   uint32_t *ptr=p;
   uint32_t x = *ptr;
   x = (x << 16) | (x >> 16);
   x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);

   *ptr=x;
}

void swap64(void * p)
{
   uint64_t *ptr=p;
   uint64_t x = *ptr;
   x = (x << 32) | (x >> 32);
   x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF0000FFFF);
   x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF00FF00FF);

   *ptr=x;
}

你可能感兴趣的:(经验分享,单片机,嵌入式,物联网,mcu,就业,面试)