程序员老鬼

给13k的候选人开25k薪资,结果人家反手要30k,说低于这个数不去。家人们谁懂啊,候选人的薪资底气在哪?

刚看到个贴子,说一家公司给候选人预估13k,结果正式开25k,人家直接回一句:没30k我不去。HR懵了:这薪资预期到底怎么算的?底气哪儿来的?
我的看法是:薪资预期,本质上是“自认价值 + 市场行情 + 备胎数量”。你要么真有稀缺技能,要么手里同时有好几家offer,要么对方业务太着急,这些都能成为30k的底气。如果只是心气高、没结果,那就是给自己加戏。 从企业角度看,他给你从13k拉到25k,本身就说明预算区间比你想的宽得多;从候选人角度,该谈就谈,不合适就礼貌拒绝,不需要互相骂。

面 试 题 :托普利茨矩阵

昨晚大概十一点多,我在公司楼下等外卖,旁边我们组那个小李突然问我一句:哥,面试老爱问什么托什么矩阵的,是不是托普利茨?我当时手机一塞口袋,就跟他讲了半天。干脆按当时的说法给你复刻一遍。 托普利茨矩阵是个啥 你先想象一个二维数组 matrix ,有 m 行 n 列。托普利茨矩阵的要求特别简单粗暴:
从左上到右下,每一条斜线上的数字都得是一样的。
比如这个就是托普利茨矩阵:
1 2 3 4
5 1 2 3
9 5 1 2
你看左上那条对角线: 1,1,1 ;从 2 开始那条: 2,2,2 ;从 3 开始那条: 3,3 ……每条“ ↘ ”方向的斜线都是同一个数字,这就过关了。 反例来一个:
1 2 3
4 1 9
7 4 1
看中间那条从 2 开始的对角线: 2,1 ,不一样,立马判死刑:不是托普利茨。 说白了,就是 对角线不能“变脸” ,一条线到底。 怎么判断一个矩阵是不是托普利茨 当时小李第一反应是:要不要把每条对角线都单独拿出来存一下?我说那也能做,但没必要。 其实有一个特别顺手的思路:
只要保证所有位置 (i, j) 的值,跟它左上角 (i - 1, j - 1) 是一样的,就一定是托普利茨。
为啥这么说?因为“左上角”连着的,就是那条对角线。你只要保证每个格子都跟它的“上代”一样,这条对角线就全都一样了。 所以伪逻辑就两行:
  • 从第二行、第二列开始遍历整个矩阵;
  • 对每个 matrix[i][j] ,判断一下 matrix[i][j] == matrix[i - 1][j - 1] 吗?不等就直接返回 false 。
遍历完没出问题,那就是 true 。 时间复杂度:每个元素最多看一眼,就是 O(m * n) 。 空间复杂度:只用到常数级变量, O(1) ,一点也不占地方。 用 Java 写出来长啥样 我当时就直接给小李在手机备忘录里敲了一版,你可以直接拿去用:
public class ToeplitzMatrixChecker {

    /**
     * 判断一个矩阵是否为托普利茨矩阵
     * 规则:matrix[i][j] == matrix[i - 1][j - 1] 对所有 i>0, j>0 都要成立
     */
    public static boolean isToeplitzMatrix(int[][] matrix) {
        // 防御性判断,面试手撕一般也可以省略
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            returntrue; // 看成“空矩阵是合法的”
        }

        int rows = matrix.length;
        int cols = matrix[0].length;

        // 从第 1 行、第 1 列开始(下标从 0,实际是第二行第二列)
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < cols; j++) {
                if (matrix[i][j] != matrix[i - 1][j - 1]) {
                    returnfalse;
                }
            }
        }

        returntrue;
    }

    // 简单测一测
    public static void main(String[] args) {
        int[][] a = {
                {1, 2, 3, 4},
                {5, 1, 2, 3},
                {9, 5, 1, 2}
        };

        int[][] b = {
                {1, 2, 3},
                {4, 1, 9},
                {7, 4, 1}
        };

        System.out.println(isToeplitzMatrix(a)); // true
        System.out.println(isToeplitzMatrix(b)); // false
    }
}
这个版本就是最常规、最干净的写法,面试时候在纸上也能快速写出来。 几个顺嘴要提的小细节 那天小李还追问了几个点,我顺便也说下:
  1. 边界情况怎么处理?
    • 一行或者一列的矩阵,比如 1xN 或 Nx1 ,肯定是托普利茨,因为压根没有“斜线”可以出问题。
    • 代码里其实已经兼容了,因为循环是从 i = 1, j = 1 开始的,这种情况循环根本进不去,直接返回 true 。
  2. 如果矩阵特别大,只能一行一行从磁盘读怎么办? 这种场景就不能一次性把整个二维数组读进内存了,可以换一种写法:
    • 只保存“上一行”,再读当前行时,只要比较 currRow[j] 和 prevRow[j - 1] 就够了。 逻辑和上面是一模一样的,只是把二维数组“拍扁”成一行一行的流来处理,空间还是 O(n) 。
给你一个简单的思路版伪代码(就不写完整 Java 了):
int[] prev = null;
while ((curr = readNextRow()) != null) {
    if (prev != null) {
        for (int j = 1; j < curr.length; j++) {
            if (curr[j] != prev[j - 1]) {
                return false;
            }
        }
    }
    prev = curr;
}
return true;
  1. 常见坑 有人会写成“从第一行、第一列开始”然后访问 matrix[i - 1][j - 1] ,结果 i = 0 或 j = 0 时直接数组越界,这个在白板上很容易被面试官逮住。习惯上就从 i = 1, j = 1 起步,就干干净净。
差不多就这些。当时外卖刚好送到,小李说这题面试再碰到就不虚了。你要是有兴趣,可以自己扩展一下,比如把这个方法封装进工具类,用在你们项目里做数据校验啥的,也挺顺手的。 -END -
我为大家打造了一份RPA教程, 完全免费: songshuhezi.com/rpa.html 最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领,也可以链 接我微信: hls404