某程序员自爆:两个工作机会,一个是大厂自研月薪21K,一个是外包27K,外包工作更舒服,该怎么选?
刚看到个贴子,说一程序员纠结:大厂自研月薪21K,但加班多;外包27K,活轻松。到底该怎么选?网友们吵翻了,有的说“选钱”,有的说“选未来”。
我觉得这事吧,关键得看你现在缺什么。要是你刚起步、想积累技术,那大厂的经验值确实值钱,哪怕累点,含金量高;但要是你阶段性想“喘口气”或者家庭压力大,那选外包也没问题。毕竟,工资多六千,能让你生活质量上个台阶。
不过话说回来,大厂不是永远的金身,外包也不等于废。你能不能持续提升,才是决定“下一个选择权”的根本。很多人纠结选哪个,其实是想两头都要,但职场从来没有完美选项,只有清楚取舍的人。【备注:文末可领最新资料】
面试题:扫地机器人
昨晚十一点多,在公司楼下啃着还没凉透的煎饼,我家扫地机器人又被地毯边卡住了…唉,正好有人在群里问“扫地机器人这题怎么设计算法比较靠谱?”,我把这两天撸的思路用大白话说一下,别太玄乎,能跑就行,慢慢再迭代。
想象成一个网格地图:0 是可走、1 是障碍;有个起点(通常是充电座)。目标很朴素——把所有“能到”的格子都踩一遍,最好别反复绕圈,电快没了还能自己回家。现实里有激光/视觉建图啥的,但面试/刷题版本就当网格。
核心思路:先全覆盖,再别走丢
我用的套路是“图遍历 + 简单路径规划”:
覆盖:用 DFS/BFS 把所有可达格子都标记干净。为了让机器人真的“走”过去,而不是只在脑子里“访问”,每次从 A 走到 B,都用一条最短路(BFS/A*)把动作补全。 回充:随时估算“回家最短路长度”,如果电量不太够(<= 回家路 + 安全余量),立刻返航,充好再继续。 避障和顺序:邻居按固定顺序(上右下左)尝试,这相当于“右手贴墙”那种朴素策略,简单、稳定,不追求全局最优,但基本不会漏。
为啥不直接“割地牛耕”?
最优覆盖(比如分解成条带、最少转弯)在有障碍的情况下,容易变得复杂(接近旅行商/最短覆盖路径的味道)。面试场景先把正确性兜住:全覆盖 + 能回家。要效率,再在“访问顺序”和“分区策略(连通块里走 Z 字)”上细抠。
两个细节,坑别踩
转弯成本:真机上转弯比直行费电,能“顺着方向”多走就多走,邻居顺序里优先当前朝向那一侧,会明显更顺滑(下面代码里留了钩子)。 回家余量:别卡在只差一格电的地方。经验法: 余量 = max(10, 地图对角线长度/4),粗糙但好使。
复杂度脑子里有数
单次最短路 BFS 是 O(HW),最坏每走一步都 BFS,路径长度 L 时是 O(LHW)。刷题规模不大完全能扛;真机就要上分区+增量地图。
Python 小示例(可直接跑)
from collections import deque
# 0 可走,1 障碍
grid = [
[0,0,0,1,0],
[0,1,0,1,0],
[0,0,0,0,0],
[1,0,1,0,1],
[0,0,0,0,0],
]
H, W = len(grid), len(grid[0])
start = (0, 0) # 充电座
battery = 200# 简化的电量单位:走一步-1,转弯不单算
SAFE_MARGIN = max(10, (H+W)//4)
dirs = [(-1,0),(0,1),(1,0),(0,-1)] # 上右下左
definb(r,c):return0<=r<H and0<=c<W and grid[r][c]==0
defbfs_path(src, dst):
""" 网格最短路,返回包含 src/dst 的路径列表;不可达则空 """
if src == dst: return [src]
q = deque([src])
parent = {src: None}
while q:
r,c = q.popleft()
for dr,dc in dirs:
nr,nc = r+dr, c+dc
if inb(nr,nc) and (nr,nc) notin parent:
parent[(nr,nc)] = (r,c)
if (nr,nc) == dst:
# 回溯
path = [(nr,nc)]
cur = (r,c)
while cur:
path.append(cur)
cur = parent[cur]
return list(reversed(path))
q.append((nr,nc))
return []
defmanhattan(a,b):return abs(a[0]-b[0]) + abs(a[1]-b[1])
# 预计算“可达全集”
defreachable_from(s):
vis, q = set([s]), deque([s])
while q:
r,c = q.popleft()
for dr,dc in dirs:
nr,nc = r+dr,c+dc
if inb(nr,nc) and (nr,nc) notin vis:
vis.add((nr,nc)); q.append((nr,nc))
return vis
all_reach = reachable_from(start)
defplan():
global battery
cleaned = set()
pos = start
route = [pos]
while len(cleaned) < len(all_reach):
cleaned.add(pos)
# 电量不够就回充
to_home = bfs_path(pos, start)
ifnot to_home: break# 理论上不会
if battery <= len(to_home) + SAFE_MARGIN:
route += to_home[1:]
battery -= (len(to_home)-1)
pos = start
# 充满(简化)
battery = 200
# 找最近的未清洁格(按曼哈顿挑个候选,再 BFS 得真实路)
candidates = [p for p in all_reach if p notin cleaned]
ifnot candidates: break
target = min(candidates, key=lambda p: manhattan(pos, p))
path = bfs_path(pos, target)
ifnot path: # 保险
# 找其他候选
found = False
for p in sorted(candidates, key=lambda x: manhattan(pos,x)):
path = bfs_path(pos, p)
if path: found=True; break
ifnot found: break
# 沿最短路前进并“清洁”
for cell in path[1:]:
route.append(cell)
battery -= 1
pos = cell
cleaned.add(pos)
# 最后回家
if pos != start:
back = bfs_path(pos, start)
route += back[1:]
return route, len(cleaned)
route, cnt = plan()
print("覆盖格子数:", cnt, "总步数:", len(route)-1, "最终电量:", battery)
# 想看轨迹就 print(route)
这段代码不追求最优步数,但有三件事能保证:能全覆盖、能躲障碍、能回家。你要进一步“像人一样聪明地绕最少的弯”,就把“下一目标”的选择,从“最近一个未清洁”升级成“分区后的 Z 字覆盖 + 分区之间用 A* 连接”,再加个“优先当前朝向”的打分器,体验会好不少。
我先去把地毯边贴个磁条…回头你要真机数据(回转半径、转弯耗电曲线)咱再把电量模型换成更像样的。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领