海康威视员工爆料:HR找我谈话,说不要没有经验的员工,让我要不就转外包公司,要不就直接拿N走人。。

科技   2024-11-17 14:08   山西  
今天看了个让人有点想笑又想哭的爆料,简直刷新了我的认知。

事情是这样的:海康威视的一位员工分享了自己和HR的对话,说HR直接给他来了一句“要么转外包公司,要么直接拿N走人”,原因是他没什么经验。🤦‍♂️
作为一名程序员,经历过无数面试和岗位调整,确实能理解公司的压力。但老实说,这种“劝退”方式有点过于直白了吧?不禁想问:“早干嘛了?”人才不是随便可以被当作棋子丢掉的。
你要有人才需求,为什么不提前规划?提前招聘,搞个有效的培训和培养机制呢?每个员工都不是天生就懂业务、懂技术的,没经验是可以慢慢积累的啊。毕竟,我们刚开始的时候都是从“菜鸟”一步步成长起来的,哪里来那么多“经验”呢?
人毕竟不是机器人,想要人才,得先给足机会和信任,才能够有更好的发展。不然,公司未来能有什么“核心竞争力”呢?

算法题:数据流的中位数

聊一个有点意思的算法问题:数据流的中位数

题目分析

问题描述大致是这样的:
我们要从一个不断增加的数字流中实时求出当前的中位数。也就是说,假设我们有一个数字流 nums = [1, 5, 3, 4, 2],那么在流的每个时刻,我们都要能快速计算出当前中位数。
你可以注意到几个要点:
  1. 每次接收一个新的数字;
  2. 求出当前所有数字的中位数;
  3. 要求这个操作尽可能高效,不然你就得不停排序,效率堪忧。

直觉法:排序求中位数

首先,我们可以从最简单的解法开始,拿 Python 自带的 sort() 来搞定。我们每次接收到一个新的数字,都把当前数字加入数组,然后排序数组,最后取数组的中位数。
代码大概是这样:
import bisect

class MedianFinder:
    def __init__(self):
        self.nums = []

    def addNum(self, num: int) -> None:
        bisect.insort(self.nums, num)

    def findMedian(self) -> float:
        n = len(self.nums)
        if n % 2 == 1:
            return self.nums[n // 2]
        else:
            return (self.nums[n // 2 - 1] + self.nums[n // 2]) / 2.0
在这段代码里,addNum 方法通过 bisect.insort 将新的数字插入到已有列表中,保证了列表始终是有序的。然后 findMedian 方法直接根据列表的长度来判断中位数是列表的中间元素还是中间两个元素的平均值。这里的 bisect.insort 是一个二分查找插入方法,时间复杂度为 O(log n),比直接用 sort() 排序要高效一些。
但即便如此,每次插入都要花费 O(log n) 的时间,算下来,性能上还是不够理想,尤其是当数据流中数字越来越多时。

高效解法:堆结构

接下来,咱们得讲讲如何通过堆来解决这个问题。堆(Heap)是个很有意思的数据结构,它能帮助我们快速找到最大值和最小值,正是基于这个特性,我们可以用两个堆来巧妙地解决问题。
具体的做法是:我们维护两个堆,一个最大堆用于存储较小的一半元素,另一个最小堆用于存储较大的一半元素。这样的话:
  • 最大堆的堆顶元素是当前小部分中的最大值;
  • 最小堆的堆顶元素是当前大部分中的最小值;
  • 中位数要么是最大堆的堆顶元素(当元素个数是奇数时),要么是最大堆和最小堆堆顶元素的平均值(当元素个数是偶数时)。
用 Python 的 heapq 模块来实现时,heapq 默认是最小堆,因此我们需要把最大堆模拟成负数的最小堆。
下面是代码实现:
import heapq

class MedianFinder:
    def __init__(self):
        # 最大堆(小部分)
        self.max_heap = []  
        # 最小堆(大部分)
        self.min_heap = []

    def addNum(self, num: int) -> None:
        # 先把数字放到合适的堆里
        if len(self.max_heap) == 0 or num <= -self.max_heap[0]:
            heapq.heappush(self.max_heap, -num)  # 使用负数模拟最大堆
        else:
            heapq.heappush(self.min_heap, num)
        
        # 保证最大堆和最小堆的元素个数平衡
        if len(self.max_heap) > len(self.min_heap) + 1:
            heapq.heappush(self.min_heap, -heapq.heappop(self.max_heap))
        if len(self.min_heap) > len(self.max_heap):
            heapq.heappush(self.max_heap, -heapq.heappop(self.min_heap))

    def findMedian(self) -> float:
        if len(self.max_heap) > len(self.min_heap):
            return -self.max_heap[0]
        else:
            return (-self.max_heap[0] + self.min_heap[0]) / 2.0

讲解代码

  1. 初始化:我们用两个堆来维护数据流的两部分,max_heap 存储较小的一半数据(其实存的是负数,模拟成最大堆),min_heap 存储较大的一半数据。
  2. 添加数字:每次添加数字时,我们根据数字的大小决定放入哪个堆。如果数字小于等于最大堆的堆顶(记得是负数),就放到最大堆;否则就放到最小堆。
  3. 平衡堆:每次插入完数字后,我们要确保两个堆的大小平衡。最大堆的大小不能超过最小堆太多,最小堆的大小不能超过最大堆。
  4. 查找中位数:当最大堆的元素个数比最小堆多时,中位数就是最大堆的堆顶元素;如果两个堆的大小相等,中位数就是两个堆顶元素的平均值。

总结

通过这种堆结构的方式,我们可以在 O(log n) 的时间复杂度内完成每次数字的插入操作,而中位数的查找则可以在 O(1) 的时间内完成。
这样,相比于排序法的 O(n log n),堆的解法无疑要高效得多,尤其是在数据流很大的情况下,能够显著提高性能。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
🔥虎哥私藏精品 热门推荐🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》

资料包含了《IDEA视频教程》《最全python面试题库》《最全项目实战源码及视频》《毕业设计系统源码》,总量高达650GB全部免费领取

Python技术迷
回复:python,领取Python面试题。分享AI编程,AI工具,Python技术栈,Python教程,Python编程视频,Pycharm项目,Python爬虫,Python数据分析,Python核心技术,Python量化交易。
 最新文章