海阔天空的云

我们在自己的世界里独自狂欢

0%

前两天,我司我这个小组来新同事,于是大家一起吃了个饭,席间,竟然谈到了香港问题。

简单地,也来说说我的理解。

  1. 之前写的 港片和回归 以及 香港是袭人,英国是雷锋 。 这两篇都是两年前我写的,当时正是香港回归20周年的时候,其实那个时候,就已经从外网能够看到很多不和谐的信息,主要集中在普选的问题上,再往前推到14年左右,也是能够看到很多关于香港的流言蜚语,所以我也一直很关注香港。

  2. 我也没有去过香港,但一直都对香港有些好感,可能也是因为看过很多港片的原因。

  3. 香港问题,就像是我之前写的两篇文章提到的,很复杂。不能够直接说,你们连国都不爱了,还谈什么皿煮。

4.关于香港的报道,大陆这边宣传地也不客观,香港那边宣传地也不客观。大陆这边不会报道香港这次大游行地起源和所谓的五大诉求,香港那边也很少报道警察怎样受到抗议者的伤害。这也很难找到制衡点,只好都看一看,然而,越看越是难以得到一个轻易的答案。

  1. 香港某些民众的诉求有没有问题呢?有问题,站在中央政府的角度来看,当然是不答应的。站在大多数香港人的角度来看呢,也不应该答应。香港还是应该认命,一国两制,五十年不变,现在已经快一半了。香港的繁荣稳定,很重要,发展经济很重要。有时候,我看中央电视台采访香港人,那些香港人说要稳定,不要游行,再一看他们的身份,都是旅游从业者,服务业从业者,显然对于他们来说,香港的这件事,减少了他们的收入,让他们不开心了。

  2. 我对学生的一个基本看法是,年轻气盛,吃饱了没事干,有时候又会过于理想主义。而对社会人的基本判断是唯利是图,争取自己利益最大化。这个判断,不光是说香港学生,香港社会人,也是在说大陆,说这个世界。在我看来,如果能够把学生和社会人的这些特点均匀一下,那自然是太好了,这一点上来看,其实现在大陆这边算是做得不错了,可惜似乎又有点过了,学生们往往过于看重自身利益了。

  3. 对香港的判断离不开对祖国大陆的基本判断,目前也快要国庆了,又到了表达爱国心态的时候了。有人说,爱国不等于爱党,也有人说,连自己的国家都不爱,连畜生都不如。我爱这个生我养我的国家,喜欢这里的一草一木,喜欢这里的人文,风土,
    如果有一天,我也要永久地离开这片土地,我也会像《亮剑》里面的楚云飞那样,把故乡的一抔土带走,寄托思念。但,我也不会无条件地宠溺它,我爱我的国家,爱它,当然是为了它好,爱它当然也会指出它的缺点和问题。而从我的个人利益出发,我也不得不爱这个国家,希望它越来越强大,越来越繁荣稳定,因为我会从中受益。

爱国家,也许是一个很抽象的事情,就像我所表达的,爱这里的一草一木,人文风土。但也可能很具体,比如爱这个中华人民共和国,爱五星红旗,就是很具体。对具体的事物表达爱意很容易,对抽象的事物表达爱意就很难了。我希望做一个自由的人,对具体的事物表达爱意要克制,对抽象的事物表达爱意要放纵。

我的居家生活

居家生活中,一开始我也不习惯。但是更多的其实是享受,在我以前的租房经历中,有相当长的一段时间,我是住在不到十平米的隔断房里的,还有一段时间,则是住在郊区的公寓里,体验其实都不是很好。但是能够两个人住在近百平的房子里,我还是很开心的。这又让我想到,物质还真的能够提升幸福感,因为之前的物质,确实很难有幸福感。

我是很爽的,但我女朋友可能并不爽。我们需要经过一段时间的磨合,她是个爱干净的人。于是每次,我回家,她都会要求我在门口换鞋,这样她才能够让我进屋。她也会要求我每天都要洗澡,每天都要换内裤,每天都要洗袜子,每次都要把柜子里自己的衣服叠得整整齐齐,我还真的很不习惯。

但是,我总觉得,这只不过是我不习惯而已,她说得很多事情其实很有道理。

其实后来,我们磨合地越来越好了。经常地,我的一天是这样度过的:早上六点多种起床,这个时候她还不顾形象地躺成个八字睡觉,我简单洗漱,然后一个人对着电脑计划一下接下来一天乃至几天要做的事情,然后就开始简单对学习一些业余知识,可能是英文,也可能是web知识,也可能会像今天这样,写一些文字。之后,等到快七点半的时候,就去做饭吃。做的饭其实也很简单,为了少浪费时间,往往我会选择煮面吃或者炒米饭吃,做法很简单,吃起来却还是蛮香的。吃饭的时候,我会打开电视,看会时政新闻,或者体育新闻。只有客厅有这么一个大电视,才能享受看电视的乐趣,才能更加感受到居家的乐趣。

之后,八点钟,我亲吻一下她,向她告别,离开家,去上班。我觉得告别前,亲吻一下,是一件很西方的事情,做得久了也很习惯了,我们也变得越来越没羞没臊,可能老外也只是亲吻下面颊,我们则会亲嘴。

上班的路上,还是会刷一些新闻和公众号,虽然只有五站地的路程,但是因为转车和客流量大,实际上也会在路上耽误很久,索性,刷手机会让时间过去得快一些,我也渐渐地体会到了北漂挤地铁的感受,这是前两年所没有的,而我也渐渐习惯了。挤地铁久了,也就不觉得多么累了。搬家之前,曾经有一段时间,是要坐北京地铁四号线再转二号线,到达公司的,要坐好久的四号线,早高峰的四号线,总能遇到人们因为太挤不懂得礼让而争吵起来的,他们争吵起来,最直接的后果就是也会连累到我们这些乘客,心情变得很丧。搬家之后,看到别人争吵的情况很少了,我还是很感恩现状的。不过有时候,无论早晚高峰,下车总是一件很困难的事情,你需要提前换到出口处,不然就很难出去,我自己经常会在换到出口处的过程中,问旁边人“您好,下一站下吗?” 很客气地问句下不下车,时间久了,就会很敏感,同样的,别人问我的时候,“下车吗?”,我都觉得很没有礼貌,很没好气。有时候也想,年龄越大,规矩也还越来越多了,也更容易因为别人生气了。

我会在九点钟左右到达公司,公司是弹性工作制,只需要上够八小时的班就可以了,一般来说,是早上九点到十点上班,晚上六点到七点下班。我往往会选择早到早走,这也比较符合我以前的工作习惯。工作时间的事情,以后单独聊。

下班,仍然是挤地铁回家,到了地铁站,我会选择找一辆共享单车骑车回家。我当然想要尽快地回家,尽快地见到她,尽快回家抱一抱她。往往在我回家之前,我们已经决定了晚上要吃什么,她会负责将那些菜切出来,等我回家来炒,有次她看着我整个炒菜的过程,后来问我,下次我直接给你把这些东西炸出来,你回来直接炒吧,这样更快,我并不同意,说女神是不能沾油烟的,很大程度上说,我的确是这样想的,我总觉得,我不希望她沦落成为一个家庭主妇,这样也会降低她对我的吸引力。而且,我曾经跟她多次说过,我喜欢做饭,也愿意做饭,我的确这么说,也的确这么想,所以,我当然更要言行一致了。不过坦白讲,我其实更喜欢一个人在厨房的感觉,那次两个人一起在厨房,给我的感觉并不美好,反倒觉得生活如此平庸,碌碌无为,只能生活做饭了。而一个人的厨房,是一个属于自己的小天地,还能释放缓解压力,让我很怡然自得,甚至有一次,本来我是不喜欢刷碗的,在做完一件很有压力的事情之后,自己一个人跑去刷碗了,我给我自己的理由是,缓解压力,轻松一下。总之,下厨房这件事,我是喜欢的,我也很享受厨房与爱。

我们往往晚饭会做两个菜,这样,她如果哪样菜不喜欢吃,就可以多吃另外一个菜。我们做的菜,往往不会做少了,宁可做得多了,第二天吃掉,也不愿意做少了,吃不饱。我喜欢她吃得多,吃得香,喜欢她夸赞我厨艺好,这样我也有几分成就感。其实对比之下,我喜欢吃自己做得饭,甚于外面的普通快餐,我觉得自己随便做些什么都好吃,外面的,不仅不卫生,还不可口。当然,外面的正经馆子,另当别论,所以我也考虑,每个月,要下几次馆子,吃吃其他的风味。另一个对比,是个老家的对比,老妈每天繁忙,于是只是随便炒个菜,还特别少,有的时候只能蘸汤儿吃,相比之下,我们在北京,简直是阔绰得很,好吧,我又给自己找了一个不回老家的理由。

居家生活之中,我们享受着厨房与爱。然而,毕竟有那么一首歌,我们来自山川湖海,却囿于厨房与爱。我自己又是一个蛮容易焦虑的人,每每下班之后,享受厨房与爱的过程,两个人做饭,吃饭,在沙发上抱在一起看电视的时候,也会生出来两分焦虑。怕自己沉迷于岁月静好的生活,慢慢地,就落后于其他人了。所以,就又说回来,我还是会利用早上的时间和周末的时间来学习,来进步。

跟她一起住之后,我跟她调侃,我说,我现在已经不知道“家”的指代了,有的时候,我们说的“家”就是北京的住处,这个时候,我在公司上班,她在家休息,她会问我啥时候回家,回家记得买啥买啥。可是有的时候,我说的家又可能是我的老家,这时候,又有可能是我老家的新房和老房,各不相同。偶尔,只说“回家“会很让人困惑,这个时候,就会加上一两个定语,来说明究竟这个”家“说的是哪里。不过,无论我们聊的家究竟是哪里,总又让我想起那句,”吾心安处是吾家“,的确很有道理。坦白讲,在北京两个人住了一个多月,更加觉得北京的这个‘家’更加轻松自在,颇有些岁月静好之感,而老家,则又会面临父母的很多”老理老例“,他们会告诉你,别人都那样做,你也需要那样做,会有很多的束缚,这些还只是心理上的。至于物质上,当然还是北京更加丰富,所以,回老家并不是一件特别开心的事情,不过能够见见亲人,尽尽孝心罢了。前两天看一篇文章,讲的是,在当代,所谓父母在不远游是一个错误的说法,有理有据,其中一个理由是说,如今科技这么发达,完全可以通过视频电话来达到”回家“的效果,但是我却觉得,视频电话,对于我和我的父母来说,完全不成立。我非常不喜欢视频电话,就算是跟同龄人的女朋友,也很少进行视频电话,所以如果可能的话,我还是会选择回家。

我很享受现在的时光,就像我前面说的,岁月静好。但是,我并不确定,是否有一天,我会厌倦。觉得,还是海阔天空,闯荡江湖,更加刺激。无论怎样,跟随内心,享受当下吧。

偶尔,我会回想起我从业三年的经历,不能说多么精彩,但也步步为营。我还是会再想的过一些,想起到底是什么样的原因,让我想要学习前端,了解前端,如果用现在的话,叫做初心。

我想起来,当初上高中的时候,我的手机流量套餐是每月30M流量,平均下来每天大概只有1M的流量,这在现在看来简直不可想象。那时候,我只在下了晚自习之后,躺在被窝里用UC浏览器的无图模式刷刷微博,每月勉勉强强流量够用。那时候,蛮好奇这些词汇的,“流量”,“无图模式”。我当时一直很好奇,“流量”到底是怎么算的。为什么我的流量有时候就不够用了呢,本着有事情问百度的精神,当时去百度了“手机流量”的定义方法。于是的出来一个计算方法,也就是看获取到的网页上的内容,来计算“流量”。图片需要消耗更多“流量” ,因此当时的UC浏览器采用无图模式,能够省流量。一切似乎都没有我呢提,我记得那个时候,我为了计算自己每天的流量消耗,还曾经打开一个无图网页,根据里面的字数,去计算消耗的流量,结果却发现,实际消耗的流量,总是超过当时的计算值。直到很多年以后,我仍然记得当年做过的这件“蠢事” ,并且终于弄懂了所谓流量的含义。当时的我,只是看到了表面上的网页展示内容的流量,却忽略了还有很多其他的网络请求,比如CSS,js文件的加载同样消耗流量,这说到底,是因为我对计算机网络这门课不了解。 而后来慢慢地接触了计算机网络,入门了前端,也就能够明白这其中的道理了。

我也想起来,大二大三的时候,曾经很喜欢折腾浏览器,包括火狐浏览器和谷歌浏览器,就是希望能够把浏览器折腾得更加高级,实现更多功能。当时按照网络上面的教程,各种鼓捣,安装各种插件,脚本,样式。其实后来想想,这所有的这些鼓捣,也都是在用前端技术,改造浏览器浏览网页的体验。当时,完全不懂前端技术的我,只是觉得很神奇。后来,大三的时候,我按照网络上的教程,给某个站点写了一个去广告的样式,其代码只有两三行。在当时看来,我写这两三行代码折腾了好几个小时,终于简单明白了审查元素,元素选择器怎么用,我只用了一条语法规则,也就是display:none。我花了几个小时,只为了学习这样一条语法,实现一个功能。这当然是因为我在此前,没有接触过前端知识,更没有系统地学习过。但是你问我现在的我后不后悔?我并不会觉得后悔,因为大概也就是从这个时候开始,我越来越对前端技术感兴趣,于是后来的转行前端也就顺理成章了。

工作之后,我的技术栈是在不断扩张的。随着技术栈的扩张,知识也越来越多。当我想到过去的那些“蠢事”时,也会觉得有几分可笑。可是,那就是青春啊。

身为一个程序员,经常会遇到的一个问题是,我们一旦换工作,就会有老的技术栈不再使用,需要学习新的技术栈。如果你是一个像我一样抠门的程序员,可能就会觉得可惜,觉得以前学的技能,又都浪费掉了,又都白学了。就拿我个人的例子来说,我在上一家单位的时候,担任的是全栈开发工程师的角色,后端语言是Python,不过我是偏向前端的全栈。到了新的公司,我开始全职担任前端开发,这个时候,就面临技术栈的废弃。我不再需要使用Python语言作为日常开发,而用进废退的道理大家都懂,一旦一个知识不常被使用,那么它就会退步。有这样的道理在先,就又会加剧几分可惜。

但是,其实回想一下我们过往的学习经历,就会发现,我们有太多的知识,学到了,过了一段时间,就再也没有用了。如果你是计算机相关专业,那么大学以前学到的几乎所有的化学,生物相干知识都没用了。太多太多的,需要强行记住的公式被你遗忘掉了,只有一些常识性的知识成为了常识,放到了你的记忆表层,能够随时被取出来使用,比如水的分子式是H20,一个理工男恐怕这辈子也不会忘记这样的知识。但是那些常常出在高考试卷上面的题目,当我们离开多年后,就再也答不上来了。于是,照样也会有人感慨,当前学到的知识,后来又还给了老师。

不过,即便是很多知识我们不再那么熟悉,可是又有什么关心呢?高中时候的化学,生物知识没用了,还给了老师,但是很多的思维方式和思想保留了下来。比如控制变量法,比如相信物种进化,相信人人平等。相应地,我可能不再会在工作之中使用Python,但是那又又什么关系,Python的很多思想我学到手了,可以借此类比去学其他的语言。比如前不久公司内部有同事分享JAVA8引入的函数式编程的思想,我就想到了Python的函数式编程的思想,lamda匿名函数的思想。学的多了,很多东西不再使用,这非常正常。再比如最经典的,我们上学的时候,都要会使用C语言,当年我还考过C语言的计算机二级证书。但是工作之后,也没有再在工作中使用过C语言,但是好在C语言是我的编程语言入门语言,从中,我了解到了变量,for循环,递归等等一个编程语言所不可获取的元素。后来学习新的编程语言,也因为有了C语言的基础而变得更加容易了。以往的知识,不是没有用了,而是内化成了一些思想,留在了大脑中。

但是,如果我们可以选择的话,所学都能致用,那当然也是一件很美妙的事情。

其实再想想,太多的人,甚至毕业之后,工作的内容,跟自己上学的时候学到的都八杆子打不着。

断舍离是一种境界,并非所有人都能够做到。面对知识,我们也应该有断舍离的心胸。

如果没有这样的心胸,当然也没有什么关系。计算机编程语言,每一门都有它的特点,就算工作中你不能使用曾经学到过的语言,技能,那么只要你有心,也是可以在自己的小项目中使用上的。总之,我们无需觉得学而无用,有一个平和的心态对待学过的知识,才是正理。

五六七三个月,总结起来干了三件事。五月份交接工作,六月份找工作,七月份找房子。每一件事,对于我个人而言,都是不小的改变。

五月份

五月份,虽说是交接工作,但是还有一个很紧急的开发工作,所以基本上就是边开发边交接。5月过完五一小长假回来,就跟领导提了辞职,也留出来了将近一个月的时间,也算是仁至义尽了。后来的事情是,领导找我谈了次话,说是项目紧急,希望我能够呆到六月份,她还说我这个人太犟了,为什么就不能从大局出发呢?我又只能说,希望自己的利益不受损害。后来也做了权衡,做了妥协,说是五月底离职之后,再去公司啥事不干,完整地交接工作三天时间。双方这才谈得比较顺利。

以前在这家单位上班的时候,除了有那么三个月的时间,老大一时兴起在公司附近租房住,于是我们跟着他一起加班。 其他的时间,几乎没有加班。但是恰恰在这即将离开的一个月的时间里,加了很多班, 最多的一次,到了晚上十点半。当然,跟我交接工作的同事,加班加得更狠,加到了凌晨1点。这次加班之后,我感冒了,又难受了好几天的时间。

之前离职,很大原因是因为这个新的直属领导, 他几乎并不懂技术,不懂互联网,不懂前端开发。他唯大领导是从,大领导今天说这个, 他就要求我们做这个。明天,大领导心情换了,想要做别的。他就又要求我们做别的。相比之下,我的上一位老大,能够很好地帮我们过滤需求,少了很多无用功。另外,这个直属领导,由于不懂技术,导致项目估算期限,出了很多问题,当项目来不及的时候,也只好让我们加班了。

有那么几天,我很怕自己突然发火,跟这位直属领导直接闹翻。不过有意思的是,自打我提出了离职,这位直属领导对我的态度也发生了转变。甚至后来,我离职之后,在部门微信群里面道别,也得到了他的祝福。我很难说,我们两个谁做错了。毕竟从他当我的领导的第一天起,我就不服气。

六月份

六月在老公司又交接了两天工作,完全是义务的,没有收任何费用。后来端午节回家,跟家人呆了两天,然后就又回到帝都,准备找工作了。

于是那个月,好长时间的工作状态是这样的:去大兴区图书馆看半天书,下午去面试,面试回来吃个饭,跟女朋友在微信上聊聊天。

面试的经历,其实也可以简单说一说。从6月13日开始面试,后来陆续有很多面试,一开始对待的态度有点漫不经心,后来发现面试结果一次比一次糟糕。有两个面试,都已经进行了两三轮了,还是被答复说,某位主管领导不在,要择日再找机会来面试,后来就等了等,问了问,人家也真给了个机会,电话面试,不过结果也不尽如人意。

五月份的时候,当时在职,断断续续面试了三家单位,面试的第一家单位,很快就给我开了一个蛮不错的待遇。只是考虑到他们公司开发人员太少,可能要做的事情太多,最后委婉地拒绝了。第一个面试就有这样一个好的待遇,其实我还是很欣慰,甚至有些飘飘然的,于是后来很自信。

七月份

找房子也不容易,首先是我们的条件,我们希望能够有一个大客厅,用来放古筝,能够进行古筝的一对一教学。其次,希望我自己的上班路程都能控制在一个小时以内。开始,我对北京的房租有一个简单的印象,认为大概五六千块钱每个月的房租,就可以搞定,满足我们的需要,后来发现,北京五环以里,稍微靠近些地铁站,房子再稍微大点,都要六千以上。这是第一个误解,第二个误解是,我以为整租一个四五十平米的房子,也就可以了。后来经过多次看房,却发现四五十平米显然不能满足我们的需要。

找房子的过程,我们起先是在手机上在线看房,女朋友比较倾向于自如,一个理由是她的一个大学同学跟别人合租,就是在自如找房,而且有趣的是,她那位大学同学多次换房,也都只找自如,足以见得对于自如的忠心。然而,我对自如的印象并不好,原因也大概就是这几年爆出来的自如房源有甲醛的事件,另外,一个理由,简而言之,就是觉得自如房源贵。而又有什么服务费,而他们的服务,我们又觉得全无需要。

之后,贝壳找房,安居客,蛋壳公寓这些app也被我装进了手机,这些app在找房的那段时间,几乎每天都在翻,都在看。于是就发现一些规律,像蛋壳公寓app上面的房源,都是以公寓形式来出租的房源,可能也由于并非是房东直租,房源量并不多,完全无法满足我们的需要。在线看来,房源量比较大的是贝壳找房和安居客,这两个app都是所谓中介模式,贝壳找房背后的中介公司是链家,安居客背后的中介公司是我爱我家。一个蛮有趣的事情是,有一次,一个我爱我家的中介带着我跟我女朋友去看房,女朋友突然问那位中介一句,链家跟我爱我家是一家公司吗?这句话一问出口,搞得我一脸黑线,中介只简单回了一句,不是。女朋友又说,我看我爱我家总是跟链家开在一起,我则连忙开玩笑,这就有点像是麦当劳跟肯德基,他俩也总是开在一起的。话说回来,安居客和贝壳找房,都是支持在app内部在线联系中介,聊租房相关事宜的。不过很快我就发现,在app内部聊着聊着,中介就会让你加他微信,然后试图将app内部的流量转化到微信,毕竟微信就是我们的生活。于是,摸着了这个套路之后,我在这两个app上,都会做的一件事情就是,在联系经纪人那里,找到他的手机号,然后将这个手机号复制下来,去微信里搜索联系人,添加为好友。然后在微信上进行交流。

再来说一说房源,首先要给安居客一个差评,也给我爱我家一个差评。安居客app是一个平台,里面有除我爱我家之外的其他一些小中介公司的房源,有时候,女朋友在安居客上,找到一个觉得满意的房源,把连接发给我看,我一看是某个小中介公司的房源,就会告诉他,咱们还是换个大中介公司吧。毕竟每个月好几千块钱的事情,还是要做得靠谱。另外一个需要吐槽的,往往在安居客上,看上了觉得满意的房源,一旦问中介,他就会各种理由,告诉你这套房子看不了。这不由得让人怀疑我爱我家,干了一件事,也就是上架虚假房源,然后诱骗消费者去跟他沟通,他好推荐其他房源。在这一点上,链家其实做的不错,基本上看,每次在线联系中介,都能得到比较靠谱的答案。不过话说回来,即便是在线上觉得满意的房源,到了线下实地去看的时候,也往往会觉得网上挂的房源图片与真实的房源之间有很大差距,毕竟图片即便没有PS,仅仅是拍摄时的光线,角度,等原因就可以让人们产生错觉。好在中介往往带看的时候,会带看不止一套房源,这个时候,选择也就更多了。然而,其实后来经过摸索,渐渐发现,其实与其每天拿着个手机不停地在刷房源,还不如看看有哪些地段值得考虑,然后直接去到附近,那附近也一定会有链家或者我爱我家,这个时候,就直接去到门店,告诉他们,我们的需求。然后让他们在他们的内部系统里面做搜索,找出附近最符合我们要求的房源,然后带看,效率是最高的。说到这里,顺便再说一句,无论是链家还是我爱我家,他们对外都有面向消费者的系统,就像前面提到的,链家是贝壳找房,我爱我家则是安居客。而他们对内也有一套面对自己员工,也就是中介的系统,可以说内部系统的房源更加齐全,很多在内部上架的房源,并没有在外部上架。所以,如果去到店里找房,也能够让选择面更大一些。不过话说回来,虽然说去到店里是一个好的选择,但是前期还是可以通过这些对外的app,来进行简单的搜索,目的是大概看看各个地段的价格区间。

由于我7月10日开始上班,从上班前两天开始找房看房,到7月21日终于定下来,总共算下来,也有两周多的时间在做这件事情了。总共,我们看了有二十几套房子,都是我和女朋友利用休息时间去看的,最早的时候,也就是7月9日的时候,我自己一个人去看房,因为我的需求不高,我不太清楚需求,于是看房的时候,还专门给她拍摄视频,录像,信号条件好的时候,拨打微信视频电话,光那一天就看了七八套房子。也正是从那一天开始,我才感觉,还是找到一个地段,然后去附近看房比较省事。那一天看的七八套房子里,最后只筛选出来一套。女朋友又要在周四的时候,才能来北京看房,确认是否需要。于是又被中介在微信上催促,我们对之不予理睬。后来的事情是,周四的时候,女朋友过来,我们两个人在那天晚上又看了三四套房子,女朋友对之前提到的那套比较满意,但又不是特别满意,反倒对另外一套之前没有带看的特别满意,因为房子装修好,又内部有钢琴,女朋友喜欢弹钢琴,然而中介报完价,我就犹豫了,超出了我的预算800块钱,如果租了这套房子,就真的成了月光族,搞不好还有可能入不敷出。对此,我当时就跟中介表态超出了预算不予考虑,女朋友却笑开了花,中介又在那天忽悠,说着这个房子确实好,每个月也只多出来几百块钱而已。可是我还是很难接受,那套房子也是那天晚上看的最后一套房子,于是我们回去商量。

周末的时候,女朋友问我,说是要掷硬币,正面的话,就租下来阿姨那套房子,也就是那套不是特别满意的那套,反面的话,就不租了。我没有掷硬币,觉得她会这么想,就说明还是不想祖那套房子。后来,也是在这个周末我们犹豫过之后,阿姨的那套房子被别人抢先一步拿走了,那个周日,女朋友没有在朋友,经历了十多天的找房,我有点疲惫了,于是跟她讲,我们提高了上限,可以考虑租那套带钢琴的房子,带钢琴的那一套只要不要超过上限就好,后来我又去跟中介联系,结果中介却告知我,带钢琴的那套房子,由于装修豪华,还带了一台钢琴,光押金就需要一万元。当我将中介的话,转告给女朋友时,女朋友一身硬气,说着她面对这样的房东,已经不喜欢那套房子了,于是只好作罢。

其实当时帮我们带看的中介,我们找了三个,其中有两个,在经历了一周多的折腾之后,不再把我们作为目标客户。反倒是有一个小哥一直不断地给我们推荐房源,也的确是够敬业,约定好了周日去看房。与此同时,女朋友开始从自如上面搜索房源,看上了百子湾附近的一个复式,我们两个周六去看房,结果发现并不理想。告别了自如的管家,又扭头去到了附近的链家,跟里面的中介描述了我们的情况之后,中介又带看了三四套房子,结果真的有一套女朋友和我都很满意,当然重点是女朋友比较满意,价格也没有超出我们的上限。我们两个回来商量,如果周日看房没有比这个条件更好的房子,那么就定下来这个房源。结果是,周日的时候,我和女朋友两个人,顶着三伏天的大太阳,在外面跟着中介小哥又遛了两个多小时,但也没有找到满意的房源。我和女朋友经过商量,决定在再去看一次周六满意的那套房源,如果仍然都很喜欢,就定下来。于是我们又跑过去,中介带看房,这一次,也仍然觉得很喜欢,于是都打算签合同了,却发现房东因为出差在外地,房产证等信息暂时不能提供,当天不能办理合同了。又是一波三折,但是好在之后,一切顺利,女朋友也于下一周的周四入住了,她入住的同时,顺带着带上了她的爸妈,我的爸妈前去参观,也让我的爸妈高兴了一阵。

我退掉了原来的房子,没有退押金,又多交了一些钱,拖着两箱行李,离开了黄村,搬到了朝阳。

我们后来发现,生活终究是现实的,离不开钱,所以也要努力挣钱,有更好的物质生活。但是我们也不要忘记了,物质生活,是为精神生活服务的。也不要忘记了,钱不是万能的,没有钱是万万不能的。

我在北京刚刚租好的房子里写下这篇博客,而这个房子,我也把它看作我的家。希望,在北京的家,越来越好,越来越温馨。

简单介绍

前面提到了我在过去的五个月内,一个人维护开发一个系统 ,也正是有了这样的经历,让我想要总结一下。

先简单介绍一下这个产品,产品是移动端商城。根据情况,可以放到微信里,也可以放到app壳子里。

技术栈

前端

我自己并没有参与当初项目的选型,但是后来,我主导了项目的前端工程化的升级改造。后来,我也写了很多篇博客来说相关事宜。

前端方面主要的技术栈

  • react
  • react-router
  • webback
  • sass
  • babel

商城采用前后端分离的技术架构,前端的框架为React, 配合上相应的一些工程化的工具,达到快速响应开发的目的。

后端

后端使用python语言进行程序编写,版本为2.7,这是由于当初移动端商城开发之前,已经有一版PC端商城,PC端商城就用到了python2.7 ,后端框架也是基于python2.7 自主研发的,因此并不想在整个大的项目中,只能继续使用python2.7编程。

  • python2.7
  • jinjia2
  • tasktiger
  • ELK(Elasticsearch, logstash, kibana)
  • git

在这里,用到了jinjia2作为PC端商城的渲染引擎。它有点像是Django的模板引擎,总体来说,使用起来比较简单。另外,使用tasktiger作为任务队列(消息队列)的处理引擎。使用ELK 进行日志监控和错误筛选。将项目部署到git私有服务器
,同时备份到github的私有仓库中,使用github的issue进行项目管理。

运维

自主研发的后端框架,支持运维的一系列工作。包括:

  • 两种部署方式
  • 容器
  • git

部署方式

一一说来,两种部署方式分为patch和deploy两种。patch顾名思义就是打补丁,全程停机时间非常短,简单来说,只是将代码上的改动放到服务器上,并不涉及到依赖包的注册或更新,而deploy的方式,是全量更新,这样的更新方式,由于是做一遍全量的检查,因此会特别慢,也因此停机时间会很长。因为非常影响用户体验,所以往往选择在夜里进行这样的部署操作。由于财力物力的限制,不能做成服务器集群。因此每次部署又会短暂地停机。如果是通过deploy的方式来部署,那么这个停机的时间就会更长。框架也没有考虑这些情况

原有的自研框架,是12年左右的时候,几个技术牛人开发的,后来就一直只是小修小改,但是其实站在19年来看已经无法满足当今的需求了。一个最明显可见的缺点是,它还在以python2.7 作为编程语言,而python官方已经明确提出,到了2020年,就会废弃python2.7,相应地,很多python2的第三方库也将不再对2.7版本进行支持。这样这个框架就显得十分落伍,相应地,性能上也无法跟上潮流。记得之前的老大曾经提到过,sanic异步框架。他还给我们科普了,如果以后上了python3,用上了sanic,去掉了tornado之后,整体的性能会有飞跃式的发展。然后,时隔近一年,他的想法也不会再在那个项目中得到施展了。

容器

并没有使用docker作为容器,而是使用了lxc这样的方式。从效果上看,lxc也有它的好处,但是还不够好。

但是框架还是提供了很强大的能力的,从一个裸机安装好ubuntu系统之后,通过框架,自动安装好所需的环境,全程不再需要运维做过多的工作,其实是能够将人从运维的工作中解脱出来的,只是说,由于这个自研框架也没有一个完善的文档,导致一旦框架本身不符合要求,出了问题,就不得不去看源码,尝试修改框架源码,而框架源码又往往更加抽象,这时候,也就到了提高自己能力的时候。比如,我曾经就因为一个误操作,搞坏了测试环境的服务器,没办法,只能给这个机器重新安装环境,结果又出现了一些曲折,最后终于算是搞定了。但这个过程,需要对这个框架的源码深入了解。

git

据我了解,有些公司的项目,代码托管方式是,整一台自己的git服务器,然后安装上gitlab,gitlab实现了一个可视化的界面,也能够进行issue管理,项目管理等常规的项目操作。不过也由于历史原因,当时我们的项目,采用了git服务器+github的方式,即项目的真实git源是在自有的git服务器上,但会将代码备份到github上,也就使用了github 的项目管理操作。

感想

可以看出来,很多时候,一个项目开发好,只是它的初生。之后,如果这个项目不死亡,就需要不断地对它进行更新,变革,这样才能跟得上时代。但是往往,这种变革伴随着疼痛,也伴随着可能的力不从心。比如,给一个以万行代码计的项目从2.7升级到3.5,是一个巨大的工作量,如果又没有更高层领导的推动,如果更高层领导又对代码一所我所知,这就是一件很吃力不讨好的事情了。所以有时候,可能将一个项目放弃,推倒重来,或许是更好的选择。

我在那家公司做了两年,其实经过这么一个过程,我看着一个产品生长,壮大,又慢慢半死不活。我看着这个庞大的项目,怎样发展,对我也是一种成长。我有一种欲望,把那段经历记录下来,总结自己的知识,所以也就有了这篇文了。

也许再过几年,回过头来看这篇文,我会感念,现在的自己视野还蛮开阔的。因为我是一个全栈工程师,只要我想学,我就能够胜任计算机相关的任何工作,就能解决遇到的问题。

1.线程的问题

2.各个方法优先级的问题

需要知道宏任务,微任务的概念。
process.nextTick()

3.对event loop的理解

事件循环机制可以让程序来执行非阻塞的io操作。虽然js语言本身是单线程的,把一些任务转移给操作系统内核来完成。

因为大多数现代操作系统内核是多线程的,因此他们能够控制多个操作在后台执行。当这些操作中有一个操作完成之后,这个内核就会告诉nodejs,这个操作已经完成,这个时候,callback函数就会被添加到队列中,等待执行。

┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘

从上面的流程图可以看出,timer的顺序是要高于poll的

各个阶段

各个阶段:

timer=>pending callback=>

pending callbacks:

poll: callbacks池,一些callback放到这个队列中,等待执行,setTimeout的时间最少是设定的时间,因为还有从队列中取出来执行的时间。

check: setImediate 的callback在这里执行

close callback:一些关闭callback在这里执行

理解io操作

我们编写的程序除了自身会定义一些数据信息外,经常还会引用外界的数据,或是将自身的数据发送到外界。比如,我们编写的程序想读取一个文本文件,又或者我们想将程序中的某些数据写入到一个文件中。这时我们就要使用输入与输出。

读取文件,我们可以使用读取文件的方法。比如fs.readFile(‘/path/to/file’, callback);

堆内存 栈内存

二叉树来进行维护

堆是一种数据结构,是利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆

堆内存 栈内存
https://juejin.im/entry/589c29a9b123db16a3c18adf

与其他语言不通,JS的引用数据类型,比如数组Array,它们值的大小是不固定的。引用数据类型的值是保存在堆内存中的对象。JavaScript不允许直接访问堆内存中的位置,因此我们不能直接操作对象的堆内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用类型的值都是按引用访问的。这里的引用,我们可以粗浅地理解为保存在栈内存中的一个地址,该地址与堆内存的实际值相关联。

二叉树

在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个叶子节点,至多有2k-1个节

setTimeout

解释:setTimeout/setInterval 的第二个参数取值范围是:[1, 2^31 - 1],如果超过这个范围则会初始化为 1,即 setTimeout(fn, 0) === setTimeout(fn, 1)。

setTimeout 的第二个参数只是说的,callback什么时候放到事件循环的队列中去。

为什么timeout的时间不准

setTimeout 的第二个参数只是说的,callback什么时候放到事件循环的队列中去。

To reduce the load (and associated battery usage) from background tabs, timeouts are throttled to firing no more often than once per second (1000 ms) in inactive tabs.

如果是非活跃标签页,那么它每1000ms会去检查一下callback执行。这个时候也是会出现时间不准的情况。

dom.min_background_timeout_value

For Firefox in particular, you can change the dom.min_background_timeout_value preference in about:config to a number of your liking in the profile that you use to run the tests. I wouldn’t suggest doing that in your default browsing profile, though: the reason for the high clamp is that it cuts down on web sites in background tabs chewing up CPU updating silly tickers and the like.

Node uses libuv which a cross-platform abstraction layer for lower level system things like file-system

In Node, if you specify setTimeout(callback, 1) then it will be executed one millisecond later (assuming the system doesn’t delay it due to be overwhelmed). In browsers, the minimum time will be 4 milliseconds as specified by the HTML5 spec:

https://stackoverflow.com/questions/7221504/does-node-js-enforce-a-minimum-delay-for-settimeout

宏任务,微任务

先执行同步任务,再执行微任务,最后执行宏任务。
宏任务有 setTimeout, setInerval, setImmerdate等,优先级不能确定

微任务 process.nextTick , promise, 按照优先级排列

当然是为了和浏览器更加趋同。
了解浏览器的eventloop可能就知道,浏览器的宏任务队列执行了一个,就会执行微任务。
简单的说,可以把浏览器的宏任务和node10的timers比较,就是node10只有全部执行了timers阶段队列的全部任务才执行微任务队列,而浏览器只要执行了一个宏任务就会执行微任务队列。
现在node11在timer阶段的setTimeout,setInterval…和在check阶段的immediate都在node11里面都修改为一旦执行一个阶段里的一个任务就立刻执行微任务队列。
最后
所以在生产环境建议还是不要特意的去利用node和浏览器不同的一些特性。即使是node和浏览器相同的特性,但规范没确定的一些特性,也建议小心使用。否则一次小小的node升级可能就会造成一次线上事故,而不只是啪啪打脸这么简单了。

作者:zy445566
链接:https://juejin.im/post/5c3e8d90f265da614274218a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

异步意味着任务不会阻塞,比如,如果我要下载一个比较忙的网络资源,我的程序不需要一直等待下载完成,它可以在等待下载时继续做其他事情。这与并行执行多个操作不同。 其实还是应用上了多线程,对于js语言而言,等于js的主线程上,再等待响应,去做了其他的事情。而系统的其他线程,则再处理相应。这是从系统层面来看这个问题,比如读取某个文件的操作,其实也是有两个线程,一个线程是js主线程,另一个线程是系统上读取文件的线程。

参考资料

https://juejin.im/post/5c3d8956e51d4511dc72c200

https://zhuanlan.zhihu.com/p/34182184

https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
https://juejin.im/post/5c3d8956e51d4511dc72c200

2019年初,由于公司裁员,我成为了公司里的唯一一个互联网程序员,即负责与线上商城有关的所有维护和开发事宜。这样的一段经历,在我看来,比较有趣,因为我一直想尝试,看看自己是否有能力做到一个人维护开发一个系统。事后证明,我也的确做到了一部分,至于为什么说只有一部分,听我慢慢道来。

工作

由于只有我一个人,我的工作包括了前端开发,后端开发,运维,以及与业务人员沟通需求等事项。对当时的我来说,已经在这家公司从事了两年开发工作,其实前端开发和后端开发已经轻车熟路,相比之下,我对运维这一块很陌生,也想借此机会,了解一下。这样,我也就能够对整个互联网产品的开发维护有个全面的了解了。我当时是有这样的考虑的,但是后来发现,其实更多时候,我其实是把这个项目以前从未接触过的边边角角的业务和技术都拎出来晒了晒,以至于,后来很多问题,我都不得不通过看代码,了解其业务实现。也让我对这个系统的后端服务有了更加全面的了解。

开发

我有两个月的时间,来开发一个服务。也就是我之前提到的https://www.jianshu.com/p/bd2090b7140e ,没有人监督,我自己也不急,考虑问题也考虑得很全面,另外,基本上每天的工作状态处于半天开发,半天维护的状态。因此从时间跨度上来看,开发了很长的时间。这两个月,现在想来其实是蛮享受的,我也挑战了一把独立开发,我曾经以为我自己没有能力独立开发,但是后来发现,通过一步一步走,也是能够做到的。

维护

除了开发之外,每天还有一项任务就是系统的维护。我在最初做这件事情的时候,经常会忘记。因此,就在我自己的手机日历上加了提醒,每个工作日的早上九点半,查看系统的任务队列处理情况以及日志报错情况。这个日历提醒直到最近,才被我去掉。有时候,因为有一些任务队列的错误,每天都要花费一些时间来处理这些事情。也因为这些错误,又总是能够发现系统代码上的一些问题,这样也就能够及时改正。

我印象很深,又一个任务队列的任务,

技术上

技术上,以前从来没有动过的自有后台框架,由于要了解其部署过程,也有了一些深入的了解。

这五个月的时间,其实还是学到了很多。但更多的并不是单纯的理论知识。更多的是,如何跟周遭的形形色色的人打交道,业务人员,需要对接的技术人员,不懂技术的领导,别的业务部门的领导等等。当然除此之外,还有,我前面提到的对整个互联网线上服务的全方面的了解和认知。

我其实是身心俱疲的,在这几个月的时间里,我看着身边熟悉的同事一个个离开,公司的经营不景气,于是开始裁员。虽然是裁员,可是也裁不到我这里,毕竟我已经是那个only one了 。然而,对于其他的业务部门的同事来说,他们肩上的担子更重了。离职了很多人,离职的交接工作很匆忙,于是原本早就教给过这些人的系统使用,又要重新再教一遍,对我来讲,实在是不情愿。当然,偶尔也会情愿,比如写了很久的代码,已经累了的时候,如果恰好有个业务部门的同事过来问问题,我就当是休息休息,耐心给她解答了。

但是,毕竟身兼数任,我明显感觉自己做的太多。却每一件都做得不足够好。

不再一个人

一个人的状态持续了两个半月的时间,之后,由于公司的“战略”,需要“紧急”开发一个项目,我经过了评估,认为我自己一个人无法在规定的时限内,完成开发。于是就有了大概半个多月的招聘,我也当了一把面试官,面试了五六个人选,最后入职的那位同事,也是通过我的面试才进入这家公司的。

然而,人手虽然多了,但是却感觉工作量,较之前两个月有了大幅的增长,在前两个月,我没有加过班,但是自从这位新同事入职之后,我们也会因为赶工期而加班,这并不是一个好事,尤其是当我正与女朋友热恋的时候。也就是在这个时候,我辞职的意念越来越强烈。

疲惫

公司处在“危险期”,于是又给人一种乱弹琴的感觉。有一次,我“有幸”参与了一场公司老总都参与的会议。会议的主要内容是谈论某个项目是否有价值做,以及怎么做的问题。在这次会议上,我明显感受到了老板的强势。虽然,偶尔也有人提出不同的看法,但是大致上,还是老板说啥,下属们听啥。老板明明是做实体经济起家的人,却在o2o上指手画脚,很多的想法,给人的感觉甚至是自己想到了一个点子,于是拼命地群策群力,给这个点子找出几个值得做的理由。而不是,因为有那么几个合理的理由,而去做这样一个事情。

我从来也不看好这个项目,做起来也当然觉得无聊。我细数了一下,在此之前,做过的很多项目或功能都已经荒废掉,没人用了。我开始质疑我自己的工作,我的付出最后得到了什么。当然,我最质疑的其实是这个公司的运营策略和方针。牺牲了那么多的人力物力财力,最后却统统成了空耗,白白浪费掉了。

那个项目进入测试阶段,我提出了离职。而在提出之后不久,却突然被告知,公司大领导决定,上面的项目暂时搁浅,集中精力去做另外一个新的项目。而那个新的项目,又是一个充满槽点的项目。这个公司里,没有人懂互联网。就像是以前看过的那个段子,人人都是产品经理,人人都想设计互联网产品,但是哪里是那么容易的。这个公司大老板,给我一种强烈的外行领导内行的感觉。其实在我看来,外行不是不能领导内行,问题在于外行应该给予内行足够的空间,而不是四处指手画脚。就像是以前听到的一个说法,领导的作用是用人,让人做事。而不是指手画脚,当提线木偶的提线人。从这个案例,我觉得我有些懂得为何传统行业做不好互联网了。如果都是外行领导内行,的确会很困难。

我想起了19年年初的那场年会,年会的节目并不精彩,看得人昏昏欲睡。但又因为这官僚的作风,不能离开年会的现场,只能够继续看着这鸡肋的年会。在年会即将结束的时候,大boss上台,跟公司的中层领导们一起合唱李克勤的《红日》,并且口中说着一日公司不上市,一年的年会结束就要唱《红日》,要把《红日》唱到公司上市。她的话,让我毛骨悚然,让我之后每次听到《红日》,就想起这位董明珠式的女boss。

一个公司如果长期陷入内耗之中,我不认为它会走得长远。当然,它可以因为财大气粗,不断地去试错。但是这个试错的过程,对于员工来讲,是会很疲惫的。如果有足够的物质精神奖励,当然还好,否则,有能力的员工当然会选择飞走了呀。

离职

在我离职前,仅仅是因为觉得续费腾讯云,需要在公司的帐目上走一个流程,略显繁琐,加之,公司的战略从不再重视自有商城的研发和维护,于是经过几个中层领导的讨论,决定不再为腾讯云续费。原本为微商城和app做的静态资源云托管,也就不能再继续用了。这也就意味着,我在最早的一个人开发系统的两个月内所作的工作又白费了。对于公司而言当然是白费了,对于我个人而言,当然还是增长了一些技术知识和经验的。而如果再仔细想想,由于我在这家单位的过去两年所做的主要工作就是移动端自有商城的开发和维护,则我过去两年的工作,也都被所谓的“公司战略”抹杀了。当然,如果我继续留在这家公司,也是能够有所作为的,只不过那个工作就是与第三方商城的对接及相关业务,这的确对我没什么挑战性,我也不打算如此。对我来说,老的项目宣告结束,但毕竟学到了很多知识。有些放到了脑子里,有的放到了文字里,总之,都有收获。

总结

一个人来维护开发一个系统可以吗?当然可以,但是我开发维护的是前人们用七八年时间积累下来的代码量数万行的项目,其实维护起来也并不容易。虽然也有一些文档,但文档上讲的比较概括,之前的领导推崇代码即文档,于是有些业务逻辑经常要去看代码实现,才能知道,业务实现。另外,还要和形形色色的人打交道,当我意识到我有能力应付这些人之后,就不想再打交道了。同理,当我知道,我自己有能力一个人开发维护这个系统之后,我就不想再继续了。为什么呢?因为觉得很累,而且性价比很低。

/etc/apt/sources.list

https://blog.huihut.com/2017/08/25/LinuxInstallConfigShadowsocksClient/

deb https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse

转载自:http://www.ti6.net/wangzhanjishu/2406.html

在使用vim编辑器的时候,有时候编辑一个文件,而文件内容比较多,如果需要快速清空整个文件,可以使用一下命令: 在命令模式下,首先执行  gg 这里是跳至文件首行 再执行:dG 这样就清空了整个文件! 还有一种方法就要退出VIM,然后使用echo >> file ,这样也能快速清空文件内容,当然你也可以删除了这个文件再新建一个就是了。

https://github.com/honovation/ljmall/issues/843

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC65Gt/3HyHe1RdL0MQBUrAh6YfR4HlXABDzN4+bJJolIHIP9A+iWRctjw5ny8OlpFLbBrBRzlCmBg5VzqEYtg4ZKLsyMsSm1944NK/ygS1Zj3PtrU93XGW+G5ItxmjhfocWS1FJJ6NtzppFE4tmkIaL32TJEZDu/jMYUu0C81s3DhZwaQNv3pzqJG3N7aeOD1RpF1aHn3FnjhbnGmZ4GNN71jyKjZQES+mGZTmVGmTde7deuc+OUM6P1ECEKzntTZJZDo7iqeoaLqweXbsI5Or1hTT4zIddkL1OnOsnb6FR/92PfHNn3lcoN1UFpG+8vOHOqT2kcVZu7NGZFwgC/5rxRhx4bHqGHnIH+zuKNihVE70zu8uiHi/n0T0+vLlTUBog8YyN5HsnbQCKI0sfMsQ7yq9vlyP/zE2RErwN8YGzqU3EvZpFVxr5KDGbZ4TazBtyTvWEs+ru1iZXy0qk+y0C3xKKF8W7h9T8ykIvASY1XfffRYQKZ+NkdxKqkl/Ioq7Z32MslWW2t8Xc/6MgeII9CyynB68FqEifC0ulc3JYkAcKAuSoT0PpscrCF2OfF3xaCUVxRxhCDh4xIV1NdWfhC+jaTfDuVZszjbciJ/VW8aG3QZtxPUjfjskgkf8DrpKwqJmECCl9+A5277hJGQxPyFGHQ4JfWgUZFKfc+NlbQ== zhangolve@gmail.com

~/.ssh/id_rsa.pub

https://leihungjyu.com/post/ubuntu-install-shadowsocks.html

https://app.yinxiang.com/shard/s23/nl/5948926/4389aa9f-6f9c-479f-abd2-3b1917926db0/

https://blog.csdn.net/fx_yzjy101/article/details/80243710

https://blog.csdn.net/timo1160139211/article/details/69948540

https://blog.csdn.net/CSDNones/article/details/48917219

https://blog.csdn.net/u014044812/article/details/78727496 pycharm破解版

问题

问题大概出在18年的双十二期间,由于电商运营团队在做活动的时候,在几个活动页面展示了好几张特别大的图片(大概有800k-1M大小的样子), 致使用户在实际浏览过程中,体验并不是很好。而如果只是普通用户体验不好,也就罢了,偏偏那几天大BOSS关注起来了app,于是问起缘由来,一级一级问过来,问到了我这里。

我当然很明白这里面的问题所在,说白了就是由于你网站上的媒体资源加载太慢了,直接造成了用户体验差。而为什么你网站的媒体资源加载慢呢?那是因为你选择了在自有机房来托管这些媒体资源数据。而这些自有机房,在网络连接速度、稳定性等方面都与专业的云服务商没法比,这就间接导致了问题的产生。

选型

有了问题,就要有对应的策略。我于是首先负责了云存储的选型,当时面临的选择包括七牛云存储,腾讯云存储,阿里云储存这几家。当时与老大商量过,认为作为一款一多半流量来自于微信平台的app,当然还是应该选择一款腾讯旗下的云存储服务了,他对此表示赞同。但还是应该考虑价格因素,经过简单的计算,发现三家在价格上没有差多少。于是选型并不费事,直接就选用了腾讯云存储。

然而,我还需要根据我的选型,去做一个使用这些新服务的费用评估。这个费用评估报告,也会交给上级领导,最后由他们来拍板,是否使用腾讯云储存服务来作为媒体资源的提供者。

一切顺利,我的选型报告给领导看后,认为这个方案是可行的。一个预期的结果是,通过使用腾讯云存储方案,能够使app上的图片加载速度快将近10倍,这样的好事,为什么不做?

技术方案

摸着石头过河

我自己决定了技术方案,这个技术方案的核心是摸着石头过河。因为在当前的技术栈中,还从来没有使用过云存储,我们谁也不知道上云会有哪些风险,会产生多少费用,即便是有一些评估,但毕竟难以保证准确。

既然是摸着石头过河,我的第一步是先在app上做一个完全新的功能出来,这个新功能一定要用上云存储。这样做有几点好处,其一,数据是完全新的,没有任何历史数据,不用额外去做数据的迁移工作。其二,在做新功能的期间,也能够熟悉了解云存储接口和使用。

我选中了订单的评价功能的改进,来作为我使用腾讯云的第一步。由于历史的原因,以往的订单评价功能,只能给出文字评价以及好中差评,并不能带图片评价。之前,已经有业务部门的同事要求,希望能够实现带图评价。于是正好借助这个功能,练练手。事后来看,我这个思路非常好,这个功能做好后没多久,app所有的可用资源就都以腾讯云存储的数据方式展现了。

在这期间,由于后端语言使用的是python,因此直接参考腾讯云存储的python sdk文档 是很快速高效的学习方法。通过简单的测试,可以很方便地对接口进行熟悉。

技术细节

本地数据和远程数据

从一开始我就不想完全放弃本地数据,也就是说,即便是我将所有的本地数据都迁移到了云上。我还是要在本地进行一次备份。数据的存储,删除,更新等操作,一定是先在本地完成,再同步到云上。这个同步的过程,为了快速,并不是说再执行一次迁移数据的脚本,而是说,将原有的操作,在云上再重新执行一遍。而实际客户端读取资源文件时,还是直接拉取云上的资源,而无须去获取本地资源。这里要再多说两句,最初我为了以防万一,写的读取资源的方法,原理是如果云上没有这个资源,就去读取本地资源,但是经过实际测试,发现判断云上是否含有某个资源的方法(get_qcloud_object)执行效率太低了,考虑到我当时已经将所有的数据完全进行了迁移,并且保证本地所有的操作,也会同步到云上,因此我可以放心地拼接一个可用的云存储链接,来作为我的图片资源地址来使用。这样以来,整个读取速度就上去了一大截。当然这样做还有一个好处,也就是容灾,我看到前不久,阿里云的北京机房还出了乱子,导致很多app处于不可用状态。我这个方案,当然能够很好地解决这个问题,一旦腾讯云上的资源处于不可访问的状态,我也可以快速地进行部署,然后将资源读取从腾讯云切换到本地机房服务器。

说到这里,其实已经很明白了。其实我的核心方法,只有三个。一个是上传数据的,用到的sdk里面的方法是client.put_object这个方法,另外一个是删除数据,用到的sdk里面的方法是client.delete_object,还有一个则是展示资源的方法,这个方法是完全自己写的,其原理也不过是将云上的资源url拼接好。

本地bucket与远程bucket

在实现腾讯云存储的时候,有一个bucket的概念。其实按照我对于bucket的理解,就是跟他的中文解释一样,是一个篮子。这个篮子里面,什么东西都可以往里面装。在我最初的设计中,我考虑到要创建一个bucket的时候,想到了直接创建一个名叫commentbucket来存放商品评价图片。之所以这么做,也是因为我在本地也是想要创建一个commentbucket,但是后来发现不能简单地将本地bucket与远程bucket一一映射。

这主要也是从两个方面来考虑。第一是数据的迁移,数据迁移的时候,其中一个配置项就是bucket的名字,这个时候如果我将本地20几个bucket一一迁移,就会显得很麻烦,每次都要修改配置文件,也要上传好多次。所以这个时候我开始考虑将原来的bucket放到下一级去处理。这有点像是苏联的成立,原来的共和国本身也是国家,但是我让他成为苏联的加盟共和国,这样就能够方便管理。同样的道理,我这里只要对象存储上创建一个bucket,由它来作为‘苏联’。这样就能够让我的数据迁移工作更简单。

方便的还不只是数据迁移,由于在腾讯云的对象存储中,每个bucket需要单独配置。比如,跨域访问CORS设置,防盗链设置,回源设置,是否开启CDN设置等,这些操作我们不能通过API来完成,必须要通过工程师手动配置。而如果有多个bucket的话,那么配置起来就会很麻烦。

而我最后虽然建立了一个苏联,但是也只不过是多写了两行代码,将原来上传资源,删除资源,展示资源的方法又修改了一下,重新做了映射。一起都非常简单,就能够解决我的难题。

当然,我们也是需要考虑每个bucket的最大存储空间和存储资源数量,我后来调查了一下。发现我的数据量,完全可以将原来的多个bucket合并成一个,而无需担心这个问题。

迁移数据

迁移数据乍一看是个麻烦事,我开始有几点考虑。一是整个bucket的数据量,达到了几十GB。当时考虑如果在网络情况不好的情况下,一天的时间也未必能够完成数据的全部迁移。有这个担忧并不是毫无道理,我最先想到的其实是当前用迅雷下片的体验,几个G的资源都要下载几个小时,更不要说是几十GB的大量碎片文件了。但是后来发现,我本地网速还不错,上传的速度够快,至少是比我想象中要快。我的第二点考虑,虽然数据迁移速度很快,但是由于在迁移工作开展之前,并没有对哪些数据需要迁移进行分析,致使有很长一段时间,我都看着terminal窗口中在上传一些日志文件、发票文件。而这些文件,用户是很少有感知的,其实也并不是我此次工作想要解决的问题。

这个时候,就看出腾讯云这个数据迁移工具的可配置性了。

在本地迁移中,有两个设置,一个是用来设置本地数据迁移的包含目录,一个则是需要排除的目录的。

1
2
3
localPath=/opt/demo/var/buckets

exeludes=/opt/demo/var/buckets/log;/opt/ljmall-public--2/var/buckets/invoice

通过上面的配置,我就可以将占用大量内存空间的日志文件,发票(主要是pdf)文件排除出去,节省了云上大量的存储空间。

由于对配置文件进行了修改,也加上网络情况良好。实际上,整个数据迁移的过程不仅快速而且也很完美。并没有出现丢失数据的情况,这里需要补充一点,由于腾讯云存储数据迁移工具是支持日志记录的,因此所有已上传成功的文件信息都已经记录在日志中,这样也避免了重复上传等问题。所以,虽然我在中途修改了两次配置文件,但并不影响我最后将我需要上传的资源快速高效地上传上去。

由于在迁移数据之前,几乎所有的图片资源都是由运营人员产生的,所以我特地选择了一个运营不上班的周末来做这件事。之后,只需要在迁移数据完成之后,将原来写的上传、删除、展示资源的方法启用,之后所有的数据就能够实现同步了。当然,为了做的更好一点,也是可以每隔一段时间,定期执行迁移脚本,来保持数据的同步的。只是,从我目前的观察来看,无需定时迁移的脚本已经能够满足业务的需要了。

前端资源的处理和上云

本来我做这个功能的时候,最初其实只是想把图片等媒体资源进行迁移,这样能够确保用户在访问媒体资源的时候,不至于因为网络情况差,造成打开图片卡顿,半天出不来一张完整的图片。然而后来,我仔细想这个问题。所谓的对象存储,理论上来说,只要是静态资源文件,就都可以用上这个方案。因此,后来,我也将微商城的前端资源放到了云上。

这些前端资源是由webpack生成的一些js,css等文件,也包括由url-loader生成的一些图片资源,字体资源等。我使用到了一个开源的前端工具库来帮我自动完成build之后的上传操作,这个工具库是cos-webpack

这里的一切也很简单,不过这个工具库,让我觉得有一点不舒服的是,他只会负责将生成的文件上传到云上,但是却不会负责将云上原有的资源删除掉,这样一旦新的前端资源上传上去了,部署了新的前端代码。那么那些老旧的前端资源就失去了意义,再也不会有他们的用武之地。我并没有对这个前端工具库进行修改,直接使用了。当然,这样的设计也有好处,因为我们build新的前端资源的时机有可能与我们下一次部署服务的时机并不相同,这个时候如果说build之后,就将原有的资源删除掉,那么就会直接导致线上的某些页面,甚至所有页面处于不可访问状态。这显然不是我们希望得到的结果。

也许有一天,我会对之进行修改,做一个更好的工具,来处理前端资源。

顺便多说一句,我将前端资源单独放到了一个叫做febucket里面。这样,实际上,我整个项目完成之后,一共是有两个bucket,也能够很好地应付业务,逻辑清晰。

智能压缩

在使用COS来作为前端资源存放地的时候,还发现,如果不应用CDN的话,我没有办法做到资源的压缩。我们知道,包括js,css等资源,通过gzip压缩之后,能够节约一半以上的体积。对于chrome等浏览器来说,就意味着传输效率快了一倍以上。在没有应用COS之前,我们通过本地服务器上的nginx来实现gzip。相关原理,点这里:探索HTTP传输中gzip压缩的秘密。但是如果直接使用上传到COS上的资源链接,正常加载的时候,是不能进行智能压缩的。查看文档才知道,只有配合了CDN之后,我才能够实现智能压缩。但是仅仅启用了CDN并没有什么作用,后来我为此还专门发了工单提问,后来终于在腾讯云工程师的帮助下解决了。原来,我虽然启用了CDN,但是我没有相应地将对外展示的资源url进行修改,用户访问的其实还是对象存储北京机房里面的数据。后来,当我将url重新拼接,换成cdn的链接后,智能压缩才应用上。

CDN的设置

在使用过程中,由于没有或对CDN设置得有问题,导致CDN上的资源加载也出了问题。

需要说明一下的是,当以COS源的方式接入CDN的时候,在对象存储上的bucket是与CDN上的域名一一对应起来的。正式因为有这样的对应关系,我又要说了,我建立的那个苏联是多么的有必要。只需要一个苏联去跟美国单独建立外交关系,而无需各个加盟共和国单独去建立外交关系,省了好多事。

我最初设置了一个IP访问限频配置,当时设置的时候也没有在意。后来过了几天,发现有时候,资源的访问会出现514 错误,经过查询才发现原来是这个设置出的问题,又赶紧把这个设置放宽到了一个比较大的标准上。

另外,前面提到的fe这个bucket也出了问题,有跨域的问题,后来我把HTTP Header配置进行了设置,问题才得以解决。

当然,前面提到的智能压缩,在默认情况下也是关闭的,需要手动打开。

效果和理解

开始的时候,我虽然考虑到了要使用腾讯云的对象存储(COS)服务,也想按照大众的做法用上CDN,但是坦白讲,那个时候我对CDN还没有一个特别清晰的理解。我当然知道他是内容分发网络,能够让资源分配到各个节点,让全国各地,甚至全球各地的用户在获取资源时,都能够享受到一个比较快的速度。我有这样一个理解,但是还是很难将他与对象存储之间的关系说明白,讲透彻。

后来真正开始使用对象存储和CDN了。有那么几天,也通过腾讯云的后台,观测数据的变化,渐渐得也观察出来点门道。且听我一一道来。

我最初只用了对象存储,因此资源的访问地址就是

1
bucketname-appid.cos.region-code.myqcloud.com/key

如果上面的参照不好理解,可以举个例子,比如:

test-125777777.cos.ap-beijing.myqcloud.com/test.jpg

由于我访问资源的时候,已经指定了资源是在ap-beijing这个机房,因此全国各地的用户访问app进而访问到这个资源,都会从腾讯云北京机房获取这个资源。需要说明的是,我们的本地服务器的所在地也是在北京,但是由于我们本地服务器在网络延迟,响应速度方面还是与腾讯云有较大差距。从实际体验来看,只使用对象存储而不使用CDN已经对app中资源的加载速度有很大的改善了。(实际经过统计发现,有60%的流量是来自于北京,外地的流量不足一半)

之所以,我们还要使用CDN,一方面当然是希望能够越快越好,尽善尽美,这也是我作为一个开发者的追求。由于我身处北京,很难去测试外地用户在直接访问源站的时候的速度,但是我却能够通过CDN 的后台看到,全国各地,访问资源,普遍的延时在200ms以内,这对我来说,是可以接受的。另外一方面,其实从整体费用上来看,使用CDN并没有增加多少费用,没有使用CDN之前,费用的大部分来自于COS外网下行流量费,应用上CDN之后,由于用户可以访问分布在全国各地的各个节点来获取资源,因此对于COS来说,它的外网下行流量没有了。取而代之的是CDN流量,以及CDN回源流量。这里有必要再解释一下CDN回源流量,我最初还没有应用上腾讯云的时候,也不是很能理解CDN回源流量,当时在做费用评估的时候,将外网下行流量=CDN回源流量来计算。

实际上,按照我的理解,应该有这样的公式。在未使用CDN之前,

总流量 = 外网下行流量

在使用CDN之后,

总流量 = CDN流量 + CDN回源流量

当然我这里必须有一个前提,那就是COS(对象存储)的外部读取完全基于CDN。

通过上面两个公式,我们可以得出一个简单的结论,由于使用了CDN,外网下行流量没有了,由于业务的情况,总流量约等于CDN流量。

既然总流量约等于CDN流量,那么这个性价比就可以说非常高了。

后话

完成这个工作之后,被运营人员夸奖,说是自己家的app已经赶上天猫的速度了,听到这个话,还是很开心的,也不枉我这些天的努力。