大家好,我是《Flutter开发实战详解》的作者郭树煜,掘金 id 恋猫de小郭 ,今天前三位分享的都是姓张的大佬,就我姓郭混迹其中,感觉压力山大啊~
如标题所示,今天和大家分享的内容是程序员的职场晋升与对抗,从标题可以看出来今天我要分享的是一个“漂亮话”,大家多多包涵,也希望可以帮助到大家。
一、对抗焦虑
为什么会聊这个话题,因为在互联网大规模红利期已经过去的现在,各种“内卷”在我们身边随处可见,而这样的大环境下,大家都在卷着活下去了,谁还考虑什么职业晋升发展?
就比如这次的 1024 游戏活动,真卷起来,别人一次挖的分数都比你瓜分的多10倍,相信大家都有所体会。
所以对抗焦虑是如今的必修课,要对抗焦虑,那首先就要找到焦虑的来源,关于焦虑的来源,我这里主要总结为以下三点:
1.1、自媒体带来焦虑
自媒体渲染焦虑相信是大家最常见的,也是最容易分辨的,这类“焦虑魔法”因为被用得太多,所以大家开始有了抗性,一般都是通过:
- “别人的高薪”;
- “某某技术要凉”
- “某某框架必火”
通过对比和带节奏来制造的恐慌,而随着这个套路的滥用,虽然大家已经开始免疫,但是 “蚂蚁咬大象”,这类内容接触多了,不自觉中潜在的焦虑情绪还是会被一点点累积。
应付这些焦虑其实很简单,就学会分辨内容的可信程度,比如:
多思考内容意义,这边文章看完之后我是学到了什么?还是单纯看完看完很不开心?因为有很多文章的风向内容可能是:
- “我为什么选择xxxx”
- ”我为什么放弃xxxx“
- ”凭借着xxxx我得到了大厂Offer“
这里不是说这些文章或者软文不好,而且先区分文章的立场,因为如果作为软文,那么的立场一般都是较为极端,需要对结论和数据做一些判断和甄别。
这些文章一般是输出自己的观点的内容,所以可能会带上”私货“,这并没有什么问题,但是作为读者,我们应该去判断文章的观点是否贴近事实,特别是提高对数据和现实的敏感度,自己多做一些甄别,比如:
在 Flutter 被狂吹的那段时间,我对于 RN 、Weex 和 Flutter 的在大厂中的使用情况产生了一些好奇,所以我就自己动手统计出了一个份数据,虽然它不一定完全实时和准确,但是在之后当我看到某些文章中所有说的一些数据时,我就可以根据自己的经验去分辨它的可靠性有多高。
今年也更新了一份新的数据统计 : 《国内大厂应用在移动端 Flutter 框架使用分析》
所以提高自己的信息量和数据敏感是有效对抗媒体焦虑的一个好办法,通过数据交流,用事实说话。
1.2、不确定带来焦虑
关于这个问题让我想起了一段话:"人越是没安全感,就越追求确定性的东西,但是生活的不可确定性本来就很多,所以就越来越焦虑。"
其实在成长的过程中,我们确实很希望追求确定性的结果,比如:
- 某某框架是不是要凉了,值不值得学; - 学 Go 是不是工资会比 Java 多一些吗; - 做算法是不是就不会那么内卷;
追求高回报高红利的技术学习没错,因为投入产出比越高肯定越好,但是往往在过度等待中去追求性价比,很容易就陷入焦虑的漩涡,因为你一直处于等待状态。
因为不确定而观望,因为观望导致焦虑一点一点累积。
所以针对成长过程中的不确定性带来的焦虑,我个人比较推荐从当前你确定的部分去努力:
与其在纠结 Compose 和 Flutter 之间学哪个好?不如就选其中一个先学下去,它也许性价比不是最高的,但是绝对是有帮助的。
想要避免因为不确定带来的焦虑,那就先动起手来,等万事俱备,往往你想要的最好状态和最佳收益,但结局就像股市一样不尽如意。
所以接受局限性,接受不确定性是对抗不确定性焦虑的关键,每个阶段的成长都需要面对各种不确定性。所以在踌躇不前而感觉惶恐时,那就先让自己动起手来,把学 React Native 还是 Flutter , 变成先学了 React Native 再说。
那有人说,我就是不知道该学哪个怎么办?
对于选择困难症的问题我是没什么办法,但是从我个人经验出发,学一个东西并不是等待万事具备之后去开始的。
因为根据我的历史经验,每当我定义一个目标,比如:
“我有一个想法,等到周末一定要把输出为写一篇文章”
然后到了周末就没有然后了,所以现在当我有一个想法的时候,我会马上先记录下载,然后先动手开始把粗略的内容写下来,这样才有可能完成我想要的目标。
回到不确定性的问题上,虽然技术的更新确实很快,但是有些规模的技术在市场上其实不是突然消亡,因为历史迭代是一个漫长的过程,你看 Weex 也通过 uni-app 存在至今,就算有了 Flutter 但是在很多场景上 React Native 明显就更有优势,比如 code-push 。
并且技术的迭代也不是断层的,往往上一个技术给你带来的经验和总结,对下一个技术都有一定程度的帮助,比如 Flutter 和 Compose 之间的相辅相成,所以动手时解决不确定性焦虑的关键,因为你的焦虑很大程度时因为在原地踏步。
1.3、努力带来的焦虑
是的,努力也会带来焦虑,因为努力不一定马上能看得到结果或者回报,因为反馈的时间,也需要累积。
为什么赌博会上瘾,因为赌博带来的反馈很快,你的每个选择马上就有结果,但是赌博好吗?显而易见并不好。
虽然学技能是跟着招聘走,但是职业生涯的晋升不单单只是追风口:
因为如果每项技能都是浮于表层的学习,那后面就会越学越累,越努力越觉得幸苦,因为你永远在不同的队伍里反复横跳,这就像是在排队一样!
我印象比较深的一句话是:“人们往往高估了短期的回报,低估了长期的收益”,其实成长和晋升都不是一两天或者一两周能完成的,需要的是长时间的学习和经验,自然而然就形成了能力的壁垒,这个过程是持续性的。
那成长路上对抗努力带来的焦虑,我的做法就是降低预期,比如今天我想学会 React Fiber :
- 那么今天我就先知道 React Fiber 是什么;
- 明天有时间就看看 React Fiber 在 React 16 和 React 17 我需要做什么变动;
- 下星期有时间做一个例子去尝试这些改变;
- 下个月或者可以思考 React 为什么不用 Vue 3.0 的动静结合;
- 再有时间就继续深入理解 React Fiber 通过什么模型和方式对底层进行了优化。
这个过程我们不需要精心策划和等待,马上就可以在任意摸鱼时间动起手来:
- 不要求快
- 不要求深
只要求降低目标,有持续性的学习,让自己的每个行为都能产生反馈,慢慢让自己沉浸进去,所以以慢打快,以远打近是我对于“内卷”下成长的一些总结,给自己更多的思考空间,更快乐的编程生活。
你不是在和同事内卷,比谁更快,而是在比持续性的输出~
所以总结起来:对抗焦虑其实就是一个修心的过程!
- 增加自己的信息量;
- 让自己多动起来;
- 给自己收获反馈的时间和可持续的动力;
当然,听了那么多鸡汤废话,接下来讲讲该怎么做。
二、自我提升
工作是靠劳动换取等价报酬,而只有在这期间有新的收获,才是真正赚到的过程。
2.1、区分努力和重复劳动
在互联网行业,一直有鼓吹“狼性”文化的传统,但是往往这种“狼性”的努力,最后反而可能是摧毁了自己晋升的路,因为很多时候只是看起来像是在努力。
区分“努力”和“重复劳动”是很重要的能力!
如果你发现每天的工作都是在:
- 调大小;
- 改色差;
- 调排版;
- 开会改昨天的需求;
- 扯皮需求是前端实现还是后端实现;
- 这是个 bug 还是 as design;
那这不叫进步,这只是在用你的时间换取对应的报酬,因为选择有挑战性的工作和选择有挑战性的体力工作是两回事。
长时间的重复性和无意义工作除了显得很忙,其实并没有其他太多的作用,比如:
- 习得如何快速进行字体大小和颜色修改, - 能通过5种方式实现五彩斑斓的黑
对职业能力的提升其实并不大,但是却会耗费你大量的时间,而好的工作岗位是能够有专业和正确的反馈,并且具备一定的挑战性,举一个例子:
Supernova 这工具不知道你们了解过没有,它是把设计稿转为代码的一个工具,在 Flutter 上是免费的,很多人不看好它,我也不看好,因为代码生成工具天然存在各种问题。
但是它却成了我和设计师之间沟通的一个桥梁:怎么做,能不能做,怎么样实现更好做,它成了我们之间一个沟通的可能性,这其实就是源于团队的配合和反馈:
当我把这款软件推荐给设计师时,设计师通过把设计稿原件导入后,他发现了自己设计的渐变进度条效果并没有出现,所以后续他在设计稿层面把设计拆分成三段渐变的颜色,之后导入发现出来的效果还可以,而我在看到生成的代码后,也知道需要通过三层的 gradient 去实现这个需求。
所以要在团判断工作内容的价值,当然工作中不可避免会做体力活,这是换取报酬的必需过程,那就学会把体力活变成不那么体力,比如通过总结、模板化、脚本等能力去降低需要投入的时间。
举个例子,之前因为设计需要频繁更新 png 和 iconfont 文件,这经常需要我手动导入并且手写 unicode, 所以后续和设计约定好一定规则之后,我通过脚本自动解析目录结构,并自动读取 iconfont.css 上的约定好的名称,自动生成对应的 IconData 对象,这就节省出很多需要我重复实现的体力劳动。
目标就是:用短期的工作量实现长期的体力解放。
2.2、做有用的交流
这一点也是很重要,因为很多时候我们很容易沉浸到无用的交流里。
互联网本来就是事非之地,你可以看到每天都有各种活跃的观点,在这个基础上交流,可以帮助我们了解到很多不知道的东西,虽然不一定有用,但是对拓宽我们的知识点很有帮助:
比如你知道 Github 的 Git LFS 是什么吗?
每个使用 Git Large File Storage 的帐户都会获得 1 GB 的免费存储空间和 1 GB 的每月免费带宽: 如果将 500 MB 的文件推送到 Git LFS,就会使用 500 MB 的分配存储空间,而不会使用任何带宽,而至下载就会占用带宽。
一般人是不会遇到这个问题,因为这个问题是因为一个朋友突然收到 Github 的提醒,说他的 Github LFS 带宽已经使用完了,如果要继续使用就需要充值。
这就是简单有用的交流带来的信息,程序员的职业生涯不只是闭门修炼内工,同时也需要对外交流合纵连横。
如果说这样的内容只是茶余饭后的闲扯,那再举个例子:比如 Andriod 国内关于隐私和上架审核的问题:
在我的群里每天都有一群摸鱼的龙王,通过他们的输出,关于审核上架的的东西遇到的各种问题就让我收获不少,比如哪些 SDK 违规,需要怎么处理,针对收集的信息就可以走少很多弯路,甚至还有一些可以出合规报告的第三方合规平台。
这些信息不一定马上有用,但是在需要的时候总能发挥出意想不到的效果,虽然靠自己也能一一解决,倒是通过获取这些信息可以少走很多弯路。
当然交流的前提是有效和健康的,比如其中最无效的交流是:网络撕逼,区分什么是讨论和什么就抬杠,避免把时间浪费在无用的地方,例如:
- Flutter 好像在图片加载上对比原生没有优势; - Flutter 是垃圾;
> 一个是在输出观点,一个是在输出情绪,针对输出情绪的交流,其实没必要花费太多的经历在这上面,例如这样的内容也是很大程度是用于引战。
有时候也会看到群里在争论:
- kotlin 和 java 谁更好;
- dart 是不是垃圾;
- Flutter 和 Compose 谁才是谷歌亲儿子
大家都在各抒己见,但是很多时候一些撕逼的目的,只是在证明自己是对的,有时候只是在展现踩踏的优越感,简单说就是:“他们是真的很闲”。
而这类撕逼最终都是不欢而散的,因为这种时候大家的讨论不是为了事情本身,而是为了展示自己是对的,想让对方接受自己的观点,双方消费的时间换来的更多是情绪上的不满,进而带来情绪上的失衡,这样消费时间的方式就很不值。
我在交流中会尽量恪守一个原则:就算你是对的,也没用必要证明别人是错的,更没必要带着知识阶级的优越感。
我们在交流的过程中,还是需要遵守一些基本的利益,也没必要也没义务强迫别人接受你的观点,带着这个角度去做交流,在适度的时候抽身,学会区分讨论和吵架的状态,我特别喜欢"张三"的这句话:吵架你是吵不赢的, 因为吵架根本没有逻辑,他一开始就带着不承认你的论点出发。
所以友好参与讨论,及时脱离“战场”,这是自我提升关键的一点。
2.3、工作的沉淀
如果说工作和交流是提升的方式,那沉淀就是最后的要素。
相信工作中大家都解决过各种奇奇怪怪的 bug ,那这些 bug 的探索,记录和沉淀就是成长最好的养分。
相信大多数看过我文章的同学应该知道,我有很大一部分文章都是来源于一些很细小的问题,比如:
“Flutter 在 iOS 系统上,系统语言是韩文时,在和中文一起出现会导致字体显示异常" ,这种问题可能很小众,如果不是因为工作需求你可能不会遇上:
解决方法也很简单,就是给 fontFamilyFallback
配置上 ["PingFang SC" , "Heiti SC"]
就可以,那这样就结束了吗?
当然不是,肯定会好奇为什么会出现这种问题呢?
经过查找资料发现,韩文在苹果手机上使用的应该是是 Apple SD Gothic Neo 这样的超集字体库,然后对比发现,【广】这个字符在这个字体集上是不存在的,所以就变成了中文的【广】;
那这样就没了吗?
- 那再想想一般情况下 Flutter 在苹果和 Android 上使用的是什么字体? 在中文和英文下用的是什么字体集合,名称是什么?
- 之后再想想那为什么【广】字会大这么多,Flutter 对于字体的渲染是基于什么设计逻辑?字体本身字重是怎么计算的?基线是的怎么对齐?有哪些可以调节的参数?它们调节的是绘制字体上的哪些内容?
可以看到,从一个小众问题可以去深挖和沉淀的内容并不少,关键在于你是否这样的求知欲,而工作中的问题其实就是最好的拓展能力的起点。 再比如:
Flutter 里的 Future 为什么不能直接 try catch ?
async/await 是 Futrue 是语法糖,那编译后的 Futrue 变成了什么样的代码?
这些都是开发中会遇到的问题,而通过简单问题的深究,就可以带来提升的途径。所有沉淀就是探索,然后一层一层得到答案,最后记录。
三、工作之外
离开公司之后你,你还剩下什么? 这可能也是职业生涯中经常说的一句话。虽然这句话听着很不让人开心,之前“贩卖”焦虑的人也经常使用这句话,但是对于程序员来说,抛开公司的项目和业务,剩下的还有呢?
这其中必不可少的就是 Github 和 博客!
而不管是做开源还是写文章,你首先得有时间,因为打造属于你自己的那部分内容,其实也是很需要很去运营,如果工作之外你有时间,那么 Github 和 写作可以给你带来新的收获:
- 第一目的是提高自己的知名度和影响力
- 第二目的是增加自己交流学习的途径
- 第三目的是通过反馈来持续推进自己的成长
3.1、Github
先说 Github ,其实做开源一般是做服务,一般的开源项目很多时候解决的是程序员的惰性:“有轮子有解决方案我为什么还要手写?”
所以很多时候 Github 项目不一定要技术很牛逼,但是一定是帮助开发者解决各种脏乱差的活,比如:
我开源过的 GSYVideoPlayer ,这个项目至今已经 5 年了,目前 16k+ 的 star ,你说它的代码量有很大吗?也并且并不是,它只是针对各种播放器常见场景做了整合,然后一步一步到走现在,解决的是用户在 Android 平台开发播放器功能时可以少写一些代码,少了解一些基础知识。
那 GSYVideoPlayer 是怎么来的?
事实上一开始我也是找了别人的开源播放器,但是用了一段时间后,发现了一些问题,并且不满足于我需要的场景,所以就基于原本的播放器项目做了一些重构和修复,随后在开源的过程中,因为 issue 和使用场景的升级,对项目进行了多次的重构和调整,就有了现在的 GSYVideoPlayer。
所以如果不知道做什么开源项目的时候,可以基于原有的开源项目做优化升级,可以去提 PR 或者实现一个进阶版的项目,从而去开始自己的开源之旅,我的第一个开源项目就是一个老项目的优化。
并且开源不要担心开源项目太过“弱鸡“,GSYVideoPlayer 一开始就很搓,问题也很多,而解决这些问题就是一个学习和成长的过程。
做开源还有一个关键点就是:一般情况下不要对自己刚开源的项目抱有过高的期望,Github 项目很多时候的关注度就是一点一点累积的,而偶尔的爆发,其实就是需要你自己的运行和长期的维护。
你看 GSYVideoPlayer 在刚开源的时候,每日增加不过寥寥个位数,但是后续的坚持慢慢有了持续的增减很关注度。
当然也不是说什么都不用做,项目创建后干等就行,要持续的增加就需要持续的维护和推广,而推广最直接的方式就是通过持续的文章创作来实现。
通过文章去产生知识点,然后通过开源项目展示成果。
这是最常见的方式,一篇好的文章可以给项目带来不错的关注度,而好的项目也可以给你的文章带来更丰富的流量,这是相辅相成的。
写作
写作也是很重要的一个能力,也是一种知识的沉淀,写文章不只是“你懂了”那么简单,而是要把“你懂的“知识变成“别人也能懂的”的内容。
在我这些年的写作中,特别是写书的过程中,我就经常发现,要把自己的想法变成通俗易懂的文字并不容易,特别是具备连贯性的内容。
所以我经常在写作的时候问自己"为什么?"
比如当我写到 Flutter 的 混合开发的内容时:
在使用 Hybrid Composition
配置就可以使用新的 Flutter 混合开发模式,通过这种方式集成的 Android 原控件的性能会更好,并且问题也会更少。
<meta-data
android:name="io.flutter.embedded_views_preview"
android:value="true" />
那 Hybrid Composition 为什么会提升性能?和之前的 PlatformView 实现的区别是什么?它的实现会有什么优势?会不会带来什么其他问题?
通过思考我作为读者可能会询问的问题,从而在写作的过程中去更新和梳理需要表达的东西。
这就是我常用的写作方式之一,当然有的人会说,我不知道改写什么,好想很多东西都有人写了,这时候从我个人建议出发,就比如音视频开发,相信很多时候大家都会多多少少涉及音视频的开发:
- 我们都知道 MP4 ,那你知道 MP4 是什么吗?
- MP4 如果作为容器协议,那里面有什么?
- 什么是视频编码和音频编码是什么?
- M3U8 是什么?
- RTSP 和 RTMP 能用来干什么?
- 倍速播放靠的是什么同步的?
- HLS 里加密是如何生效的?
- 硬解码和软解码的区别是什么?
这些问题可能一般情况下我们都不会碰到,或者碰到了我们也不知道,因为一般情况下我们可能就是简单播放一个MP4 URL ,SDK 帮我们做好了很多的东西,流服务商帮我们处理了很多情况,遇到不能播放的,我们会说 SDK 不支持,直接提个 issue 就好了。
但是就是这种状态,导致我们错过很多可以用于提升自我的机会,甚至在我的 Github 里还出现过类似这样有趣的 issue :
所以当你不知道写什么的时候,就可以从工作中遇到的问题去逐步深入探索,把学习和探索的过程变成文章或者项目,而这些东西也将成为工作之外你个人价值的提升和体现。
最后总结一下: