分享|算法还是挺有用的
5146
2024.05.31
2024.05.31
发布于 中国

这里分享一下楼主最近面某大厂的经历,非常好玩(挺重视写代码的)

一面

前面的略过....
面试官:那我给你出一道题吧,你写一下
我:好
面试官:写一个堆排序吧,升序的
我:好的(内心是崩溃的,因为我已经开摆很久了,只记得小根堆的定义😭)
然后开始写了,发现竟然是个白板,只能自动补全括号。而且是写Java,平时全是回车,回车,回车...
这下更慌了...
写到一半
面试官:这个add函数是啥意思?

  • 我便解释了一下完全二叉树的定义(除以2是parent,乘以2是左儿子...),添加元素如果很小,应该得一直向上传

面试官:你的思路没问题
继续吭哧吭哧写,写得差不多了,一点调试运行,全是语法报错,类似int数组只写了int没写[]😣
这时面试官也在帮我找错,然后圈住一块,说:int rson = index << 1 | 1是什么意思?
我:左移1位之后最后一位一定是0,再或上1,等同于int rson = index * 2 + 1😎
面试官:原来是这样,这样虽然效率更高,但是可读性不太好😋
改完之后,一点运行,竟然对了!(不可思议)
面试官投来异样的眼光,说:我们对本科生的要求自然会低一些,你在本科生中算挺厉害的了(内心窃喜😝),我和领导反馈一下,待会儿跟你约下一次面试,你有什么想问的吗?
此处省略...(下面是现场写的代码)

import java.util.*;

public class Main {
    static class Heap {
        private final int capacity;
        private final int[] arr;
        private int length = 1;
        private final List<Integer> ret = new ArrayList<>();

        Heap(int capacity) {
            this.capacity = capacity;
            this.arr = new int[capacity + 1];
        }

        public void add(int x) {
            int index = length;
            arr[length++] = x;
            while (index != 1) {
                int fa = index >> 1;
                if (arr[fa] > x) {
                    swap(fa, index);
                }
                index >>= 1;
            }
        }

        public void sort() {
            for (int i = length - 1; i > 0; i--) {
                ret.add(arr[1]);
                swap(1, i);
                length--;
                heapify(1);
            }
        }

        private void swap(int i, int j) {
            int t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }

        private void heapify(int index) {
            if (index >= length) return;
            int lson = index << 1, rson = index << 1 | 1;
            if (lson < length && arr[lson] < arr[index]) {
                swap(lson, index);
                heapify(lson);
            }
            if (rson < length && arr[rson] < arr[index]) {
                swap(rson, index);
                heapify(rson);
            }
        }

        public void print() {
            for (int x : ret) {
                System.out.printf("%d ", x);
            }
        }
    }

    public static void main(String[] args) {
        int[] nums = new int[]{3, 8, 3, 1, 0, 10, 34, 2, 6, 1};
        int size = nums.length;
        Heap heap = new Heap(size);
        for (int x : nums) {
            heap.add(x);
        }
        heap.sort();
        heap.print();
    }
}

面试完之后,没几分钟,约下一次面试...
事后想了一下,应该按照优先队列那个类的写法,应该会更好一些(类似动态扩容,pop,poll,peek,size,isEmpty这些方法),当时比较慌,也就是想到什么写什么了。

二面

前面被狠狠拷打,略过...
此时已经感觉GG了,因为前面很多都答不上来...(一查,原来是高级技术专家)
面试官:给你一个稀疏矩阵,之后要查询对应坐标的值,应该怎么设计呢?
我:(想都没想,脱口而出)存个三元组,然后排序,查询就两次二分。
面试官好像不是很满意,此时还好想到了另一种方法
我:i和j应该都不会很大,可以i << 32 | j当做key存哈希表里
面试官这才觉得还行,然后说:给你出道题吧,一面面试官说你刷题很多,你估计也写过
他在白板上给我手动打字:3*4的矩阵,顺时针打印
我心想:这不螺旋矩阵嘛,好麻烦的题,有点小崩溃😢
好在十分钟左右写出来了,他也很认真的在看我代码,我给他讲了讲每个变量的含义
随后,面试官:你以后是要用手速解决问题呀🤣


第二天offer了,感谢这两个面试官😆

  • 手速还是很重要的,可以说明平时写代码比较多
  • 现场写也能看出来编码习惯,最好平时就把缩进和空格都规范点
评论 (21)