@charset "UTF-8";.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:14px;overflow-x:hidden;color:#353535}.markdown-body h1{padding-bottom:4px;font-size:30px}.markdown-body h1,.markdown-body h2{margin-top:36px;margin-bottom:10px;line-height:1.5;color:#005bb7}.markdown-body h2{position:relative;padding-left:16px;padding-right:10px;padding-bottom:10px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h2:before{content:"「";position:absolute;top:-6px;left:-10px}.markdown-body h2:after{content:"」";position:absolute;top:6px;right:auto}.markdown-body h3{position:relative;padding-bottom:0;margin-top:30px;margin-bottom:10px;font-size:20px;line-height:1.5;color:#005bb7;padding-left:6px}.markdown-body h3:before{content:"»";padding-right:6px;color:#2196f3}.markdown-body h4{margin-top:24px;font-size:16px}.markdown-body h4,.markdown-body h5{padding-bottom:0;margin-bottom:10px;line-height:1.5;color:#005bb7;padding-left:6px}.markdown-body h5{margin-top:18px;font-size:14px}.markdown-body h6{padding-bottom:0;margin-top:12px;margin-bottom:10px;font-size:12px;line-height:1.5;color:#005bb7;padding-left:6px}.markdown-body p{line-height:inherit;margin-top:16px;margin-bottom:16px}.markdown-body img{max-width:100%}.markdown-body hr{position:relative;width:98%;height:1px;margin-top:32px;margin-bottom:32px;background-image:linear-gradient(90deg,#007fff,rgba(255,0,0,.3),hsla(0,0%,100%,.1),rgba(255,0,0,.3),#007fff);border-width:0;overflow:visible}.markdown-body hr:after{content:"";position:absolute;margin:auto;left:0;right:0;bottom:0;top:0;display:inline-block;width:60px;height:20px;background:#fff;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAADoklEQVRYR82XTYgcRRTHf2933Q1RjAa9eFO8JHoJ8RQVBQ2iBwXBET0YEUTXNVmNQtTpmeqaWV0XNRq/o4KoECSCEPSg4CF BYUkIIiCoCJCPIhC/Ihh2Z0nVV27VnZnenumW9i6ddV7//frV69fVQurfMgq56NawFTPAU6QyomqXrw6wIZeyhCPebA5buNR akKyGoAjd6BshthnYdSjqNcRVuOlIUsD2j0SuA94IwuMHdh5ZUykOUBXfSGbmKI54EtAeYIHSZoy5dl4JxvNYBOKdW1KE8BQ8AkVk6WhasWsAiN0TX9gveXQaPP Aytpc4u bMI06JNohsYYYYOR2lJWtS3OKDRfcAtQfgDoI6Vo4UCGb0OmAEuDvZvYmVbEd/igC3dzDz7gQu8sPA9kJDK27mBmjqBeLjTg90PDFOjWawFFQd06kZHEfaj3LAIpTRpSXsZ5E06zEYP9sDimnAApYaV2SLZG/wjMeqAkijwW4xQJ5Gf/ZzRC8OW3hiBTGGlURRswW55Bh/Ssxljrwew8l1PQaM14GngvGDzBUKdDsMeTtgU5o8B92PFlUf3YXUrHa7Fys6lBqcCGnX15YQ2A18FyPd7Crd1A3M8C1wdbH4DD3hWeP6IEXbQkG97ajR1HPFnuPP5jFFq1OWX7hl8WM9l1AO648uNfwLk7tytMeogty xeQ4rO3r6bdcx1nuwOGsHmaXGtPzae4uzGnLH1kQkvpdZGrHjssBZJrL pqS05KWc8tgITAPXRzYvYOXe/C2OV43eDcRBDtIhoS2f9wzc0Cv8Wls zoFzUC5zF0U241h5uZtPfptp6OUM8wbK cH5GEpCS17P3fJei0Z3 npTxryJ8CPzbKMtn/ZyWbkPGl0PuFPkmkjkcb4h4R2ZLwRq1H0ALmvjkf2HwK1Y T1PY2XABe/sHJ6MxN5lnoSpnC/UGbsTaI5phK2R7x6s3Ffk5YoDOrWm3onwJHBmEP86bPmBrsGaenNoIdnxCH gPEhLXi0Cl1VBvyPVLSh7gEuC62yAfOIUqabWEaaiucMIk6RyqJ Q/QM69V26jjW86Gvov/EaoyT8zRCn Xq7PVrbx0nuYUaO9wM3WAbjCE1NEUw09Um4UV 2OKfYfu5/S19gsAzGKqm6LE5FrShbdS0ku465DjDwKA/oQht19ejqbaEVuRbiLhuHByYLjtUAZpDutzP7cYdHsPJXWbjyNVgFwQoa1WXwf4Jd9YD/Ap80 yE7 u9aAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-size:auto 100%;background-position-x:center}.markdown-body code{padding:.065em .4em;font-size:.87em;color:#c2185b;word-break:break-word;overflow-x:auto;background-color:#fff4f4;border-radius:2px}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{display:block;padding:16px 12px;margin:0;font-size:12px;color:#333;word-break:normal;overflow-x:auto;background:#f8f8f8}.markdown-body pre>code::-webkit-scrollbar{width:4px;height:4px}.markdown-body pre>code::-webkit-scrollbar-track{background-color:#bedcff}.markdown-body pre>code::-webkit-scrollbar-thumb{background-color:#2196f3;border-radius:10px}.markdown-body a{position:relative;text-decoration:none;color:#3da8f5;border-bottom:1px solid #bedcff}.markdown-body a:hover{color:#007fff;border-bottom-color:#007fff}.markdown-body a:active{color:#007fff}.markdown-body a:after{position:absolute;content:"";top:100%;left:0;width:100%;opacity:0;border-bottom:1px solid #bedcff;transition:top .3s,opacity .3s;transform:translateZ(0)}.markdown-body a:hover:after{top:0;opacity:1;border-bottom-color:#007fff}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #c3e0fd;border-spacing:0;border-collapse:collapse}.markdown-body table thead{color:#000;text-align:left;font-size:14px;background:#f6f6f6}.markdown-body table tr:nth-child(2n){background-color:#f7fbff}.markdown-body table tr:hover{background-color:#e0edf7}.markdown-body table td,.markdown-body table th{padding:12px 8px;line-height:24px;border:1px solid #c3e0fd}.markdown-body table th{color:#005bb7;background-color:#dff0ff}.markdown-body table td{min-width:120px}.markdown-body blockquote{color:#8c8c8c;border-left:4px solid #2196f3;background-color:#f0fdff;padding:1px 20px;margin:22px 0}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body b,.markdown-body blockquote>b,.markdown-body blockquote>strong,.markdown-body strong{color:#2196f3}.markdown-body em,.markdown-body i{color:#4fc3f7}.markdown-body del{color:#ccc}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:4px}.markdown-body ol li{padding-left:6px}.markdown-body details>summary{outline:none;color:#005bb7;font-size:20px;font-weight:bolder;border-bottom:1px solid #bedcff;cursor:pointer}.markdown-body details>p{padding:10px 20px;margin:10px 0 0;color:#666;background-color:#f0fdff;border:2px dashed #2196f3}.markdown-body h1::selection,.markdown-body h2::selection,.markdown-body h3::selection,.markdown-body h4::selection,.markdown-body h5::selection,.markdown-body h6::selection{color:#005bb7;background-color:rgba(160,200,255,.15)}.markdown-body p::selection{color:#c80000}.markdown-body a::selection,.markdown-body b::selection,.markdown-body del::selection,.markdown-body em::selection,.markdown-body i::selection,.markdown-body strong::selection{background-color:transparent}.markdown-body code::selection{background-color:#ffeaeb}.markdown-body pre>code::selection{background-color:rgba(160,200,255,.25)}.markdown-body ol ::selection,.markdown-body ul ::selection{background-color:rgba(160,200,255,.15)}.markdown-body .contains-task-list{padding-left:14px;list-style:none}.markdown-body .contains-task-list input[type=checkbox]{position:relative}.markdown-body .contains-task-list input[type=checkbox]:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;width:inherit;height:inherit;background:#f0f8ff;border:1px solid #add6ff;border-radius:2px;box-sizing:border-box;z-index:1}.markdown-body .contains-task-list input[type=checkbox]:checked:after{content:"✓";position:absolute;top:-12px;left:0;right:0;bottom:0;width:0;height:0;color:#f55;font-size:20px;font-weight:700;z-index:2}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}
我从事技术写作的时间其实不长,开始写作的时间就是我掘金账号注册的时间:
到今天(2021年2月23日)也就是一年零一个月,这一年的收获是超过我的预期的:
- 产出博文四十多篇,总共数十万字
- 掘金优秀作者,掘金年度人气作者No.27
- 思否2020年度"Top Writer",万粉专栏作者
- 开源中国优秀源创作者,源创计划年度活跃博主 Top20
本文想对这个历程做一个回顾,并分享一下我总结的写作技巧以及推广策略。
为什么写作
在写作之前想清楚为什么写作非常重要!因为你最初的想法会决定你往哪个方向去写,写出的内容的质量怎么样。
我写作的原因很简单,就是我前端做了几年了,大部分时间都在写业务代码,技术上一直没有太大的突破,最多也就是换个框架,换个UI库,换来换去始终感觉似曾相识。为了不让几年工作经验成为“第一年工作经验的复制品”,我决定再深入,系统的学习下前端知识。所以对于我来说,写作是我的学习方法,我的首要目的是学习知识,写作带来的社区声望只是附带的,有了当然好,没有也没必要刻意去刷。
“为学习而写”与“为刷声望而写”
根据我的观察,社区上的作者写作目的主要分为两种:“为学习而写”与“为刷声望而写”。
大部分厉害的大佬其实都是“为学习而写”,就是他们看到什么好玩的,新奇的技术,去学习了,自然而然的总结出文章。或者觉得某个知识点大家很容易搞错,想输出自己的观点,帮大家避坑,就将自己的见解写成文章,这个过程作者虽然更多的是在输出内容,但是写作的过程其实也会强化作者自己的理解,其实也是一个学习方法。我个人认为“为学习而写”写出的文章才是正道,是社区良性发展的方向。
当然也有少部分作者想在短时间内获取更多关注而刻意的去迎合读者口味,也就是“为刷声望而写”。比较典型的一个例子就是,掘金曾经在某段时期被大量的面试题汇总占据。大家出去面试了回来分享下心得其实是好事,但是刻意的去搜集面试题,相似的内容发了一遍又一遍,里面的答案甚至还是错的,会导致社区越来越功利,低质量面试题霸版,高质量技术文章反而没机会展示,从而造成劣币驱逐良币的现象。我记得那会儿有个作者靠反复发面试题,短时间就刷了三四千掘力值,眼看就要到“优秀作者”了,结果被一个社区大佬怼了,然后就没怎么露面了。这样,前面刷的几千声望不是都白费了吗?后来掘金官方也整治了低质量的面试题文章,现在的情况已经好多了。
所以我说,写作前想清楚“为学习而写”与“为刷声望而写”很重要,如果是“为学习而写”,那就可以写出自己的心得体会,写出高质量文章,如果单纯是“为刷声望而写”,可能短期会有点收益,但是也有可能会被大佬怼,被官方整治,前功尽弃。
写什么
在这个“系统学习计划”开始之前,我其实没怎么写过技术文章,甚至都没怎么逛过技术社区。平时如果需要学习一个东西,比如学习React
,那我会直接去它的官方网站,把它的文档全部读一遍,现在这些流行库的文档都写的很好,看一遍基本就能上手了。如果看完了还是不太知道怎么用,那就去公司看看有没有项目用过,公司没用过,就去GitHub上找找,然后抄抄改改就能上手了。这个过程一般也就几天,复杂的库最多也就一两周就能上手。使用的时候遇到问题就用Google搜,基本都会找到Stack Overflow上,答案拿过来一用就行。
前面几年我的工作模式基本都是这样的,这样应付工作也没啥问题,但是第一年是这样,第二年是这样,第n年还是这样。。。就成了“一年工作经验复用n年”,成了名副其实的“API工程师”,做项目没问题,问原理似曾相识,但是却说不太清楚。如果一直这样,技术就会一直原地踏步,在现单位很容易被替代,出去找工作也可能会四处碰壁,或者找来找去找到的始终跟当前的差不多,很难实现大的突破。
我感到,我碰到瓶颈了。我想突破这个瓶颈,但是我不知道怎么做!在没有具体方向的时候,就看看手上能做啥吧,从简单的,可见的开始做。于是,我决定,我要重头整理自己的知识框架,把那些只是似曾相似的技术,原理全部吃透,于是我从网上找了一份“前端知识架构图谱”,决定按照里面的提纲,全部重新学习一遍。只是我再次学习不能是简单的看看书,看看博客,看看视频就行了,这种事情我以前干过了,作为一个有几年工作经验的前端,我对自己有更高的要求:所有学过的知识点,必须自己全部写成文章进行巩固;所有框架的学习,必须学到原理或者源码层面!
所以,“写什么”这个问题的答案已经有了:学习前端知识架构,将学习过程写成文章。
怎么写
上面说了,我其实并没有什么写作经验,我最近一次写作是大学论文,再往前就是高中作文了,写作水平其实不咋地。但是技术写作跟普通作文不一样,一般不需要华丽的辞藻,更重要的是要把问题讲清楚,看技术文章的读者需要的是学习技术知识,而不是看风花雪月,所以技术文章的逻辑,层级递进,由浅入深,好理解其实更重要。我刚开始时也不知道怎么写,也是在不断写作工程中,一边写,一边总结,整体来说,我自己的文章其实都分了好几个阶段:
- 就是记个笔记
- 有自己理解的知识点解析
- 深入源码,探究原理
- 从工作中总结
就是记个笔记
从小学开始,老师就会让大家记笔记,大家应该都会,这也是最简单的切入点。我刚开始的时候,不会写文章,写的基本都是笔记,比如各种CSS居中方案,这就是我在其他地方学的,然后把他记录下来,也就是个笔记而已。对于“CSS居中”这种问题来说,面试问烂了,网上资料也是一大堆,这篇文章也没什么出彩的地方,所以关注的人不多。其实对于“笔记型”来说,获取关注少是很容易理解的,因为你写的东西是笔记,也就是说你也是从其他地方学来的,整个文章的思路其实也是人家的,如果自己记笔记的水平不高,可能写出来的效果还不如原文章。
有自己理解的知识点解析
在写了一些“笔记型”文章后,我发现效果不好,不仅仅是没什么人关注,甚至对自己帮助也不大。经常是写了没多久就忘了,需要的时候还要回过头来看看笔记,我开始意识到,这个现象的本质是,你写的东西是笔记,核心思想都是人家的,或者是自己东拼西凑的,整篇文章没有自己的逻辑,没有自己的见解。于是,我开始尝试在文章中加入自己的见解,当时正好组内有小伙伴对“JS原型链”理解的不是很透彻,网上虽然有很多类似文章,但是很多都是从表面来解释“原型链是什么”,画的图也很复杂,不是很好理解。于是我尝试自己写一篇原型链的文章,因为我知道他可以实现“面向对象”的特征,这是很多其他文章都没怎么提的,但却是设计者最初可能想要实现的效果,于是我类比Java的面向对象,从面向对象的角度讲述了原型链的作用以及他存在的意义,就是这个:轻松理解JS中的面向对象,顺便搞懂prototype和__proto__。这篇文章上了掘金首页推荐,最终获得了两百多赞,一万多阅读,这让我开始意识到,“有自己理解的知识点解析”在掘金可能更受欢迎。
在这之后,我开始有意识的在整理知识架构时加入自己的见解。那对于一个知识点,怎么产生自己的见解呢?这需要在学习时多问自己几个问题!比如,学习HTTPS时,除了跟大家一样搞清楚HTTPS的加解密流程,握手过程外,我问了自己一个问题:“HTTPS有没有可能被破解?假如我是个黑客,如果我想破解HTTPS,有哪些方法和途径?”带着这个问题,我从“破解HTTPS”的角度讲述了HTTPS的原理,这篇文章也上了推荐,获得了一百多赞和好几千阅读:RSA初探,聊聊怎么破解HTTPS。
尝到点甜头后,我更加注意在学习中反问自己问题,加入自己理解了。有时候在学习别人的东西时,我发现了别人没发现的一些点,也可以从这个角度加入自己的独到见解,写成自己的文章,比如某视频课程在讲述JS的事件循环时说:“setImmediate
比setTimeout
先执行”。听到这句话,我敏锐的感觉不太对,因为我曾经遇到过setTimeout
比setImmediate
先执行的情况,但是具体是啥情况我一时想不起来。于是我花了点时间把这个问题和原理彻底弄清楚了,并写成了自己的文章:setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop。这篇文章最终也获得了一百多赞,大几千阅读~
深入源码,探究原理
JS知识体系虽然庞大,但是终究是有限的,很快我就写了十几篇JS的文章,内容包含了内存管理,深浅拷贝,面向对象(原型链),this
指向,事件循环,变量类型,作用域等等。这些已经囊括了JS的主要知识点,JS上我已经很难找到新的写文章的点了。
于是我的文章内容开始转向我使用的框架,这几年我主要使用的React
技术栈。于是我准备重新整理学习React
技术栈,当然不是学习他的用法了,毕竟我用了几年了,用法早就熟悉了,这次我要学的是他们的源码和原理。源码和原理相对于JS知识和框架使用方法来说要难得多,受众也小的多,对于读者来说也很难产生直接的收益。因为读者可能看个JS知识点,出去面试就能应付大部分的JS面试了,除了些大厂外,也不是每个公司面试都会问源码,而且这些受欢迎的开源库是各位大牛努力写作的成果,里面汇聚了各种JS的高级用法,各种高级编程思想和设计模式,所以即使我尽量写得深入浅出,层层递进,相较于其他文章来说仍然会显得更加晦涩难读。所以这类文章在掘金获得的赞和阅读并不可观,我大量的源码解析都只有三四十个赞,这里面还有一半左右是我厚脸求朋友同事们点的(这点我后面在讲推广的时候会说)。
对于作者来说,写源码类文章需要去读框架源码,也会很花时间。我写一个JS知识点的文章,因为东西都是我熟悉的,可能几天就搞定了,写完了还会有上百的赞。但是一个复杂框架的源码解析,比如Express.js
,我需要一点点的去读,去调试源码,成文可能需要两三周,写完后可能仍然只有三四十个赞。从社区声望增长这个角度来说,性价比极低!但是我一直没有放弃这类文章,甚至现在成了我主要的写作方向。为什么?因为人总要突破自己的舒适区,探索未知的领域,最终才能学习到东西,获得成长!这其实回到了文章开头就提出的问题:“你为什么要写技术文章?”对于我来说,这是我学习的途径,所以如果这个过程我能够学到东西,能够感受到成长,我就会坚持去做,即使他在其他方面性价比很低!另外我的源码类文章虽然在掘金反响不是很好,但是在其他平台,比如思否,还可以,所以其实也是有回报的。
好了,说了这么多为什么要写源码解析,现在来谈谈怎么写源码解析。前面说了,在我从事技术写作之前,我基本不懂源码,是名副其实的“API工程师”,那会儿我也是一提到源码就心慌,完全不知道从何下手。后来我忐忑的打破自己的心理障碍,多次尝试之后找到了一个看源码的套路。其实再