Python技术迷

同等能力下,其实就差在一张985文凭上,有文凭的就可以拿50w年薪,高中毕业的就是只能 5w年薪拿着。。

最近我刷到个吐槽:同样能写代码、同样能扛需求,面试聊得飞起,最后卡在一张“985纸片”上。

Image

网友说得更扎心:有那张文凭的,开口就是50w年薪;高中毕业的,再能干也像被系统限流,工资条常年5w,还得自带“吃苦耐劳”Buff。

我觉得最难受的是,你明明能把bug修得漂漂亮亮,却要先证明自己“配得上”被看见。真想给招聘系统提个PR:多跑几次真实项目的压力测试,把“纸面参数”权重调低点,让会干活的人少走点弯路。

最后受益的其实是公司,招到能打的,比招到好看的更省心。

算法题:用栈实现队列

昨天不是加班嘛…就是那种,晚上十点多,群里有人突然甩一句:哥,算法题又来了,“用栈实现队列”…我当时脑子一激灵,哎这玩意儿在业务里还真遇到过类似的,像你们做日志上报、消息缓冲那种,表面看是 queue,底下为了省事儿拿 list 当栈,最后就变成“两栈一队列”了,对吧。

思路其实很土,但是好用:准备两个栈,一个我叫 in_stack,一个叫 out_stack。入队的时候,别想太多,直接往 in_stack 里压。出队的时候才关键:如果 out_stack 里有东西,直接 pop;如果 out_stack 空了,那就把 in_stack 里所有元素一个个 pop 出来,再 push 到 out_stack 里——这一倒腾,顺序就反过来了,最早进去的就跑到 out_stack 顶上了,然后再 pop 就是队列的出队。

你看起来像是每次都在搬家很累,其实摊到每个元素身上,最多被搬一次(从 in 搬到 out),所以平均下来还是挺香的,反正面试官爱听“均摊 O(1)”这几个字,哈哈。

直接上 Python 代码,我自己平时就这么写,带点防呆:

classMyQueue:
def__init__(self):
# 用 list 当栈
        self._in = []
        self._out = []

defpush(self, x: int) -> None:
# 入队:进栈 in
        self._in.append(x)

def_move_if_needed(self) -> None:
# out 空了才搬运,避免反复搬
ifnot self._out:
while self._in:
                self._out.append(self._in.pop())

defpop(self) -> int:
# 出队
        self._move_if_needed()
ifnot self._out:
raise IndexError("pop from empty queue")
return self._out.pop()

defpeek(self) -> int:
# 看队头
        self._move_if_needed()
ifnot self._out:
raise IndexError("peek from empty queue")
return self._out[-1]

defempty(self) -> bool:
returnnot self._in andnot self._out


if __name__ == "__main__":
    q = MyQueue()
    q.push(1)
    q.push(2)
    q.push(3)
    print(q.peek())   # 1
    print(q.pop())    # 1
    q.push(4)
    print(q.pop())    # 2
    print(q.pop())    # 3
    print(q.pop())    # 4
    print(q.empty())  # True

我以前还犯过一个小坑…就是每次 pop 都把 in 全倒过去,结果你连续 peek、peek、peek,疯狂搬家,CPU 风扇都要起飞了。上面这个 _move_if_needed() 就是专门治这个的:out 里只要还有货,就别动 in,让它慢慢攒着。

对了还有个小细节,你们如果做题平台那种,pop/peek 空队列到底是抛异常还是返回啥,看题目要求来,有些要返回 -1,有些要你保证不会空调用。反正我写业务代码,宁愿抛错也不想默默吞掉,后面排查日志要命…哎说到日志,我先不扯远了,要不然又被人说我水群了。