当前位置: 首页 > 面试经验 >

暑期实习:美团 测开+答案 (一面 二面 hr面)

优质
小牛编辑
83浏览
2024-12-24

暑期实习:美团 测开+答案 (一面 二面 hr面)

虽然是做嵌入式的,当时特别慌所以测开我也投了,而且美团的流程特别快,一周就拿到了offer,也为我稍稍缓解了一些找工作的焦虑,让我们一起感谢美团!

一面

  1. 自我介绍
  2. 算法:有序链表合并 leetcode的解法,基本都这样
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1 == nullptr) {
            return l2;
        } else if (l2 == nullptr) {
            return l1;
        } else if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }
};
  1. 测试用例怎么写

这个主意就是一些边界条件,指针空啊,数据不合理啊,数据的类型不合理啊啥的,这个多刷刷算法,应该会有比较多的认识,我感觉这个言之合理就可以,因为我也是按照刷算法的时候经常没考虑到的边界情况来说的~

  1. 时间复杂度计算

    1. 一个for 就是n,嵌套几个就是几次方
    2. 二分是log,
    3. 其他的是1
    4. 如果是嵌套关系就是乘,并列关系就是取复杂度高的那个
    5. 然后记一下常见的几种算法的复杂度
  2. 指针和引用

    1. 区别

    一个是地址一个是别名,初始化不一样,然后就可以从使用的角度说一下,引用可以避免拷贝啊,不用解引用啊啥的说说。

    1. 自增的意义的区别

    指针自增就是指向下一个地址,引用自增是那个数据增加

    1. 指针没有做类型检查

    指针会做类型检查,但是可以强制转换来绕开,不是特别严格。

  3. 写代码的时候如何处理异常 空指针这种可能出现风险的地方会如何处理

    1. 首先是要有良好的编码习惯:new 和 delete配对,不要用悬垂指针、空指针、野指针等等吧
    2. 做好异常处理
    3. 可以用一些工具检查,AddressSanitizer等等吧方便检查
  4. 异常捕捉方式

    1. catch中需要写些什么内容
  5. 析构函数的理解

可以看看《程序员的自我修养》里面对析构函数有很底层的讲解~。我先抛砖引玉一下,用一个段来存放这个类生命周期结束后,自动调用的用来做一些清理工作:释放资源等等吧。

  1. 深拷贝和浅拷贝

    1. 区别、底层实现的区别

    • 深拷贝:把所有的都重新拷贝一份,重新分配一份动态内存,新旧对象拥有各自独立的内存,不会互相干扰、冲突,使用更安全,但拷贝代价更高
    • 浅拷贝:如果有指针啥的只拷贝指针,也就是说拷贝出来的会和原来的共享同一个动态内存。

    所以,浅拷贝后,释放了一个,如果另一个也释放就会出现重复释放的问题~

    1. 最主要的区别,是地址+值 和 只是地址么?

    是的

  2. static

    1. static修饰成员方法呢?

    放在text段,共用且不依赖实现可以CLASS::STATIC_FUNC()直接用,且在程序开始时就已经存在,直到程序结束,有点类似于区分命名空间的意思

    1. static修饰变量内存分配?和其他变量有啥区别?

    • 和程序同一生命周期

    • 只在类内可见、共享

    • 放在数据段而不是栈上了

    1. 栈上是怎么开辟的?
    int foo(int a, int b) {
    	int x = a + b;     // 局部变量 x
    	int y = x * 2;     // 局部变量 y
    	return y;
    }
    

其汇编如下

```asm
	; 函数入口
foo:
	push    ebp              ; 1) 保护调用者的基址指针
	
 类似资料: