在大厂,一位年薪300W的P9告诉我,领导最烦这种下属,哪怕技术再牛逼,也不会给晋升机会。
刚看到个贴子,说在大厂,一个年薪300万的P9吐槽,领导最烦那种只会埋头干活、技术再牛也不懂“配合”的下属。
这话挺现实的。 我觉得这事吧,不是贬低技术,而是提醒你:职场不是实验室,光靠实力不够,还得懂人情和氛围。
有网友说“我就做事,不拍马”,听着硬气,但真相是,职场规则从来就不只是技术逻辑,还有权力逻辑。 领导用人讲的是信任和风险控制,你再能干但不好沟通、不愿配合,他也不敢提你上去。
毕竟团队需要的是整体协作,不是个人英雄。 说到底,晋升靠技术起家,但靠关系稳住。会干事的人是骨架,会做人的是血肉。
只有两者兼得,才能在大厂不被边缘化。【备注:文末可领最新资料】
面试题:把三角形染成红色
昨天晚上十一点多,我在公司楼下吃碗夜宵,手机一震,有个同学问我一句特别抽象的话: “哥,我有个算法题,怎么把三角形染成红色?” 我当时一愣,这不就是我们平时画图、游戏里那种给三角形填颜色嘛,用程序干一遍就行。
你可以先脑补一下场景:有一块像素画布,是一个二维网格,比如 100×100,每个小格子就是一个像素。现在给你三角形的三个顶点坐标 (x1, y1)、(x2, y2)、(x3, y3),要求你写个 Python 函数,把这个三角形内部的像素都“刷成红色”。题目说的“染成红色”,本质就是:判断哪些点在三角形里面,然后标记一下。
我一般会这么干,分三步,思路一点都不花哨。
第一步,先把搜索范围缩小,不要傻乎乎地遍历整张图。 最简单的方法是算一个“包围盒”,也就是这个三角形最小能装下它的矩形:min_x = 三个点的 x 最小值,max_x = 最大值,y 也是一样。 那只要在这个矩形里挨个点去判断就行了,外面的点肯定不可能在三角形里,对吧,这一步省了不少无用计算。
第二步,核心:判断一个点在不在三角形里面。 这个地方刚工作那会儿我还挺懵的,直到后来写游戏 UI 才真正记住。
有一个特别好用、又好理解的方法,叫“同侧性”,不用记名字,你就记一个感觉: 三角形有三条边,每一条边把平面分成了两半,你站在三角形的三个顶点那里看,三角形内部的点,总是跟第三个顶点在每条边的同一侧。
翻译成计算就是:用向量叉积看“朝向”是不是一致。 假设三角形三个顶点是 A、B、C,要判断某个点 P 在不在里面,做这么几步:
看 P 和 C 在边 AB 的哪一侧。 看 P 和 A 在边 BC 的哪一侧。 看 P 和 B 在边 CA 的哪一侧。
如果这三个“朝向”的符号都一致(要么全是正,要么全是负,还可以允许等于 0 表示在边上),那 P 就在三角形内部或者边上;只要有一个反着的,就在外面。
这个“朝向”怎么算呢?就是二维向量叉积的符号:
defcross_z(p1, p2, p3):
# 计算 (p2 - p1) × (p3 - p1) 的 z 分量
return (p2[0] - p1[0]) * (p3[1] - p1[1]) - (p2[1] - p1[1]) * (p3[0] - p1[0])
结果 > 0 代表在一侧,< 0 在另一侧,= 0 刚好在一条直线上。 这玩意儿听起来有点数学味道,但你就把它当成“朝左”/“朝右”的判断开关就好了。
第三步,套一层循环,把该染红的点全找出来。 这里我不用真正的图片库,直接用一个二维数组模拟画布,用字符打印出来,看个效果就行。Python 伪代码大概是这样:
defpoint_in_triangle(p, a, b, c):
# 用叉积判断 p 是否在三角形 abc 内部(含边界)
c1 = cross_z(a, b, p)
c2 = cross_z(b, c, p)
c3 = cross_z(c, a, p)
has_neg = (c1 < 0) or (c2 < 0) or (c3 < 0)
has_pos = (c1 > 0) or (c2 > 0) or (c3 > 0)
# 既有正又有负,说明不在同一侧,点在三角形外
returnnot (has_neg and has_pos)
defpaint_triangle_red(width, height, a, b, c):
# 创建一张“画布”,用 '.' 表示没染色,用 'R' 表示红色
canvas = [['.'for _ in range(width)] for _ in range(height)]
# 计算包围盒,限制遍历范围
min_x = max(0, int(min(a[0], b[0], c[0])))
max_x = min(width - 1, int(max(a[0], b[0], c[0])))
min_y = max(0, int(min(a[1], b[1], c[1])))
max_y = min(height - 1, int(max(a[1], b[1], c[1])))
# 遍历包围盒里的每一个像素
for y in range(min_y, max_y + 1):
for x in range(min_x, max_x + 1):
# 用像素中心点来判断,稍微精准一点
px = x + 0.5
py = y + 0.5
if point_in_triangle((px, py), a, b, c):
canvas[y][x] = 'R'
return canvas
if __name__ == "__main__":
# 随便造一个三角形
A = (2, 2)
B = (15, 3)
C = (5, 10)
img = paint_triangle_red(20, 15, A, B, C)
# 打印看看效果,注意 y 是从上到下
for row in img:
print(''.join(row))
跑一下你就会看到终端里有一块“红色”三角形(当然我们用的是字母 R,将就一下)。游戏引擎底层画三角形,其实思路也就差不多,只不过人家会做得更极致,比如用整数运算、预计算边函数、做插值渲染等等。
顺带说一句,这个算法的时间复杂度大概是 O(W×H),W、H 是三角形包围盒的宽和高。 一般小图、UI 按钮这种大小,完全够用;如果你要染一整个 4K 屏幕上密密麻麻的很多三角形,就可以再往前走一步,搞“扫描线算法”:按一行一行 y 扫过去,每一行只算左右两边的交点,中间一整段像素直接填红,比逐点判断更省。
但对于“面试/刷题”层面的“把三角形染成红色”,上面这一版已经相当实用了: 输入三个点坐标,算包围盒,循环里用叉积判断,在画布上标成红色,就这么简单。 我刚才敲到这儿肚子又饿了,等会儿去弄杯奶茶,你要是想顺便扩展成“支持任意颜色、多边形填充”那一套,也可以在这个代码上继续改着玩。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领