开源了两个小插件

开源两个自己之前写的小工具,koa-router-decoratorreact-native-dynamic-stylesheet.

koa-router-decorator

链接在此:koa-router-decorator
第一个是用装饰器写路由的工具。

想法源于flask,之前看flask写的路由,觉得用装饰器写的话,会比较优美,然后就写了这个插件。
效果如下:

react-native-dynamic-sty2lesheet

链接在此:react-native-dynamic-stylesheet
这个则是自己在写RN App时候,有一些样式需要按照状态变化,写起来很繁琐,然后就自己写了个插件,专门用于生成动态的样式表。

用上之后自己在这方面的效率确实高了好几倍,还是很开心的。

这些天做过的一些分享

这段时间,一直专注于给家园工作室团队内部去做一些分享。
有规范的制订,也有前端的学习,还有关于学习方面的分享。

REM + Flex 布局

第一份:REM + Flex 布局

讲的是我在写移动端页面,和学习Flex布局中的一些经验和好的资源。

家园项目Git规范

第二份:家园项目Git规范

讲的是给家园工作室制订的Git规范,参照Git Flow,但是根据我们的实际情况,增删了部分内容,比如取消了 dev, release 等辅助分支。

学习如何学习 人生元编程

第三份:学习如何学习 人生元编程

讲的是自己在学习过程中,结合各种方法与教程,所总结与探索出的,一份适合自己的学习方法

JavaScript实现列表无限加载

起因

之前自己在使用这种网站时,经常看到无限加载的效果。
今天正好看到了getBoundingClientRect这个Api,就想着试试看如何实现Infinite scroll的效果。

原理

在需要无限加载的列表底部,埋下一个隐藏元素。
当不断滑动时,隐藏元素将出现在视窗(viewport)里,也就意味着当前浏览的列表已经到底部了。
这时候就需要进行列表加载。
大概的HTML结构如下:

1
2
3
4
5
6
7
8
9
10
<div>
<ul class="article-list">
<li>我是文章</li>
<li>我是文章</li>
<li>我是文章</li>
<li>我是文章</li>
<li>我是文章</li>
</ul>
<div class="infinite-scroll-signal"></div>
</div>

也就是:滑动列表 => 隐藏的无限加载指示器出现在视图 => 开始加载

那么重点就是检测隐藏的无限加载指示器是否出现在视图窗口。
还好,我们有getBoundingClientRect这个Api。

getBoundingClientRect

通过查阅MDN,得知:

Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。而除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。

至于兼容性,一片绿,可以放心使用。


Can I Use getboundingclientrect? Data on support for the getboundingclientrect feature across the major browsers from caniuse.com.

DOMRect 对象

getBoundingClientRect()方法的返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集合 。

对象的属性如下图所示:

其中的 top, left, bottom, right 均是元素自身相对于视图左上角而言的。
top, left属性而言,很好理解。而bottom, right则一开始搞的有点懵,后面通过devtools观察,发现bottom是元素的最底部相对于视图窗口左上角而言的,而right则是元素的最右侧相对于视图窗口左上角而言的。
其中right-left为元素的宽度,bottom - top则是元素的高度。

检测元素是否出现于视图窗口中

在这里,有两种情况,一个是元素是否出现于视图窗口中,另一种则是元素是否完全出现于视图窗口中。
两种情况的区别在于一个是部分出现,一个是完全出现。

下面我把两种情况都写出来:

  1. 部分出现在视图窗口中
1
2
3
4
5
6
7
8
9
10
11
function checkIsPartialVisible (element) {
const rect = element.getBoundingClientRect()
const {
top,
left,
bottom,
right
} = rect
const isPartialVisible = top >= 0 && left >= 0
return isPartialVisible
}
  1. 全部出现于视图窗口中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function checkIsTotalVisible (element) {
const rect = element.getBoundingClientRect()
const {
top,
left,
bottom,
right
} = rect
const isTotalVisible = (
top >= 0
&&
left >= 0
&&
bottom < document.documentElement.clientHeight
&&
right < document.documentElement.clientWidth
)
return isTotalVisible
}

那么问题来了:我们到底选用那种呢?
从无限加载这个业务场景出发,埋在列表最下边的加载触发器都非常小且不可见,因此推荐选用第二种,也就是完全出现于视图窗口的方式。
至于第一种,更适合检测该元素是否已经出现在视图窗口,但并不要求全部出现的情况。

实战

具体可以看我在jsfiddle上写的demo:
无限加载实例

后续

后续更多的则是一些性能优化的事情,比如debounce或者throttle来减少scroll事件调用次数,加入ajax加载,loading indicator等。
那些都是属于具体的业务范围了,这儿不做讨论。

iNCU App开发实践 - 架构设计

App架构?

架构很多时候,是个很玄的词。
软件开发中,架构真实的存在并影响着软件研发、运行与维护时的质量。

好的架构,明眼人一看就知道。比如Linux内核,又比如一些优质的开源软件。
而其他架构的质量,则往往难以判断。

嗯,关于这次iNCU App的架构,自己虽然觉得有些地方仍有不足,但是已经是自己尽全力的作品了。

这次分享出来,也是想分享自己在App架构上的实践与思考,如果有不足的地方,还希望各位多多指正。

思考🤔

App在正式开发之前,自己思考了两周,内容是 App的分层,文件的结构与技术选型等。

App的分层,在我看来是个非常重要的部分,假使View, Model, Router等层级杂糅在一起,在代码达到一定规模时,开发将会变的非常痛苦。容易出现耦合性高,BUG多,修改难等诸多问题,牵一发而动全身,从而陷入无边际的重构或者修改BUG的过程。

为了不陷入这种“地狱”状态,所以宁可多花时间在前期的思考与尝试中。

React Native

React Native是一个很特殊的框架。跨平台、复用性高、热更新等特性听起来很美好,但实际开发中会发现限制和BUG也很多。
很多功能,想要实现,只能靠原生拓展,但是这边能写原生的人只有一个……所以大部分原生拓展只能依赖开源的RN模块去实现。

团队

种种限制之下,对App的任何功能的开发与拓展,与我而言都不亚于一场战争。
毕竟,我也大概只能在家园工作室呆几个月不到的时间了,而这个App在一两年的时间内,还是需要做一个维护与拓展的,如何平衡这个问题,也需要自己耗费诸多脑力去思考。
如果只是为了自己开心,上一堆花式炫技的技术或者选用一堆不稳定的模块,其实只是顾着自己一时爽快,对于整个团队而言是弊大于利了。

另外自己写代码也快有两年时间了,直到今年年初,通过看书才悟出了“程序的第一要义是明确”的这个道理。而这个项目,也希望给学弟学妹们留一个好的例子,写代码很多时候真的不需要花式炫技,代码可读性高,可维护性好,健壮性强才是真正值得去追求的。

启动工作

与之前相比,在写这个App的功能或者模块时,自己会先画个思维导图或者流程图,确保逻辑是通畅的、可实现的。而不是边写边想边重构。

因为大概自己也很清楚,难点和问题从来就不在实现的具体方式和技术上,而是逻辑和流程上。有了具体的逻辑,写东西那是唰唰的快。

比如说关于网络层的思考:

自己画了详细的思维导图,考虑了可能会出现的所有情况,所以在开始写代码的时候,便显得有把握的多,后续的开发过程中也证明了这种思路的可行性,没有大修大改的情况,只是在这个基础上做一个修修补补。

设计模式

嗯,其实也算不上设计模式,但是之所以还是取了这个标题,是因为自己觉得整个App的研发过程中,充满着设计模式的思想。就是:

把变与不变的地方分开

基于这点,在开发过程中,更多的考虑了变与不变,从而在此基础上实现了文件结构,模块划分等。
至于后续的开发体验,只能说爽~~~
即使改了需求,也只需要改动一小块地方,耦合性低,再配合自己写的单元测试,可以说是效率极高。

测试

测试,是iNCU在开发中的核心环节,也是iNCU顺利开发的保护伞。也就是从这个项目开始,真正理解了测试的作用。
在这里的测试,包括 单元测试、Api接口测试、snapshot测试三种。
其中单元测试针对一些函数和功能,确保正确运行。
Api接口测试则是因为这儿接入了五六个后端,需要确保后端的接口运行正确与返回的数据正确。
Snapshot则是为了保证基础组件的正常运行,防止出现版本升级突然挂掉,或者修改属性也不知道的问题。

三种测试一起使用,保证了项目在修改,升级的稳定性。

文件结构

首先放上项目的文件结构:

.
├── __tests__ # 全局测试文件
├── common # 通用工具
│   ├── __tests__
│   └── analytics # 数据分析 
├── components # 基础组件
│   └── __tests__
├── constants # 常量
├── containers # container
├── networks # 网络层
│   ├── __tests__
│   ├── api # api
│   ├── interceptors # 拦截器,用于对网络请求做一些拦截处理
│   │   ├── request
│   │   └── response_error
│   └── interfaces # 接口定义文件
├── pages # 具体页面 View层
│   ├── __tests__
├── redux # Redux
│   ├── modules # 具体的Redux 模块
│   └── sagas # sagas 
└── typings # 自定义的接口文件

文件结构在我看来,一直是个很重要的内容,因为在项目发展的过程中,一个设计不佳的文件结构会给人带来很大的困扰,比如开发新功能或修改老功能。

上面放的就是iNCU项目的文件的结构,做了一个分层的处理,从而保证开发有序。
而在Redux的处理上,按官方推荐的那种结构来,在项目扩大化时,将会遇到繁琐的问题。
因此对于Redux中模块的处理,参照了 dva 和 vuex 的实现,聚合在一起,从而避免一些不必要的操作。

结语:

这篇博客是2017-04-17开的坑,因为自己在忙一些别的事情,所以今天(2017年05月06日)才补完后半部分。
无论如何,也算是写出了自己一直想说的一些事情吧~

前端路漫漫,且行且歌~

TCP/IP 学习

起因

之前自己学习的时候,碰到一些与计算机网络相关的问题。有侧重于HTTP的,也有侧重于TCP/IP等偏底层知识的。
今天对着阿里的《技术之瞳》这本书,准备系统学习一下计算机科学相关的知识。而书中的重点,就是TCP/IP。

TCP/IP 三次握手和四次挥手

首先要说的,就是最经典的问题之一,TCP/IP 三次握手和四次挥手。
具体可以看图,内容应该也很直白。

自己在学习过程中,产生的疑点在于三次挥手中的第三次握手。
也就是发送方发送ACK信号这一条。
在自己的理解中,既然已经确认了对方确认了自己的请求,那么自己再发送ACK信号是否是多余的?

后续再继续查阅相关文档时候发现,并不是自己想的那样,《图解TCP/IP》这本书简化了细节但有些时候是也不利于自己的理解。

第一次握手(SYN=1, seq=x):
客户端发送一个 TCP的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入 SYN_SEND 状态。

第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。
发送完毕后,服务器端进入 SYN_RCVD 状态。

第三次握手(ACK=1,ACKnum=y+1)
客户端再次发送确认包(ACK),SYN标志位为0,ACK标志位为1,并且把服务器发来 ACK的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN
发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP握手结束。

引用自:TCP三次握手四次挥手

是的,《图解TCP/IP》这本书简化了客户端进入 XXX 状态这一点,所以看得时候是有些云里雾里的。

具体则是:

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
引用自:简析TCP的三次握手与四次分手

确定唯一目标

在发送数据时,如何确定唯一的发送目标。
之前自己想的是ip地址+MAC地址,后续看书时候发现并不是。
MAC地址很多时候只是充当了下一跳的作用,而非唯一地址。

而确定唯一目标的关键,则在于IP+端口号。

有了 IP 地址,为什么还要用 MAC 地址?

这个是在看ARP协议时候,产生的问题。
后面发现是因为历史遗留与需要唯一识别的原因。
具体的内容可以看:有了 IP 地址,为什么还要用 MAC 地址?

iNCU App开发实践 - 技术选型篇

不知不觉App已经上线快一个月了。而自己也总算结束了匆忙且无序的生活。生活节奏开始走向了正轨。
上个月说好的在博客更新iNCU项目中的点滴,也从这篇博客开始,慢慢的书写。
开发过程中,想的有点久,东西有点多。
今天就先从技术选型开始讲起。

主要技术

作为一个程序员,自然要把App中使用的开源技术,放到感谢的栏目中。
以下是App中核心的技术与框架。

技术选型の观点

关于技术选型,其实是一个老生常谈的问题。每个人都有各自的想法与观点。因为技术选型的观点不同而在社区引起争论的现象比比皆是。

于我而言,技术选型最重要的一点是:效用
效用在这儿指的是技术选型对整个项目/个人/团队所起的作用。
假如从这一点出发,便能避免很多不必要的问题与怀疑。

对项目的效用

首先则是对项目的效用,也就是要选用的技术对项目所起的作用与满足的需求。
一味追新,则可能经常性的碰见Breaking Changes,大部分时间都耗在弥补升级的坑上了。
一味保守,则可能出现效率不高,无法应付未来需求的问题。用jQuery当然很稳定,但是如果是大型SPA,则会出现力不从心的情况。

从iNCU项目本身而言,从技术层面出发,选用的都是偏稳定,生态繁荣,依旧在发展中的技术。
比如React Native,比如TypeScript,两者目前都是偏稳定的技术,一定时期内不会有太大的Breaking Changes,能稳定且持续的开发下去。

从需求层面出发,iNCU最好是能够发布Android与iOS版本,而目前团队移动端人手不足,短期内培养出移动端开发人员是个不现实的愿望。所以只能自己亲自上阵。
而我作为一个前端,技术选型上自然偏向了HTML5和RN。最后在评估几次需求与使用RN和HTML5(Cordova, ionic)写了好几个demo时,做出了最后的选择,RN。

对我而言,RN的优点如下:

  • 满足需求,能实现iOS/Android端的开发
  • 性能较强
  • 可拓展性强,后期可以通过原生拓展实现一些高级功能
  • 使用纯 JS + CSS Flexbox 语法编写,上手难度低,无语言切换成本

RN的缺点则是:

  • 团队目前前端主技术栈为 Vue,学习React的人比较少,后期维护可能会有问题。
  • RN仍不够稳定,一定时间后可能会出现较多的Breaking Changes,升级可能有障碍

再三权衡之下,选择了RN作为主开发框架。

对个人的效用

因为自己目前也只是一名学生,所以很看重技术选型给自己带来的效用。
换句话就是,选这个技术对自己的成长有什么帮助?或者能给自己带来什么?
带着这种想法去做技术选型,去学新技术,则会明确许多,而不是盲目的追新。

假使我已经能熟练运用Vue,理解Vue的思想与要解决的问题,那么下一个项目一定是React/Angular等未知领域的框架。
即使Vue用起来很方便,由于经验的积累,写起来也很快。但是对于个人成长而言,所起的作用已经不大,是时候去接触新的思想,新的框架,而不是继续留在舒适区。

这也是我在日常学习中很注重的一个方面:刻意练习。

在这种情况下,我选择了TypeScript作为自己的主开发语言,于我个人而言,TS的类型系统写起来很爽,也能让自己避免一些低级错误,还起到了基础的ESLint的作用,可谓是一箭三雕。
而事后也证明,熟练使用TS,让自己的开发效率大幅度提升,同时BUG数量比之前的少了很多。同时也能学到一些静态语言的知识。

另外一种情况则是自己选用的RxJS,整个项目中,就一个函数使用了RxJS,功能也很简单。

但是自己却觉得很划得来,因为RxJS的函数式写法很优雅,赏心悦目,看着就很开心。(对,为了开心😊)

至于自己对RxJS的作用和优劣,我在V2EX一个RxJS的问题中有回复:

前些天一直在学 Rx ,想引入项目后面还是放弃了。
目前看来 Rx 适合复杂的异步时间和数据流等,简单的小场景用 Rx 只是自己给自己找麻烦。而且 Rx 的侵入性特别强,基本上用了之后都是 Rx 那一套东西了。
最后贴一句前两天自己看到的一句话:不要为了 Rx 而 Rx 。

以上两个就是基于自身考虑的技术选型情况。
我从今年以来,一直有个想法,那就是掌握框架,或者说掌握哪个框架并不重要,掌握解决问题的方法,理解框架的本质,才是真正核心的。

对团队的效用

iNCU是个团队的项目,自然需要考虑后续维护的问题。
那么技术选型也应该是这样。
之前有在Redux + Redux-sagaRedux + RxJS + Redux-Observable中纠结很久,最后选择了目前最成熟的Redux + Redux-saga,无他,RxJS的侵入性和门槛太高了,不利于他们的后期学习与维护。
同时也是基于对应用场景的分析,不想为了 Rx 而 Rx 。,自己玩玩还行,但如果放在团队中,可能就容易坑到人了。

自己关于团队技术选型,观点则是:

引入技术是要解决实际问题的,引入的收益最好大于大家接受他的开销。否则是得不偿失。

结语

以上则是自己对于iNCU App的技术选型,和自己对于技术选型的一些思考和见解。
如果你有什么更好的看法,欢迎随时找我交流~

我的第二个App, iNCU上线一周啦~

从去年十二月写完2017年的年度总结后,便没有再去写博客了。
不是不想写,而是在忙一个项目,一个对我而言很重要很重要的项目。
我的App,iNCU

当时App上线时,有三天的预热活动,自己也写了三天的说说,来表达自己对这个项目的情感。
以下的三段为空间说说全文。

项目起因

@佛爷 两年前向你申请加入家园,答应要做一个安卓App。三个月后转了前端,你却很支持我的决定。如今时光荏苒已过两年,当年的约定我还一直都牢牢记着。
从去年八月份开始到今天这半年多时间,或许只有自己清楚为了这个App的出现,到底做了多少事情。
明天App就上线了,是两年的心血,是两年的成长,也是给绵延两年的承诺所交出的答卷,希望你能收到并满意。
最后的最后,感谢学长你在少年一无所知的蛮荒年代,给予他前行的期望与勇气,支撑着他走下去直至见到光明。
【不忘初心,方得始终。2015.03.27-2017.03.09】

项目进展与个人

刚看了看项目提交记录,898个commit,10000+行代码,从安卓iOS到前端后台,产品的每一个功能,都是自己再三思考和权衡的最优解。开发过程中,两次重构,无数次改动,只为追求更优的用户体验,写出更好的代码。整个项目做下来,恍如隔世却也脱胎换骨。

项目结尾时想说的话

这个App,算是这两年来自己的心血之作,也作为礼物送给自己,送给家园,送给每一个期望南昌大学变的更美好一些些的你我他。(鞠躬)

技术

做整个项目,只想说一声脱胎换骨。(不过也导致上线后几天不想写代码,玩脱了)
具体的技术内容,剩下几天我将一一道来。

既然来了

最近的事情有点多,再加上自己想的也多,所以有很多烦恼。
包括待人接物,处理事情,项目管理等一堆烦恼堆积在身边,不知道用什么态度去处理比较好。

晚上一边啃泡面,一边看着Bilibili的中国诗词大会比赛视频。
直接看了决赛获奖者武亦姝的那一场,觉得很喜欢她这种在比赛中的表现与对诗歌的热爱,于是又去看了她之前的比赛。

【中国诗词大会】武亦姝 cut合集的第一个视频中,看到了她的自我介绍与准备。最后在总结时她说了一句:

我是武亦姝,既然来了就做到最好吧。

说话的时候悠然且闲适,仿佛习惯了如此这般。

在电脑面前啃泡面的我,一瞬间触动万千,也想通了很多事情。

编程源于热爱,偶尔也会有不知道如何选择,该去哪儿,该做什么,做到什么样的时候。
现在的话,倒是突然有了自己的态度和想法。

我是刘子健,既然来了就做到最好吧。

生活

如果天空是黑暗的,那就摸黑生存;如果发出声音是危险的,那就保持沉默;如果自觉无力发光的,那就蜷伏于墙角。但不要习惯了黑暗就为黑暗辩护;不要为自己的苟且而得意;不要嘲讽那些比自己更勇敢热情的人们。我们可以卑微如尘土,不可扭曲如蛆虫。

2017-当行远方

又是一年圣诞夜

去年的这个时候,自己全心全意的投入于编程这项活动中。面对着或多或少的质疑,提笔写下了一篇短文《拥抱自己所热爱的,即是正义。》
拥抱自己所热爱的,即是正义。

无关风月,没有胜负。只是心有猛虎,即使只是做困兽之斗,也不甘被任何人束缚。

2016这一年

在前些天写的文章《2016-编程元年》中,有简单的提到这一年做的事情,但是没有细说。现在正好回顾一下。

前端-从一到N

首先要提的还是前端方面。如果说去年的第一次Ajax,让我正式跨入了前端的大门,那么今年所做的一切,都在不断拓宽我对前端的认识, 开始向一名JavaScript Full Stack程序员蜕变。

当然现在很多人是不认同JavaScript Full Stack的。但我觉得,无论用什么语言,能让我以较低的成本,适合的方式去完成一个产品都是值得的。然后JavaScript的出现正好满足了我的需求。

JavaScript

首先要说的,应该就是JavaScript的学习。这一年来积极关注社区动向,努力学习JavaScript的最新规范。从一年前的磕磕绊绊,ES5都很难写好和理解透彻,到现在熟练使用ES6/7去完成任务。同时对JavaScript语言理解的加深,也能利用其“特性”去实现一些小tricks。

包括说前些天写的,利用Decorator去写Koa的路由。中间的Hack意味就非常浓。具体有时间,写篇博客记录其实现方式~

TypeScript-不止JavaScript

另一个突破在于TypeScript,一门转译到JavaScript的语言。
起因是我在用习惯ES6的时候,就在一直思考,有没有一种更好的方式,让我更高效的编写代码,从而提升开发体验与效率。
于是在十一月的某一天,又一次盯上了TypeScript。
是的,又一次……
说来,很惭愧……自己其实在今年四五月份就盯上了TypeScript,可是当时不知道怎么配置环境,也因为各种Typings文件的安装而烦恼……所以一直没有成功。
所幸在TypeScript发布2.0后,情况大有改观,Types文件安装起来简单顺手,自己也开始习惯使用VSCode与默认配色(默默吐槽一句,默认配色真的好不习惯啊……看到的时候简直没有写代码的动力)

TypeScript 2.0发布后,开始学写TypeScript,遇到问题也是积极去解决,而不是躲回原生JS的背后,继续写着和之前一样的代码。同时也在积极寻找项目,甚至创造项目,去用TypeScript写或者重构。

时至今日,用TypeScript还会有磕磕碰碰的感觉,但是比之前顺溜多了,也能完成相应的项目。而Types文件所带的详实准确的代码提示,确确实实的提高了开发效率。类型系统的存在,能极大的减少自己因为类型不清,而出现一些低级问题。

总的来说,感觉还是很棒的。

Koa2-Easy - 不止浏览器端

因为去年对Express的学习和使用,知道了自己对于后台框架的真实需求。
同时苦于每次使用Koa时,装插件的繁琐,于是从零开始,组装了一个适合自己的Koa框架。
自己写了项目的骨架/cli 以及配套的中间件,部署等工具。
经过一次又一次的调试,对中间件的挑挑拣拣,最终搭配成了最符合自己需求的一套工具。
然后放在Github开源了。项目刚开始的时候,还写了一篇《从零组装新工具 - Koa2》

截止到今天,自己提交了148次代码,获得了60个Star。这个也算自己始料未及的事情。
甚至说还有用户,真正的在使用我的框架,认真的去提issue。
感觉,能帮助到他们,自己的产品有人用……真的是好棒啊。

React Native - 不止Web端

在写Web相关应用的时候……看到了Weex的开源,在开发者大会上也听到了CrossWalk这种优秀的跨平台开发工具,还盯到了React Native的蓬勃发展……
自己的心……开始躁动不安了……
开始在思考自己怎么样去做一个App。
今年八月开始,自己接触了Cordove等Hybird App与Weex的解决方案后,觉得都差强人意。堪堪够用但是又感觉缺了点什么,性能和可拓展性都是阻碍自己的原因。
于是决定尝试一下React Native。
七天后,我的第一个App就上线了。

在剩下的日子了,仿佛上了瘾一般,开始疯狂的迭代App。把所有能用JavaScript写的,都写一遍。把不能用JavaScript写的部分,去网上找教程,加入iOS和Android的原生模块。

当然,版本号也从一开始的1.0.0……两三个月内狂飙到5.0.1……
中间也知道了写一个App,与写一个Web项目的不同。提交App给AppStore,却因为截图问题,被打回来好几次。想更新App但是无奈iOS审核太慢,于是尝试了热更新方案。
诸如此类的事情还有很多很多……个中滋味只有自己能够体会。

设计/交互/产品 - 不止前端

曾经有人在一年前问我:“你觉得什么是前端?”
当时我给的回答是:“前端是一个程序员+半个后台+半个产品经理+半个UI设计。前端之所以为前端,就是因为不局限与浏览器的简单前端。而是关注人机交互的‘大前端’。”
现在看来,自己这一年所做的事情,和当时的回答,基本一致。
自己在学习前端相关,计算机相关内容之外,还会去主动学习设计/交互/产品等方面的书籍。并且对我自己的成长起了较大帮助。至少,和一起做项目的小伙伴交流时,不会是抓瞎的状态了。能和他们顺畅的交流需求,知道怎么做前后盾配合更好,知道怎么做,UI和前端的对接更快。这些都是属于自己在学习过程中,得到的宝贵收获。

Docker - 与技术潮流接轨

另一个不得不提的事情,是自己学会使用Docker。嗯,虽然只是简单的使用,但已经确实体验到了Docker在运维上的便利。不用担心每到一台主机上,都得重装环境,也不用担心应用冲突等烦心的问题。
简单的拉取镜像,并且用Docker-Compose一键部署,便可完成复杂的部署工作。
不得不说,会用一些Docker,对于个人效率的提升还是很有帮助的。

开发者大会

七月份,参加了北京的Node Party, 九月份,参加了JSConf。
至于要说收获的话,见仁见智吧……
Node Party上,看到了同为人力资源管理文科生的同学,现在用Node.js用的很6。
也在JSConf,得以见到诸多大牛,与贺师俊前辈的一番交流,更是受用至现在。
到现在还记着贺师俊前辈在我道谢之后,说的那一句话:

“没有什么的,如果我的交流能给你们这些年轻的工程师带来些许帮助,就再好不过了。”

当时瞬间荣誉感爆表……感觉自己在大牛的祝福下,完成了从学生到年轻工程师的蜕变。

算法

嗯……还是不得不提这个。算法与数据结构是心头大患,因为自己数学并不是很好,所以学起算法来会感觉到吃力……
不过还好,自己没有放弃。现在对于算法的掌握程度,可以算是入门啦~坚持多学一点点,虽然工作中基本用不到,但是掌握知识本身,就是一件很开心的事情。

家园 - 从零到一

掐指一算,自己加入家园工作室,也将近有两年时间了。
如果说大学期间自己做的最正确的一件事,那么一定是加入家园。

从接触前端,再到正式入门,直至现在的全面开花,无一不与家园相关。
而自己也从去年的索取者,转向为家园做点什么的贡献者。

在工作室的分享会

16年在工作室这儿,陆续开了三场分享会。
分别是《前端的新方向》,《REM + Flex 布局 》和《你好,校招》。

两个与职业相关,一个则是与自己专业相关。至于效果,只能说自我感觉良好……

开发部の分享会制度

开发部之前,是没有成型的分享会的。有的也只是说个人的小型分享会。
在意识到这个问题之后,觉得应该做一些改进。
于是在开发部这儿,推行了分享会制度。
至于效果,应该算是出其意料的好。每周想分享的人都要排队。

工作室转型 - 阵痛

很快到了学期末,工作室面临着换届的问题。自己努力争取,进入了工作室的中心组(可以理解为决策层)。

因为自己在工作室呆的这段时间,能察觉出不少问题。所以希望自己努力,能去改变点什么。
躲避固然轻松,祈祷纵然心虔,但工作室不会有任何改变。于是带着一车使命感,开始着手去做一些事情。

具体转型的问题,和几个同学+学长来来回回的讨论了两个月。中间的情况也是错综复杂。现在依然在进行转型,转型的怎么样,怎么转,希望明年的总结能给个答案。

有的时候,感觉家园像是一艘艨艟巨舰,而我就是那船长Coco,劈风斩浪指引方向。有时候却又觉得自己只是船上一名普通无比的水手,安心的做好自己的事情就行。最极端的时候,有觉得自己只是船底下的一条鱼,大船将倾,自己却妄图撑起来,结果也只能是被碾的粉碎。

项目管理 - 家园之殇

家园作为一只以产品为主导的团队,那么对于项目的管理自然至关重要。
然而长期以来,大家都使用/习惯使用 QQ 等方式进行交流。
而之前的学长学姐,也进行过类似的尝试,只是都因为各种各样的原因,废弃了。
到了我接棒的时候,依然遇到了类似的问题。项目管理混乱,很少有人知道其他人在做什么,大部分的时间浪费在无效的沟通上。
于是自然而然的产生了和学长学姐类似的想法,引入项目管理工具。
只是这次,是在充分调研和实践的基础上进行的。自己先是在各类项目管理工具的使用和调研基础上,选定了Teambition,并在部分小部分项目中使用。
后期也联系上了在Teambition工作的学长(人超级nice呀~)。最后因为收费等问题,切换到了Tower。

按照网站的历史,是会举办寒假比赛的。恰巧在引入Tower的时候,寒假比赛刚刚开始。于是将Tower算作考核项,开始推广给他们使用。也算是意外之喜吧,大一的学弟学妹对Tower不排斥,而且上手速度也很快。

这个事情依然在进展,希望井然有序的项目管理能对工作室有所帮助。

产品成长

家园作为一只以产品为主导的团队,产品的地位是很特殊的。
然而由于产品经理其职位的特殊性,基本属于可遇不可求的状态。
所以一直在思考,该怎么做,才能培养出产品经理,带领家园的产品向前走。

最后确定的方式是,给最大的硬件资源支持,给最大的人力物力支持,让他去折腾。
于是工作室这儿,一咬牙掏出了老底……出资购买了产品经理微专业。
希冀对网站的产品经理成长,有所帮助。

人才培养与更合理的招聘制度

身处南昌,互联网环境堪称贫瘠。
这是我在探索家园如何更有效的培养互联网人才,最深的体会。
整个的大环境不好,招人就难招。然而孤掌难鸣,只靠我们几个大三的,也很难保证走了之后,还能撑的下去。
于是在苦苦的思考过后,决定采用内部培养+外部招聘的方式进行。
内部好好培养,对外则改变一年只招新一次的方式,开始多次招新。
在招新的形式上,也改变之前一二三面就决定的情况。开始向互联网公司的招新形式靠近,同时结合学生的特点,开始做一些新的尝试。

具体的方式,看明年的培养效果。如果好的话写篇博客补上。

家园的核心

家园真正的核心是什么。
毫无疑问,是人。
无须赘述。
所做的一切一切,尽以人为本。只是时间和精力有限,做不到尽善尽美。

自我评价

这一年来,所作所为或许有可取之处,或许也有错误的地方。
有些东西,可能要好几年后才能看到结果。
总而言之,对于自己的评价:

已尽力而为,问心无愧。

生活与工作

这一年下来,生活方面,没有什么太大波澜却也没有什么太大的惊喜。除了感情方面,别的方面都挺顺利的。

身体方面的话,能明显感觉到是不如去年的。因为种种原因+自己懒,所以并没有去健身房健身也没有下去跑两圈。

工作

从今年三月份开始,就尝试着找大二的实习。
很幸运的接到了两份Offer,权衡再三后选择去了北京。

很高兴能遇到小兰姐这么棒的Leader,两个月的时间内基本全部在写JavaScript,这也使得我对JavaScript的理解进一步加深。
中途出去封闭开发了两周,遇到了非常棒的前端总监威哥。每天就是跟在威哥后面,听威哥去做分享,给我做CodeReview,看着各式各样炫目且实用的技巧。感觉对自己的成长帮助很大。那两个礼拜,也是过得“最无忧无虑”的两周。每天出门就是写代码,也不用挤地铁啥的。

做自己想做的,成为自己想成为的。

生活

生活的话,在北京也碰到了超级Nice的朋友/合租室友,还有超级暖的房东大哥大姐们。
感觉如果需要写下来,能写满满当当好几页~

2016,一生想做浪漫极客

在去年写的文章《2016,一生想做浪漫极客》中。黄玄学长送了一句寄语给我。

@Lxxyx 是一名大二的文科生,在本文中讲述了他因为兴趣走上程序员之路的故事。摘一段乔布斯的话作为寄语吧:「Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven’t found it yet, keep looking. Don’t settle. As with all matters of the heart, you’ll know when you find it. 」

很喜欢这句话,希望有缘看到这篇博客的你,也能找到自己所喜爱的事业。

2017-当行远方

17年到了。自己在今年也得正式的去面对春招,校招,找工作,是否考研等一系列事情。
这一切一切的事情,自己都不确定。
唯一能够确定的是,17年,自己会远离家乡,远离昌大,去往遥远且不确定的远方。
在大学的温室呆了太久,每日的生活就是寝室->机房->食堂的往复。
生活过于安逸的结果就是,容易自视甚高和自己感动自己。

去年在知乎上看到一段文字:

这些年我一直提醒自己一件事情,千万不要自己感动自己。
大部分人看似的努力,不过是愚蠢导致的。
什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。
人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。
——于宙《我们这一代人的困惑》

于是每当自己沉迷于安逸的现状或者开始自己感动自己时,便不断的去警醒,去催促,去推动自己走出去,去见识更广阔的天地。
去看看外面都市的繁华,去看看远方的山川河流,去见识各路大神,然后再被惨虐一番。

成就感

成就感是个好东西。但是一直沉迷于成就感,容易毁了自己。
这一点在16年中体会极其深刻。当做到很多别人暂时做不到的事情,自己的内心会像气球一样膨胀起飞。
这时候,只有靠着自己所剩无多的理智,自己亲手去把气球戳破。

就那种,“Pa!”的一声,整个人摔在地上,摔成一张饼那种。

每每戳破气球的时候,自己就会开始庆幸,又跨过了一个坎。
如果真的一直沉迷过去,沉迷那种虚假的成就感。迟早💊。

生活的正轨

自己在某些时候,会觉得这是生活在正轨的状态。
出现一些问题,自己处理完成的时候,也会有种生活回归正轨的状态。

于是很多时候就会去思考,什么才是生活的正轨。
究竟我一直所感觉,所认同的生活正轨是什么。

在一次回寝室的时候,自己突然想通了这个问题。
所谓的生活正轨。

“自己能掌控自己的生活节奏,朝着目标稳步前进,进步明确的状态。”

换成游戏里的行话,就是“带节奏”。只是玩家就我一个,输了也不会复活。

在这种状态下,由于“把控”了生活的节奏,自己在处理事情,学习新东西,思考各类问题的能力都会有较大的提升。
这一点,在半年前准备做但最后没有讲出来的分享中,有所提及。


17年-对自己的新期待

在代码方面,希望能写出更好的代码,包括但不仅限于可读性强,效率高等。希望自己具备解决一些复杂Case的能力。

团队管理方面,希望自己能带好家园,给家园带来最新的,互联网公司的氛围。推动家园向专业化学生团队发展。
尽管南昌互联网土壤贫乏,家园依然要努力开出最美的花儿。

生活方面,希望自己能够多注意身体,多去运动,毕竟活着最重要。

感情方面,希望能够遇到自己的那个她。

2017 - 终将远方

带着2016年的热枕与对2017年的期待。
前方路漫漫,且行且歌!