工作两年的一些感悟

By | 2020年6月26日

时间挺快,转眼工作快两年了。工作前从不会写代码,到理解互联网后端研发的工作职责,到跳槽承担更大的责任,过程中踩过很多坑,也有很多的感悟。这里想要分享一下,希望能够给后来者一些帮助。

在读研期间,我们实验室是做生物医学方向的,再加上本科并没有计算机相关的基础(本科的专业是「弹药工程与爆炸技术」),在准备求职时有点丈二和尚摸不着头脑。看过软件开发的书籍(计算机系统介绍书籍、C++/Java等语言类书籍、算法导论等算法类书籍),也看过现在的所谓算法类的书籍(《统计学习方法》、《机器学习》等)。看过的很多,但是真正沉淀下来的不多。

现在看来这些书籍都是非常重要的,也非常值得去阅读,但是为什么自己都没有沉淀下来呢?这个问题我想了很久。到了工作渐渐有些沉淀,会发现之前的思路是有些问题的。之前看书更像是学生阶段的那套思维:看书 -> 记下来知识点,只是最后没有考试这一环。但是对我而言,由于没有相关的编程经验,更没有工程经验,这么多琐碎的知识是不太可能都记下来的。正确的做法应该是,大概有个方向,然后再去有针对性的积累,这样效率最高。

反思了读研和工作以来的经历,有很多思路上的转变,我将大的思想转变都浓缩在这篇文章中了。

这篇文章会讨论几个方面:1)业务与技术的关系;2)战力与潜力;3)收入与个人成长.

业务与技术

在读研期间,我是从事计算机视觉相关工作的,当时课题的方向是CT图像肺结节检测。最后完成的工作就是使用深度学习去做CT图像的肺结节检测任务。当时的自己对课题方向不是特别感兴趣,伴着对求职的信心不足再加上有点急功近利,走了很多的弯路,甚至错失了很多机会。比如,一直去跟最新的技术,却没有仔细思考这些技术应用在不同场景的区别;再如,由于对课题不感兴趣,导致自己没有深入地在一个场景上系统地探寻问题的解决方案;又如,自己急功近利看了很多书籍,但是却没能把这些知识系统化地消化吸收。

导致这些问题最重要的原因之一,就是当时的我没能认清「业务」与「技术」的关系。

什么是「业务」?什么是「技术」呢?拿我上面的例子而言,业务就是「检测CT图像中的肺结节」,技术就是「使用深度学习的方法做检测任务」。「业务」即是我们需要解决的问题,「技术」就是我们使用的方法。

面试的时候面试官考察一个候选人,会考察哪些内容呢?最简单的说就是,「解决问题的能力」。那么怎么考察这个能力呢?最好的方法就是,在你的业务领域,如何用技术解决当下的问题的。

怎么理解这句话呢?

还是以我的课题为例。课题的业务方向是「检测CT图像中的肺结节」,那么这个业务方向会引申出很多问题,比如:CT图像是如何存储与读取的(即它的数据结构是什么样)?肺结节有哪些特点?使用计算机存储后如何能够被识别出来?而技术方向,也能引申出很多问题,比如:深度学习有哪些做检测任务的框架?不同框架有哪些特点?框架演变的原因是什么?检测任务和分割任务有什么区别?深度学习比传统的机器学习方法解决图像问题有什么优缺点?当然还有很多技术细节的问题可以问。

对上面问题的回答,就能体现出一个人的「解决问题的能力」,这其实就是一个系统的解决问题的思路——我们可以用哪个指标描述我们的目标,从而进行优化?我们的场景可以提炼出哪些信息(特征),参与到目标的优化当中?我们使用什么优化方法,更适合当下的业务场景(或者在得到可接受的结果时成本较低)?你的解决过程又是怎样的?

上面是现在算法同学面临的问题。我的第一份工作是美团推荐广告的后端研发,这个是一个研发方向,同样可以拆分成为「业务」+「技术」的组合。业务方向是「推荐广告」,那么引申出来的问题就可以有:广告如何竞价?用户在使用App时可以获取哪些信息使用在推荐策略中?技术方向的问题可以是:广告系统应该设计成什么样(广告系统应该包含哪些模块)?美团这样大的业务量下,如何应对三高(高并发、高性能、高可用)问题?一个应用在广告场景下的系统,针对流量变现是否有哪些优化(从而加快流量变现效率)?还有就是编程的相关知识了。

这也就是为什么那些有项目经验的人,更容易被录取,因为项目经验背后的潜台词是你有一定的工程经验,有了工程经验后可能就会有一定的工程思维。如果你仅仅看书,想把书上的知识点都记牢是很困难的。

(面试经验可以参考我的这篇文章《2018计算机校招的思考》)

上面分别分析了现在算法和后端两个方向的「业务」与「技术」,我将这两个方向均概括为:「面向业务编程」。对于算法方向,就是应用已有(或者说是已经成熟)的技术或者方法,针对业务场景进行取舍调优;对于工程方向,就是想清楚业务特点,搭建一个支撑对应业务的系统。

所以我认为,刚刚接触工作的同学,一定要养成一个好的习惯,梳理清楚业务流程,想清楚业务模型,这样才会事半功倍。

如果在研究生期间的我能够想清楚这些,我绝对不会盲目的把时间花费在各种书籍都浏览一遍,而是针对课题尝试不同的方法,想清楚不同方法之间的优劣,不同框架之间更迭的原因,这样就是有了一套系统的工作,在面试时也就能游刃有余了。

即战力与潜力

大概到新公司45个月的时候,我经常工作到很晚,压力也会很大。那段时间其实也比较开心。为什么这么累、精神压力大还很开心呢?因为那时候我是三个业务线的负责人,其中有两个还挺重要的。由于我花的时间很多,很清楚上下游的定位及功能,出了问题很多合作的业务方和兄弟团队都会向我咨询,同时自己长期还算不错的表现给自己带来了一定的话语权。那段时间自信心也得到了提升,甚至有很多时候和比自己高两、三个职级的人在会议上怼起来(创业公司经常会和比自己高职级的人开会),气场也不输。

起初一段时间自我感觉良好,但是过了几周发现这样的节奏不对:我花了更多的时间去熟悉业务与链路,虽然在自信心、话语权等方面有所提升,但是换个环境,我还能表现成这样么?或者还有这样的机会给我表现么?

其实抽象过来就是,我牺牲了很多的休息时间,得到了大家的认可,换来了一定的公信力与话语权,但是长期看这些经历(经验)给我的能力带来多少提升呢?

于是我将能力的种类分为「即战力」与「潜力」,感觉这样更容易评估自己的提升。「即战力」是能够为当下、短期内带来很大收益的能力;「潜力」是能够在一个较长时间跨度内,为我带来持续、稳定收益的能力。那么我通过加班熟悉业务以及链路流程,更多属于「即战力」,也有部分属于「潜力」。「即战力」的部分来自于我对这个业务与流程的理解,我在做这块业务时能给自己带来收益,但是如果因为某些原因我换了业务甚至换了公司,那么这些就都要重新来过了(互联网行业变化很快)。「潜力」的部分来自于我通过刻意熟悉当下的流程,对类似的业务和系统有了更多的思考,同时由于我不停参与不同合作方(产品、运营、算法等)的讨论,我的解决问题的思路以及表达能力都得到了提升。但是前者会更多,因为前者的时间占比更多。

想到这些,我就开始思考该如何平衡「即战力」与「潜力」了。

哪些时候更适合提升「即战力」呢?刚到一家公司入职时,我们需要向老板和合作伙伴们树立一个良好的形象,提高公信力,告诉他们我是一个好的(产出高、乐于合作、乐于分享的)下属/合作伙伴,这个时候我们就需要花更多的时间熟悉业务,做些脏活累活提升公信力,花更多的时间在「即战力」上。未来某个固定的时间有晋升或者好的项目,我们也需要花更多的时间在「即战力」上,多做些工作得到更多的赏识,争取得到这样的机会。如果是短期没有什么提升,即没有好的项目或者机会提升自己,又没有什么窗口的限制,是不是就需要考虑猥琐发育、韬光养晦,来提高自己的「潜力」,从而在未来能够有实力(甚至有更好的精神状态)来挑战更重要、更困难的任务呢?

我个人认为,「即战力」更多是熟悉程度,「潜力」更多来自于基础的扎实程度、视野、理解力、表达能力甚至人格魅力等。

收入与成长

以前常听前辈们说,工作初期薪水差个几千块不重要,当时我还有些不太理解,自从理解了一句话之后——「人的收入不是线性增长的」——发现确实是这样。

在工作初期,大部分人工作的内容都不是关键性的,更多偏向于完成工作,而不是设计一套在部门中非常重要的方案。初期不同人的工资虽然也会波动,但是由于所做的工作内容重要性没那么高,薪水的浮动应该还是比较小(其实一个月差几千块并不多,眼光放长远一些)的。工作到了一定阶段,你所做事情的重要性也变得更高,那么收入的浮动就会更大了。虽然在同一家公司可能体现的没那么明显,但是一旦跳槽,收入状态可能会大幅改变。

在一家公司的薪水职级影响因素很多,比如公司的发展状态、和领导的关系、你做事情的重要性等等。而这其中有些你不太能掌控,或者由于入职先后等,不太能自己控制。比如我在前司有一个同事,由于他是别的组合并过来的,晋升时一直没有得到好的结果(那么薪水大概率达不到他的预期)。同时,他的能力真的挺强,后来他跳槽去了腾讯,薪水大幅提升,职级给的也非常高,一下就弥补了之前薪水不合符他工作能力的问题。短期看可能你的收入不符合预期,那么不要急,掌握住了核心能力之后,收入会符合你的能力与付出的——毕竟薪水是在你的价值上下波动。像我上面举例的那个家伙,他在我们当时的部门中,能独立撑起一块业务,即使由于当时他在组里面不是「嫡系」部队,市场也在他跳槽的时候回馈了之前他的努力。这也验证了收入不是线性增长的。

同时,你会发现,单一的技术往往不是最有价值的,最有价值的是「解决方案」。在当下的业务中,如何系统性地解决最核心的问题或者痛点,才是稀缺的。所以你可能就需要把更多时间花在这些方向上。工作初期一般不会让你去担当如此重任,你就需要思考你当下系统中核心的部分是什么,痛点可能是什么,如何能够解决,争取早日参与到解决此类问题当中。这样,才会让你成长得更快。

这是我两年中一些重要的思考,肯定还有很多不完善的地方,还欢迎大家多多留言参与讨论。如果感觉写的好,希望大家能够帮忙关注、转发,也分享给更多的同学。感谢大家。


在微信中长按下图中二维码选择识别,就能关注该公众号

[Java]并发编程(一)多线程相关的基础知识及概念

By | 2020年1月4日

1 并发与并行

并发是指在某个时间段内,多任务交替处理的能力。并行是指同一时刻处理多任务的能力。在并发环境下,由于程序的封闭性被打破,出现了以下特点
1)并发程序之间有相互制约的关系。 直接制约体现为一个程序需要另一个程序的计算结果,间接制约体现为多个程序竞争共享资源,如处理器、缓冲区等。
2)并发程序的执行过程是断断续续的。 程序需要记忆现场指令及执行点。
3)当并发数设置合理并且CPU拥有足够的处理能力时,并发会提高程序的运行效率。

2 线程的五种状态

为方便理解,可以认为线程在其生命周期中有五种状态:新建状态(New)就绪状态(Runnable)运行状态(Running)阻塞状态(Blocked)终止状态(Terminated)。他们之间的关系可以表示为:

3 创建线程的三种方式

1)继承Thread类;2)实现Runnable接口;3)实现Callable接口

4 线程的内存分配

每个线程拥有自己的虚拟机栈(Java Stacks)、本地方法栈(Native Method Stacks)和程序计数器(Program Counter Register)。虚拟机栈包括局部变量表、操作栈、动态链接和方法返回地址等。

5 线程安全

在一个多线程环境的程序中,当程序结束时能够得到预期的结果,那么称这种状态为线程安全。单线程中,永远是线程安全的。

6 线程交互的可见性

6.1 指令重排(Instruction Reordering)

编译器在编译代码时,为了提升CPU的工作效率,会对指令进行重新排序。在并发执行的情况下,重排序可能导致意想不到的运行结果。

6.2 原子性

一个不能被分割的操作叫做原子操作。非原子操作在并发条件下会得到意想不到的结果,如下例:

public class Increment {
    private int value;
    private static final int TIMES = 10000;
    private static final int THREAD_NUMBERS = 20;

    public void increase() {
        value++;
    }

    public int getValue() {
        return value;
    }

    public static void test() {
        Increment increment = new Increment();

        Thread[] threads = new Thread[THREAD_NUMBERS];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < TIMES; i++) {
                        increment.increase();
                    }
                }
            });
            threads[i].start();
        }

        for (Thread t : threads) {
            try {
                t.join();
            } catch (InterruptedException e) {

            }
        }

        System.out.println("result:" + increment.getValue());
    }

    public static void main(String[] args) {
        test();
        /*
        输出(一个小于200,000的值):
        
        result:71641
         */
    }
}

6.3 可见性

可见性是指,当一个线程修改了共享变量的值,其他线程也能够感知这个修改。因为每个线程拥有自己的工作内存,所以一个线程的操作不是对其他线程都可见的(每个线程在运行时会有自己的工作内存,工作内存的值会不停写回到主内存)。

6.4 volatile关键字与Happends-before原则

volatile关键字的作用有两点:1)保证volatile修饰的变量的可见性,即每次有线程更新共享变量时,其他线程也可以感知到此更新操作;2)禁止指令重排序优化。由此可见,volatile只有在多线程程序中,才有用处。

Happends-before原则是一种偏序关系:有两个操作A和B,如果A操作happends-before操作B,那么A操作就会在B操作之前发生,且A的所有改动对B都是可见的。记做hb(A, B)

Happends-before原则包含以下几条:
1)程序次序规则(Pragram Order Rule):在一个线程内,按照程序代码顺序,书写在前面的操作happends-before于书写在后面的操作。准确地说应该是控制流顺序而不是程序代码顺序,因为要考虑分支、循环结构。
2)管程锁定规则(Monitor Lock Rule):一个unlock操作happends-before于后面对同一个锁的lock操作。这里必须强调的是同一个锁,而“后面”是指时间上的先后顺序。
3)volatile变量规则(Volatile Variable Rule):对一个volatile变量的写操作happends-before于后面对这个变量的读取操作,这里的”后面“同样指时间上的先后顺序。
4)线程启动规则(Thread Start Rule):Thread对象的start()方法happends-before于此线程的每一个动作。
5)线程终止规则(Thread Termination Rule):线程中的所有操作都happends-before于对此线程的终止检测,我们可以通过Thread.join()方法结束,Thread.isAlive()的返回值等作段检测到线程已经终止执行。
6)线程中断规则(Thread Interruption Rule):对线程interrupt()方法的调用happends-before于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测是否有中断发生。
7)对象终结规则(Finalizer Rule):一个对象初始化完成(构造方法执行完成)happends-before于它的finalize()方法的开始。
8)传递性(Transitivity):对于操作A,B和C,如果有hb(A, B)hb(B, C)那就可以得出hb(A, C)的结论。

理解Happends-before原则有什么用处呢?先来看下面的例子:

T1
x = 5;  // 语句1
y = 6;  // 语句2
T2
if (y == 6) System.out.println(x);  // 语句3

x, y初始值都为0,那么T2的输出可能是5,也可能是0。因为在T1线程中可能会对两条语句进行重排。从上面的happends-before原则1)可能会推测,x = 5这条指令一定会在y = 6之前运行,实际上是错误的。对于T1来说,语句1和语句2谁先执行谁后执行不影响最终的一致性,所以可能因为指令重排导致先执行语句2,在执行语句1,那么语句3的输出就是0了。

参考:

在美团点评的那些日子

By | 2020年1月1日

一、初窥上海

我足足发了一个小时的呆。

18.07.02大学同学结婚,跑了个龙套客串了一下伴郎。晚上又急急忙忙乘高铁到上海,到租的房子那边的时候已经十点半了。

18.07.03晚上又看了看前一天拍的照片,回顾了一下昨天见到的三年未曾相见的那群大学同学,恍如隔世。

年岁渐长,我仿佛明白,人生是个不断和故友道别的过程。

18.07.04又是忙碌的一天。打扫之前租好的房间、去超市置办常用的生活用品、观察周边有哪些店面……

毕竟这不是第一次来到上海。之前来上海,或是旅行,或是面试,看到的只是它令人向往的那个侧面:大都市繁华的街景以及更多元的工作机会;而今天的一番经历,体味到的是真正在上海生活的那些事儿:吃喝拉撒,柴米油盐。

这天傍晚,我到隔壁的菜场买了点熟食当晚饭。匆忙的步履、拥挤的人潮、漫长的红绿灯以及饮食习惯不同造成的不合口味的饭菜……在吃完饭后,我呆坐在客厅中,不断翻看昨天同学婚礼上的那些片段。甚至还发了条朋友圈。

可能是昨天情绪溢出太多了吧。

有时会和一起毕业的小伙伴儿聊聊上海,大家的感受多是,在为上海的建设做贡献,并没有享受到太多这个城市发展所带来的繁华……

二、房东奶奶

「租房子要在意是否和房东直接签合同,同时要看到房东的房产证以及身份证」。租房子前上网看了一下租房的注意事项。

签租房合同的时候房东即没带身份证,也没带房产证。她说我们这边都不用带的,不过中介也要求需要看到房东的房产证,房东说晚上回去会用微信补发给中介。于是我也顺带要求把身份证发给我看一下。

房东看上去年纪不小了,但是由于我对事情的判断都很不准确(比如人的年纪、房间大小等),再加上这是第一次见面,未敢直接询问。一个小情景还是验证了我的猜想:房东在擦拭窗台的时候,手已经会发抖了,是不由自主的那种。从我个人的经验来看,这都是上了年纪的人所表现的特征。

晚上房东遵守了诺言,发来了身份证。我在意了一下年纪,竟然已经77周岁了。

「沈老师看上去显得挺年轻的,未来一年也麻烦老师照顾了」,我回复房东奶奶的微信。因为之前她是老师,她喜欢我们这样称呼她。虽然这些话语中略有恭维对方的色彩,不过房东奶奶确实显得很是年轻,而且这么多事情也自己操持。其实我也挺喜欢称呼别人奶奶,因为称呼她阿姨,显得自己年纪太大了。这个年纪的人,也够自己奶奶辈分了。

「你们太客气了,有什么事(可以直说),也不用客气。就是我现在住的地方到你们那里比较远,能帮的上的,还是会帮你们的。你们刚到上海,人地生疏,有什么事咨询一下也不妨。微信把我们的距离拉近了,作为长者也应该尽力帮助」,房东奶奶回复说。

初到上海,需要办居住证。我们和房东奶奶约定了时间,一起去派出所办理。

「你们起床了么?」周六9点左右,我的电话响了,是房东奶奶。

「我们在外面买饭来着,马上就回去」,我说。没想到房东奶奶这么准时,之前我们约定的时间就是九点,因为我们起床了看还有些时间,就想着先出去买点早餐,也不会耽误很久。

跑回租的房子这边,房东奶奶微笑着站在门口。

「抱歉,抱歉,我们以为您可能会稍微晚点,起床后又有些饿了,就出去买点东西。让您久等了」,我给奶奶鞠了个躬,表示歉意。

「没事,没事。我以为你们是因为平常工作忙,周末会想着睡个懒觉。能理解的」,房东奶奶说,同时没有半点埋怨的意思。

在几次交流之后,和房东奶奶慢慢熟悉了起来,在去办理居住证的路上聊了一些关于奶奶的事情。

「沈老师您住哪啊?」我很好奇她竟然九点就到了我们这边。

「我住在闵行的XX小区,离这边太远了。要先坐地铁,再坐公交,路上的时间大概要一个半小时」,房东奶奶说。

「那您起的好早啊,竟然这么早就到这边了」,我惊讶地问道。

「我早晨都忙完很多事了,之前还带我老公去了医院验了下血。哎呀,现在的科技真发达,我们去医院,都不用排队了,刷下身份证很多事情就都解决了」,房东奶奶回答说。

「您看,今天还真麻烦您跑了一趟。毕竟我们工作日都要上班,只能麻烦您周末来这边,这跑的大老远的,也挺费事儿的」,我对房东奶奶的操劳表示了下谢意。

「也幸好派出所周六上午能办理居住证,不然我们还真的麻烦呢。工作日我也有事,女儿要上班,外孙女还要照顾。周六了,女儿休息,孩子能交给她照顾」,房东奶奶说。

房东奶奶的房产证上有三个人的名字,但是只带了自己的身份证过来,最后没办成,需要下周再来弄一下。

下周她又准时过来了。这回我和她聊了更多。奶奶1961年就上了大学,当时身体不好,医生还误诊了,差点没毕业,而且因祸得福分配到了上海长宁区当老师:当时党员要分配去新疆、团员要分配去近郊。还聊了她当过团支书、辅导员、班主任的事情。她非常喜欢当班主任,因为这样可以和学生的关系更近一些,不过也为此操劳很多。

「在我们小城市,这个年纪早都应该颐养天年了,您还操持那么多事情。而且还真没看出来您年轻的时候身体不好,现在感觉您精神状态挺不错的」,我笑笑说。

「有些事情也是没办法啊,毕竟孩子也忙,我们能帮帮孩子就帮一帮,而且我也很喜欢帮助人的」,奶奶也笑笑。

之后我和奶奶又聊了许多。她问了我家庭的情况,我又问了更多关于奶奶早年的经历。

「人生确实会交织着很多苦难啊!沈老师今天说的也让我学到了很多。老师回去路上注意安全啊」,奶奶离开前我嘱咐说。

三、踏上职场

「上班一点都不好玩儿」,我在大象(公司的通讯软件)上发了个消息给室友。

现在租房的室友恰好是研一的室友,还在一个公司,总算是多了个可以扯淡的人。室友人也非常nice,也包容了我很多。

每天早晨通勤的时间有将近一个小时;几千人的园区食堂大概只有十个菜不到;我们组人太多了,工位不够两个人挤一块儿。刚到德必易园的时候是这样的一番景象。

「唉」。

当然,这边也有很多值得庆幸的地方:同事间关系都很好,印象最深的地方就是吃饭大概有十来个人一起,吃饭的时候还会打王者荣耀;公司的文档还算全面,同时也在不停完善,从这也能看出一个公司的技术储备以及眼光是否长远;这边leader做事情也挺负责,主管对我们组每个人的事务都很清楚。

而且,去年也开始在饭否上关注了王兴,在他的饭否动态上也学到了很多。印象最深的一个动态是:「『大多数人以为战争是由拼搏组成的,其实不是,是由等待和煎熬组成的…』说这话的大哥当年参加过中越战争,后来创过业,现在做投资。」

我们组每周四会有个大组会,每个月的第一周会给这个月生日的员工过生日,然后再随便聊些八卦。恰好我入职的第二天就经历了这样的周会。

我之前晚上走的都挺早,但是在第二个周会上发现大家一周都能做那么多事情,于是当时我暗下决心,准备晚点走。可是,到了十点,我发现我走的次序和平常八点离开的次序差不多……基础不足、人还笨……以后要加油啊。

也是那天加班的晚上,七点半本来有个会,code review。快到了七点半左右,一个妹子来了个电话,上来就是称呼我的名字(不加姓)。听到这样称呼当时真的吓到了。我本来就不太习惯别人直接称呼名字,我挺喜欢别人叫全名的(姓氏+名字),这还是一个妹子打来的电话,当时真觉得……别扭……她大概介绍一下我就意识到下午有个运营那边的妹子提了一个需求,让我们晚上完成,应该是来催任务的。

「抱歉,我这边有个会,没看到大象上您的消息。这边需求我们已经解决了」,我说。

「哦哦,那知道了,也谢谢了」,对方说。

其实,我真的会想,为什么……大家工作都那么有激情……都这么晚了还因为工作去打电话……

晚上回来和室友分享了运营妹子来电话的事,室友调侃说:「你不趁着机会拖一拖需求,多跟她聊聊,而且这还是直接通话的。」

「诶,好像是这个道理唉」,我笑笑。

之前参加同学婚礼的时候,在车上和一同参加婚礼的其他人聊天。他们各自聊了自己的工作,还聊了房价,最后还说学校其实挺好,工作了太忙。

在我看来,学校和工作都很忙,只是方向不同。就像房东奶奶,都年近耄耋,不依然操持着一家上下么。

四、蒲淞北路60号

出了小区的门左转,沿着金钟路直走,穿过一个菜场之后,顺着北翟路走到一个路口,右转到蒲淞北路,便是公司新址了。

这段路程本身并不远,可能由于这是我上下班经常走的一段路,所以印象也就格外深刻了罢。

记得那是18.10.23晚。10.24是我经历的第一个程序员节,公司早早地拉起了横幅。当晚上线后有两个小的报错,虽然也不算特别严重,不过自己还是想要修复后再走。定位Bug花了很久,然后又由于自己手误多打了个字符导致无法打包,弄完了都快十点了。大部分的机器上线后,已经有11点半了,那是我第一次因为上线弄到这么晚,还是挺有趣的。

记得那是18.12.25晚。当时一个业务方的接口需要升级,快到deadline,升级完jar包之后总是出错,最后定位问题也是弄到了接近12点。那天应该是我18年打卡最晚的一天了。深夜里,室外并不算特别冷,我奋力地蹬着单车回去,迎面吹来的风中也洋溢着喜悦。

周末闲暇时我喜欢去公司的健身房跑步。实话实说,我是蛮喜欢这种两点一线的生活——Keep it simple and stupid也是我一直崇尚的方向了。从北翟路转到蒲淞北路是一个下坡,骑着单车转弯后就不需要再蹬脚蹬,一路车子能够滑动一、二百米,然后直接停到公司门口路边指定的停车区。在停车前会经过一个限制机动车通行的栏杆,间隙大概只有40、50公分,借着车的惯性直接停稳还需要用一点巧劲儿,那种感觉真的挺爽的。怎么形容这段路上车子滑行的感觉呢?大概像是《老炮儿》结尾处的那个鸵鸟狂奔在大街上吧。

在下班的途中必定会经过那个菜场,那段路上是卖水产的,晚上小商贩会收拾关门,收拾鱼虾脏水也就直接倒在路边,腥味扑鼻。就是这样一条每次遇到同事都会吐槽脏乱差的街道,在我离开后偶尔再经过也竟有些怀念了。之后,那块菜场也被拆了。

有时,路边会看到一个老妪,背弓到了大概90度,在捡垃圾。路灯下的倒影显得动作格外矫健。这里也是摩登大楼、霓虹闪耀的魔都。

五、接纳自我

我并算不聪明,可能还有些愚钝——随着年岁的增长,我渐渐认清了这些。而且,我好像是个无趣的人——我并不是特别喜欢看电影,现在也几乎不看电视了,对吃喝的兴趣也不是特别大。不过,我倒是慢慢喜欢上独处时「面对真实的自我」的那种感觉了。

其实,从大约初中开始,我一直都不认为我是一个和自己相处融洽的人。我感觉自己的记忆力不如别人好,成绩也一般,很多人情世故也不善处理……我也努力尝试着改变很多……但是,我依旧发现和身边的人差距很大……倒是工作后,我渐渐开始正视自己的优缺点,开始沉下心来反思自己、磨炼自己了。在花了很长时间思考自己真正想做的事情之后,反倒是自信了很多——每个人的目标都是不同的,把注意力花在和别人比较上对实现自己的目标可能是无用的,应该花更多时间去提升自己,朝着自己憧憬的方向积累、试错。

「真的猛士,敢于直面惨淡的人生」,在接纳了这些之后,我经常这样调侃自己。毕竟,承认自己愚钝确实需要有挺大的勇气罢。

随着在工作后渐渐接纳了自己以后,我还理解了一个很重要的事情,那就是「工作会占据你生活中很大一部分比重」。

乔布斯曾在2005年斯坦福大学的毕业演讲中说到:

You’ve got to find what you love, and that is as true for work as it is for your lovers. 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, and don’t settle.
你必须去找你热爱的东西,对工作如此,对你的爱人也是这样的。工作会占据你生命中很大的一部分,你只有相信自己做的是伟大的工作,你才能怡然自得。如果你还没有找到,那么就继续寻找,不要停。

王小波在其《工作与人生》中,也花了很大段落阐述「工作是人一生的主题」。

记得以前去北京找同学玩吃全聚德的时候,北京烤鸭上只有几片烤鸭皮,看起来晶莹剔透,嚼起来又脆又酥,口感确实绝佳。在那时候的我看来,全聚德这种地方还挺奢侈……当时同学想把这些都留给我吃,我觉得有些腻了就说算了,然后被同学调侃这辈子没口福。之后想想,可能还真是……

六、意料之外

我没有想到过这么快就会离开,就像我曾经也没想过自己会有幸加入这个优秀的公司、加入这个优秀的团队一样。

今年年初部门主管离职,组织架构调整。做为一个入职半年的毕业生,影响也没有特别大,还是做着同样的事儿。调整后的部门在过了一段适应期之后,大家的工作也又井井有条了起来。

伴随着一连串的雨季,今年上海的夏季感觉来得稍晚。连续阴雨放晴后的天气,显得格外喜人。鸟语伴着花香,简直神清气爽。

那是初夏的一个周五晚,我突然想再看一遍大学时期看过的一部非常著名的电影——《肖生克的救赎》——那可是IMDB的top 1。当时也是被这个名头吸引过去的,虽然第一次看完之后只是觉得震撼,然后就没有然后了。

工作后依然被那些事情困惑着,譬如我是谁,譬如我从哪里来,譬如我该到哪儿去……这些问题也和朋友们聊过很多次,他们告诉我,是我想的太多,做的太少。想想也是。

那天晚上我花了足足两个多小时,静静地看了一遍《肖生克的救赎》,看完已经是凌晨两点多。

But I tell you these walls are funny. First you hate them. Then you get used to them. Enough time passes you get so you depend on them. That’s institutionnalized.

Get busy living or get busy dying.

在当晚决定重温这部电影的前一秒,我都没想过会把它看第二遍……

七、情理之中

感谢!

一路走来,自然而然,还是源自大家的帮助。这部分也不用详细展开了,总之,感谢那些包容我,帮助我的大家伙儿!

人生是一场有趣的旅程:)

19.12.29 于上海新泾六村居所


扫描下图二维码就能关注我的微信公众号