软牛科技逆向开发工程师一面

本来投递的是软牛科技的Cpp开发岗,然后HR表示Cpp已经招满,只剩逆向方向,然后我就转了逆向方向,之前也没有逆向相关的经验,只是懂点RISC-V汇编、反汇编过一些ELF可执行文件,但抱着试试看的想法,还是参加了笔试,笔试主要都是C/C++的基本知识点考察,只有一道跟逆向相关的直接空过了,后面交了笔试之后有一段时间没咨询HR,结果一直没有反馈,后面想起了这茬,问了一下HR才说笔试通过了,可以安排面试。

  1. 自我介绍。
  2. 对逆向岗位的了解有多少?
  3. 看没看过《汇编语言》(王爽)?(回答看了一点,后面因为没有需求就没看了,主要看RISC-V指令集。)
  4. 汇编语言中,函数是如何传参的?(这里他想问的可能是x86,但是我不太了解,于是我就答了RISC-V函数调用的时候参数是放到a0-a7寄存器里,超过的参数会放在栈上传递。)
  5. 之前有没有调试过汇编?(答了在用gdb调试项目里的内核代码的时候,有时候会用gdb看看汇编指令,顺便也讲了RISC-V函数调用的过程,先压栈ra寄存器,然后压栈fp、sp寄存器,然后申请栈上变量,返回时恢复ra、sp、fp。)
  6. 知道函数调用中的传参顺序吗?(答了第一个参数放到a0,以此类推直到a7,更多的参数放在栈上。)
  7. 可能我没描述清楚,假设我有一个函数f(int a, int b, int c, int d),这四个参数在汇编的时候它们传到函数内部的顺序是什么样的,先传哪一个?(这个问题没听明白,不太清楚想问的是什么,于是就答了C++标准对于参数的求值顺序应该是没有指定的,由实现来决定参数的求值顺序,至于传入顺序,感觉就是从左到右传递,也即从第一个参数开始传递。)
  8. 你对C++的函数调用约定了解过么?(答了没了解过。这个之前没有了解过,当时没答上来,后面搜了一下才知道原来就是之前看好多函数声明前面带着的符号__cdecl之类的一类符号就叫C++函数调用约定,涨了一波知识。
  9. 你说你是通过自学的方式学习C++的,你看过C++的哪本书?(答了《C++程序设计语言》(1-3部分)。)
  10. 说说C和C++有哪些区别?(答了C++引入了一些抽象机制,比如类的继承多态,模板,移动语义,lambda表达式,仿函数等。)
  11. 说说在笔试题里如何区别重载函数的关键字你为什么要选择virtual?(答了因为如果父类有virtual函数,派生类可以通过重载这个虚函数,来实现多态机制,也即在通过父类引用或指针来调用这个虚函数的时候,会根据实际引用或指向的实参不同而分别调用不同的实现,这样感觉能实现函数重载。后面复盘的时候才发现好像把函数重载和子类重写父类函数两个概念给搞混了,脑子抽了。
  12. 假设父类里面有个函数f参数是int,派生类中有个同名函数参数是const int,那子类中这个函数会覆盖掉父类中的函数么?(答了不会,因为它们的参数类型不同。当时真是没反应过来,后来才回过神来,对于一个实际的int参数,编译器根本没办法区分是调用const int还是int,所以子类的实现应该可以覆盖掉父类的实现的。
  13. 有了解过C++重载是怎么实现的么?(答了C++编译器会把参数的类型也编码到函数的名字里,这样即使函数名字相同,但它们的参数列表不同,编译器也会认为它们是不同的两个函数。)
  14. 假设在全局定义了一个函数f参数是int,另一个函数f参数是const int,那么这两个函数实现重载了么?(答了可以实现重载,因为它们的参数类型不同。面试官继续问这个问题,应该就是确认一下之前那里我确实答错了,实际上应该是不算重载的,因为没法区分。
  15. 讲讲构造函数和析构函数的调用顺序?(答了构造函数先调用每个成员的构造函数然后执行自己的构造函数,最后构造函数返回,成功构造,析构的话先调用自己的析构函数,然后调用成员的析构函数,所有析构结束之后返回,成功析构。这里忘说了继承情况下构造时应该首先执行父类的构造函数,析构时最后还需执行父类的析构函数。
  16. 假设一个类里有多个成员,那么这多个成员的构造函数调用顺序是怎么样的?(答了按照成员在类声明中的声明顺序来调用的。)
  17. 假设一个类没有数据成员,那么这个类在内存中占大小多大?(答了如果有虚函数的话会占一个指针大小的空间,如果没有的话所占空间是0Byte。后面查了一下发现所占空间不是0B,是1B,是因为C++标准规定完整对象的大小不能是0,为了区分不同的对象,所以最小只能是1,但是在继承中,空类可以不占空间。
  18. 你刚才说如果有虚函数,那所占空间是个指针大小,那么具体是多大呢?(答了地址空间是32位的话就是4B,64位的话就是8B。)
  19. 假设我有一个结构体第一个成员是int,第二个成员是long,这个结构体在32位机器和64位机器上所占空间是一样大的吗?(答了标准规定long大小是大于等于int,在64位机上long和int应该是一样大的,都是4B,在32位机上long应该是比int大的,但是考虑到内存对齐的话,可能两个结构体是一样大的。这个地方后来查了一下也答错了,64位机上long比int大,long是8B,int是4B,32位机上long和int一样大都是4B。
  20. 如果想要这两结构体在32位和64位机上大小一致,可以使用什么策略?(答了可以用内存对齐来实现。)
  21. 之前是否使用过VisualStudio这个开发工具?(答了,之前使用过,现在使用CLion。)
  22. 对内存的话有什么了解呢?(这个问的有点宽泛,就问了具体想问什么,面试官也没继续纠结,转而开启下一个问题。)
  23. 看你玩过操作系统,那你对PE文件有了解么?(答了没有了解,但是猜到可能是Windows上的可执行文件的格式,于是就简单讲了讲Linux系统的ELF可执行文件格式,也不太懂,就大概模糊的讲了一下。)
  24. 讲讲堆和栈的区别?(堆上分配的对象需要手动释放,栈上分配的对象会自动释放,堆上一般分配大的对象通过指针访问,栈上一般不分配大的对象,栈是从高地址向低地址增长。)
  25. 了解什么是栈溢出和堆溢出吗?(答了操作系统会通过在栈的上下设置不能访问的页面作为哨兵来检测栈溢出,当访问的地址到了这两个哨兵页面就会产生缺页中断,操作系统就会发现产生栈溢出,从而执行对应的处理策略,而堆溢出的话有可能是在堆上分配的对象过多或者对象过大,或者是产生了内存泄漏,从而使得堆空间被用尽,导致发生堆溢出。)
  26. 平时会使用什么方法来避免这些情况?(这个的话因为平时也没怎么遇到过,所以就岔开话题,答了xv6是如何检测栈溢出和堆溢出的,栈溢出是通过哨兵页面,堆溢出的话之前没处理过。)
  27. 假如在Windows上编写多线程程序,开多少个线程是比较好的?(这个直接给我问住了,一下不知道咋答了,后来就答了一个Amdahl定律和CPU核心数限制同时并行执行的线程数,还提了一嘴因特尔的超线程。)
  28. 之前有了解过死锁吗?(答了死锁产生的四个条件,然后避免死锁可以破坏其中任意一个条件,举了GPU调度线程执行时提前分配好了线程需要的所有资源,从而破坏占有且等待条件从而可以避免死锁,还有使用银行家算法在进程申请资源时检测在分配资源后系统是否会进入危险状态,如果会进入危险状态则不分配资源,从而避免死锁。)
  29. 看你之前学习过一些汇编语言,你对汇编语言怎么看待?
  30. 反问环节。

一面面试官说是感觉答得还可以,所以去叫部门主管来继续面一次,应该也算是二面了。

  1. 对逆向方向是否有兴趣?
  2. 可以去看一下《加密与解密》前八章,如果感兴趣后面可以再聊。
  3. 看到你参加了ACM这个竞赛你主要负责哪些方面的算法?(动态规划和图论相关的算法都学习过,还学过一些基础的计算几何。)
  4. 之前读过或者手写过汇编级别的程序么?(答了在做项目的时候,在上下文切换的时候需要手写汇编代码,然后用户进程陷入内核的话需要读汇编代码。)
  5. 讲一讲线程上下文切换的时候做了什么?(答了操作系统在内核中进行内核线程的切换的时候,首先保存当前内核线程的callee保存的寄存器,然后保存返回地址ra以及栈顶指针sp,之后将之前暂停的另一个线程的保存的寄存器加载到CPU中,从而实现线程的上下文切换,而用户进程陷入内核的时候,不能只保存callee保存的寄存器,还需要保存所有可用的寄存器,以及指向页表的寄存器,指向用户栈的寄存器,pc寄存器等寄存器,才能完成陷入内核的操作,在从内核退出前再次恢复之前保存的寄存器,从而实现了,用户进程陷入内核和恢复执行。)
  6. 讲一讲进程陷入内核态的时候用到了哪些汇编指令?(答了ld,sd,jalr,ecall。)
  7. 看你这个项目是个操作系统内核,你平时怎么调试这个内核?(答了使用gdb server调试。)
  8. 你平时都会使用什么调试方法?(答了会打断点,然后查看backtrace,然后使用printf语句。)
  9. 假如你的程序中有内存越界问题或者内存泄漏,有没有什么方法来排查?(这两个问题都不太会,之前没了解过,所以就大概乱答了一下。)
  10. 汇编语言如何实现条件分支?(答了RISC-V提供了beq之类的分支语句,通过判断两个寄存器的值是否相等来决定是否跳转到指定地址执行,从而实现分支以及循环。)
  11. 循环一般有三种写法,你觉得哪种效率最高?(答了我觉得while(expr){}这种写法效率最高。)
  12. 函数调用中,栈是如何变化的?(答了先把ra、fp、sp寄存器入栈,然后再保存一些在函数中用到的callee保存寄存器,然后改变栈指针分配栈上的变量,返回前再将之前保存的寄存器恢复即可。)
  13. 反问环节。

总结:挺多问题没太答好,而且可能项目技能和岗位相关性不太高,这家公司开发主要是在Windows上做逆向开发,Linux上的一些知识就不太有用,所以后面挂了也是可以理解的。

全部评论
都过了,到了HR面,然后不想面了= =感觉薪资有点低
4 回复 分享
发布于 2023-09-22 18:43 江苏
这感觉不容易啊,之前还想考虑去试试,现在感觉还是算了
1 回复 分享
发布于 2023-07-11 16:49 广东
兄弟线上笔试大概考什么内容啊
点赞 回复 分享
发布于 12-04 18:52 广东
这也太难了吧,逆向是个啥😭
点赞 回复 分享
发布于 04-22 16:12 广东
文档不错mark一下
点赞 回复 分享
发布于 02-12 15:50 广东
我是二面挂了😭
点赞 回复 分享
发布于 2023-08-15 23:27 安徽
答得还可以了叭,这都挂了😭
点赞 回复 分享
发布于 2023-07-18 10:09 江西
一面已经可以挂了,对逆向一点不熟,面试官很留面子了
点赞 回复 分享
发布于 2023-06-21 00:51 山西
二面有给博主时间看吗
点赞 回复 分享
发布于 2023-06-18 18:47 福建

相关推荐

11-27 22:23
已编辑
百度_前端(实习员工)
【11.21 百度一面】:1:自我介绍2:小程序项目介绍(面试官比较感兴趣这个)3:实习项目简单问了一下4:可视化5:大文件上传整体的思路、断点续传具体怎么实现?6:讲一下transform怎么使用的(提到小程序里面的一个应用)7:react常见hook8:父组件A里面有一个子组件B,子组件B使用useMemo()缓存值,如果A重新渲染,会导致B中useMemo重新计算嘛?        (回答:分情况,要是缓存的值中有父组件传递的props就还是要)9:无限滚动加载和图片懒加载10:拦截器主要做了些什么工作?11:数组常用方法?12:你做了可视化大屏展示,现在有多个大屏,怎么适配各种尺寸呢?(答了媒体查询,为每一个尺寸范围适配不同的比例大小)追问:如果提前不知道大屏的宽度呢答:可以使用flex响应式布局,比如flex 1 自动填充剩下的内容区域13:说一下事件冒泡是什么,怎么阻止冒泡(用e.stopPropagation())14:手搓 轮播图(太久没有写react了,面试官一直耐心指导,最后还是没搓出来,说了一下实现原理)15:反问业务、技术栈、实习生培养方案一面的面试官真的超级好,就我面试以来(七牛云、金蝶、懂车帝)是最好的一个了。一点一点指导,面试用的“如流”这个软件,中间断联了两次(一次网络断开,一次电脑没电直接关机,人傻了直接),结果面试官一点都没生气,还是很耐心的讲面完,10分钟不到,发消息,约二面...【11.24 百度二面】1:自我介绍2:Promise哪些常用方法3:大文件上传4:手写Promise.all (有一点点小缺憾)5:懒加载怎么实现的 (IntersationObserver)6:react的懒加载怎么实现(同上 + React.lazy结合Suspense)7:react常用hook8:useCallback和useMemo说一下9:手撕一个react自定义hook:getPrevieusValue(value) 传入一个值(state),获取他上一次的状态值(用的是map+数组存)面试官:其实可以用ref,因为你现在这个实现的话,依照的是状态,万一不小心改变了状态可能导致页面重新渲染8:3s后页面上显示啥?为啥?const app = () => {const [count, setCount] = useState(0)const [countTime, setCountTime] = useState(0)useEffect(() => {let timer = setTimeout(() => {setCountTime(count)}, 3000)setCount(5);() => clearTimeout(timer)}, [])return (<div>count:{{ count }}countTime:{{ countTime }}</div>)}(答了:分别是5和0,因为react状态是一个快照,他每计算次依照的是当前这一刻的状态(还好之前看过官方文档))9:上一个问题,那我想让都显示5怎么办?(提到用函数式更新、flushAsync、Ref持久化绑定)面试官:也可以在useEffect依赖里面加 count10:redux使用过嘛? 了解过基于redux开发的第三方工具嘛?(不了解)11:为啥使用redux不用useContext呢?12:说一下小程序的分包机制和分包预加载13:手写:数组转成树结构(没写出来[我算法太弱了[苦涩]],说了思路,用递归)const a = [{id: 1, parent: null, name: 'Big'},{id: 2, parent: 3, name: 'hello'},{id: 3, parent: 1, name: 'aloha'},{id: 4, parent: 1, name : 'yes'}];const b = {id: 1,name: 'big',children: [{id: 3,name: 'aloha',children: [{id: 2,name: 'hello',children: null,},],},{id: 4,name: 'yes',children: null,},],};面试官说你思路没问题,然后就给我讲了一遍非递归的实现思路如流这个软件,不知道是不是不适配我的电脑还是啥,面试的时候一直掉线(掉了四五次),开始我还以为我的网有问题,不过好在面试官没有生气,而且手撕题还给我耐心纠错和指导,也是很好的一个面试官【11.27】hr电话正上体育课,刚测完1000m,累成憨憨了,摊在地上结果忽然收到hr的电话,oc,下午1点多快到2点的时候,收到正式offer邮件......【插话】本来二面结束(周一),感觉没戏了,周二到周四整个人都是一个将die的状态,浑身不舒服,也没胃口,觉也睡不好,期间还面了懂车帝、深圳锐明技术,懂车帝面成粑粑了、锐明面的很好,但是这俩截至目前都没有下文面试,运气真的很重要,要是遇到一个恶心人的面试官,神来了也得挂。唯一 一点幸运的是,我做过小程序,刚好和他们组技术栈和业务匹配,同时干小程序的人本身也不多,所以被面试官看上了吧,要是投的其他业务组,一面都得挂
发面经攒人品
点赞 评论 收藏
分享
12-19 02:15
门头沟学院 C++
1. 实习介绍2. 两段开源经历拷打,主要聊开发过程遇到的事,技术涉及较少,虽然也没什么技术,估计就是确认一下是本人干的。3. 面试官介绍自己部门不是搞数据库内核的,询问真想来吗,给面试官给予了肯定的回答。4. 开发习惯闲聊,看不看火焰图,跨语言的benchmark怎么测的巴拉巴拉。5. 正式开始拷打,汗流浃背了。简历上项目就是常规15445+tinykv,遇到一个也都做过的面试官相当正常。6. 15445 lru-k算法、crabbing 协议(还包括读写锁细节,楼主都快记不得了,头一次有面试官问这个)。7. ACID 含义(楼主顺便聊了一下CAP的C跟ACID的C区别,直接预判面试官)8. 15445 三种隔离级别(RU, RC, RR,这块楼主早忘记了,所以回答的是mysql和pg的实现细节,参考:https://gg2002.github.io/2025/03/16/mysql-latch,顺便扯了几嘴mysql为啥会有表级锁和binlog,因为mysql是一个分离式的架构巴拉巴拉)9. tinykv拷打,multi raft必要性,项目思想。10. 分布式事务Percolator跟寻常单体数据库事务的差别(楼主大败而归,说到3列,但是忘记怎么具体地写这3列)11. raft全流程介绍(leaderelection+logreplication,楼主顺便加了点行业现状试图展示知识面)12. raft脑裂问题,prevote优化介绍13. raft的Leader Lease和ReadIndex优化(更是大败而归,头一次有面试官问这个,早就忘记了,扯了几嘴思想草草而过)14. 面试官询问tinysql,楼主没做过,但楼主打过ob数据库比赛,说那个比赛sql写的多,再次跟面试官闲聊一阵15. 广告场景题,问楼主广告曝光log和点击log哪个存kv好些,楼主说点击log少些,存点击,面试官说错,然后解释16. 算法题,线程安全的LRU
点赞 评论 收藏
分享
评论
19
71
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务