绝了!身边的都在作弊笔试,面试也可以作弊。。

文摘   2024-11-19 12:29   陕西  
绝了,最近听到一个让我血压飙升的事情——笔试、面试都能作弊?!🤯
身边还有人兴致勃勃地分享心得,说什么“别自己做,浪费时间”。兄弟,咱们考的难道不是同一个岗位吗?靠这种手段拿offer,真的不心虚吗?🙄
更扎心的是,我刷着某贴,看到一条评论直戳灵魂:“他的简历是假的,笔试是假的,面试是假的,但他的offer是真的。我的简历是真的,笔试是真的,面试也是真的,所以我的邮箱是空的。“

作为一名靠自己熬夜、掉发、敲代码杀出的程序员,我觉得这波作弊确实给“内卷”赋予了新高度。

大家辛苦刷题、背项目案例,结果可能斗不过开外挂的选手。
不过话说回来,这种竞争压力下,保持初心真的难。再怎么说,技能是真材实料,不是靠“假外包”能撑起来的。至于作弊的同学,拿到offer后第一周应该就会被现实打脸吧——毕竟写代码可是作弊不了的!💻

算法题:将数据流变为多个不相交区间

最近刷题的时候,碰到一个挺有意思的问题:怎么把数据流变成多个不相交的区间。看似简单,其实挺考验思路的。
题目是这样说的:给你一个整数数据流,每次插入一个新的数字后,要返回当前所有不相交区间的集合,区间需要按照起始值排序。举个例子:
  • 插入 1:结果是 [[1, 1]]
  • 插入 3:结果是 [[1, 1], [3, 3]]
  • 插入 2:结果是 [[1, 3]]
刚看到这儿,我脑袋嗡了一下,这不就是让程序员们变身区间管理员吗?一会儿合并区间,一会儿添加区间,操作像极了996后还得分身带娃的我。

解题思路

这个问题的关键在于如何高效地管理区间的增删改查。常规思路是用一个有序结构(比如 TreeSet)来存储这些区间。因为区间是有序的,我们可以借助二分查找快速定位需要处理的区间。每次插入新数字时,要做以下几步:
  1. 找到新数字左边和右边的最近区间;
  2. 判断新数字是否与左、右区间相连:
  • 如果可以与左区间相连,就扩展左区间;
  • 如果可以与右区间相连,就扩展右区间;
  • 如果左右都能连,就干脆把两边合并成一个区间;
  • 如果都连不上,自己单独成一个区间。
听起来有点绕对吧?别急,代码直接安排:
import java.util.*;

class SummaryRanges {
    private TreeSet<int[]> intervals;

    public SummaryRanges() {
        intervals = new TreeSet<>((a, b) -> Integer.compare(a[0], b[0]));
    }

    public void addNum(int value) {
        // 找到右边第一个区间
        int[] higher = intervals.ceiling(new int[]{value + 1, value + 1});
        // 找到左边第一个区间
        int[] lower = intervals.floor(new int[]{value, value});
        
        if (lower != null && lower[1] + 1 >= value) {
            // 和左区间相连
            lower[1] = Math.max(lower[1], value);
            if (higher != null && lower[1] + 1 >= higher[0]) {
                // 左右区间合并
                lower[1] = higher[1];
                intervals.remove(higher);
            }
        } else if (higher != null && higher[0] - 1 == value) {
            // 和右区间相连
            higher[0] = value;
        } else {
            // 新区间
            intervals.add(new int[]{value, value});
        }
    }

    public List<int[]> getIntervals() {
        return new ArrayList<>(intervals);
    }
}

代码解析

这个实现的核心就是 TreeSetceilingfloor 方法,用它们快速找到可能与新数字相邻的区间。至于为什么选 TreeSet 呢?因为它不仅有序,还支持高效的增删查操作,插入一个数字的时间复杂度是 (O(\log n))。对于数据流这种动态输入,效率特别重要。

使用示例

话不多说,直接来看这段代码的运行效果:
public static void main(String[] args) {
    SummaryRanges sr = new SummaryRanges();
    sr.addNum(1);
    System.out.println(sr.getIntervals()); // [[1, 1]]
    sr.addNum(3);
    System.out.println(sr.getIntervals()); // [[1, 1], [3, 3]]
    sr.addNum(2);
    System.out.println(sr.getIntervals()); // [[1, 3]]
}
运行这段代码,你会发现,区间管理就像动态拼图一样,每次插入一个数字后,区间会自动调整,真是一件令人“窒息”的优雅设计。
最后:如果把这段代码用在高并发环境下呢?不敢想象程序员们为了线程安全会摔多少键盘💻。

好了,这道题的分享就到这儿,你觉得还能优化吗?欢迎来聊聊

-END-


ok,今天先说到这,老规矩,给大家分享一份不错的副业资料,感兴趣的同学找我领取。

以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言

程序员老鬼
10年+老程序员,专注于AI知识普及,已打造多门AI课程,本号主要分享国内AI工具、AI绘画提示词、Chat教程、AI换脸、Chat中文指令、Sora教程等,帮助读者解决AI工具使用疑难问题。
 最新文章