四天面试小记

连续四天的面试,简单记录下。

xx一面:

1.简单说了项目。
2.算法题。一个大于内存的文件怎么排序,这种题一看到肯定就是外部排序,内部归并处理,当时阻塞在认为每次归并必须把整个归并段全部调入内存中,再进行归并排序。然后就没把思路放在归并排序了,想到了堆排序,假设一共n个数,每趟可以使用小堆选出最大的k个数,然后将最大k个数输出到外存中,然后将剩下n-k个数再次调入内存进行堆排序,继续选出k个数,输出到外存中,直到所有的数字全部筛选完。内部使用归并肯定比堆排序处理的IO次数少,所以效率要高。
3.找到这个大文件的中位数,快排加上外部排序。
4.Lock和synchronized的区别和实现。
5.Java文件流,IO和NIO。 这个比较有意思,传统Java的IO是阻塞的,面试官一直追问我线程被阻塞,线程在等什么,当时没理解他问题的目的,回答等文件被写入,重复问它在等什么,回答等java调用操作系统提供的接口…蜜汁尴尬,重复问题,原来是个操作系统相关问题,在等通道处理…
6.面试官给了些建议,多注重底层,他们不关心那些什么框架…

xx二面:

1.JVM,GC简单说下。
2.多线程接触过没,简单描述下你使用的场景。
3.闲谈,实习时间等。

zz一面:

1.面试官第一个问题就问有刷题么,平时在哪刷题。。。答只刷了三十道题。
2.项目介绍。
3.算法题链表操作,复杂度,代码实现。

对链表的重排序问题:
输入:L1 L2 L3 …Ln-1 Ln
输出:L1 Ln L2 Ln-1 L3 Ln-2…

面试期间,只给出了O( n2 )复杂度的解决方法,当时写的代码在边界上也没处理好,虽然面试官没看出来,但是回来上机验证还是有问题。下面是用递归解决的。代码如下:

ListNode op(ListNode root) {
    if (root.next == null | root == null) return root;
    ListNode pointer, fronter = null, target;
    pointer = root.next;
    target = root;
    while (target.next != null) {
        fronter = target;
        target = target.next;
    }
    fronter.next = null;
    root.next = target
    if (target != pointer) {
        target.next = op(pointer);
    }
    return root;
}

复杂度:每一次都会减少两个结点,假设有N个结点,第一次遍历N个结点,第二次遍历N-2个,第三次遍历N-4个…这是一个等差数列。套用等差数列公式,算出时间复杂度约为O( n24 )。

当时在面试中,想再优化问题,在稿纸上已经画出了一个链表,然后找到中间结点断开,当时思路还是卡在断开后,后面那一段链表还是从头开始到后面找,如果这样时间复杂度当然也是减少了,也只是增大了分母,但还是 n2 的复杂度。后来回来睡觉就想到了,可惜当时没有想到。把后一段链表逆置,然后前后两个链表进行交叉合并,最后形成的链表就是目的链表。找到中间结点设置两个指针,一个一次步长一个两步长,走到链表尾部即可找到中间结点,链表逆置可以采用头插法,这里采用递归方法逆置。以下面链表为例:


这里写图片描述

ListNode op2(ListNode root) {
    if (root.next == null | root == null | root.next.next == null) return root;
    ListNode pointer, pointer2, root2;
    pointer = pointer2 = root;
    //先找到中间结点,断成两个链表
    while (pointer2.next != null) {
        pointer = pointer.next;
        pointer2 = pointer2.next;
        if (pointer2.next != null)
            pointer2 = pointer2.next;
    }
    root2 = pointer.next;
    pointer.next = null;
    //将后一半链表逆置
    root2 = inverse(root2);
    pointer = root;
    pointer2 = root2;
    ListNode tmp1, tmp2;
    while (pointer != null && pointer2 != null) {
        tmp1 = pointer.next;
        tmp2 = pointer2.next;
        pointer.next = pointer2;
        pointer = tmp1;
        pointer2.next = pointer;
        pointer2 = tmp2;
    }
    return root;
}
//逆置链表
ListNode inverse(ListNode root) {
    if (root.next == null | root == null) return root;
    ListNode head = inverse(root.next);
    root.next.next = root;
    root.next = null;
    return head;
}

复杂度:第一步找链表中间结点,需要遍历整个链表复杂度O( n ),第二步,逆置后一段链表,复杂度O(n2),交叉合并两个链表复杂度为O( n2 ),所以最后的时间复杂度为O( 2n )。

4.递归都可以用迭代完成么?
5.同步,异步,阻塞,非阻塞。概念没讲清楚。
6.面试官建议到算法呢,只有多刷题,校招时候得把基础课程都温习一遍。

xxhr面:

1.自我介绍。
2.项目介绍。
3.项目困难,怎么解决。
4.平时看什么书等。
5.职业规划。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值