致王勇

以下内容是我在知乎对“如何看待Deepin操作系统创始人王勇离职”的回答。 这个月,从王勇改微博后缀,到删除deepin字样相关的代码,再到一则朋友圈,最后论坛的一篇《感谢亲爱的你们,大家继续加油》,有好几个朋友过来问、或者代朋友问王勇的情况,我虽然已经知道他的打算,但是不管朋友远近我都是说他在家休息,因为我知道他离开的消息有多大的影响。现在大家都知道了,也都震惊了,有人觉得伤感、失落,包括我自己都一样,这没什么,但是很多无良的媒体大肆渲染,最后以讹传讹,我甚至感觉我明天就不用去上班了…… 压抑了好久,有必要在这里说说。 王勇离开深度,我觉得对我最大的影响是 少了一个导师,没有了精神寄托。 跟很多deepin的粉丝一样,我还在上大学的时候就知道了deepin,随之就对deepin和ManateeLazycat(王勇的网名)产生了巨大的喜爱,成了王勇的脑残粉;幸运的是我居然凭着自学(当然也得感谢当时猴哥和xiangzhai在网上对我的指导),拿到了去深度工作的机会。而我刚进深度的第一个目标就是“王勇,我要在技术上超越你”,被王勇知道后以至于到现在还被他拿出来刺激我 :O 深度当时的技术氛围非常浓厚,因为一个屋子,清一色的程序猿。所以在深度的第一年里,是我技术成长接触面最广的一年,学了很多语言,接触了很多技术,对我影响最大的可能就是跟着王勇和猴哥学了Emacs,另外也自学了Elisp和Common Lisp,虽然当时心高气傲搞了一个hualet-emacs,实际上用王勇的话说“就是对着deepin-emacs抄嘛 :P”,事实上也确实如此,那时候也是第一次看到王勇在UI细节打磨上执着,他把emacs的每个插件都折腾成自己的风格,所有插件放在一起你都不觉得他们是分开的,自成一套体系,对我影响很大。 后来的一年多时间,是我在深度的沉寂期。默默无闻,但是我看到了王勇做的一些事情,其中就包括跟其他社区的人吵架,或者叫“互喷”吧。当时有点不能理解,社区都好好相处,不是挺好么,还容易积聚力量,后来慢慢懂了。前段时间看《走向共和》和《曾国藩的正面与侧面》,我觉得王勇很像晚清那些想叫醒中国人的斗士、英雄,看到开源社区很多浮在空中的“所谓的大牛”,说的话都对,却很少或者说从来不做实事,而愤怒地发出怒吼。 “有了求实一念,人才会从道德制高点上下来,脚踏实地,不激不随。”我觉得王勇能成为我心目中的领袖,是他很早就知道“求实”,而不是站在道德的制高点上喷这个、吹那个。 15年的时候,我迎来了自己在深度的机会:掌管桌面组和系统发布。但实际上当时我申请了这个职位以后没过两周我就后悔了,深度的用户都知道,15版本是近年来最大的一次版本变迁,首先是仓库从ubuntu切换到了debian;另外是桌面环境全换Qt重写。这对我来说不仅是巨大的工作量,关键是我当时还主要是做应用,压根儿不知道这个桌面是怎么一步一步被做出来的,还要面临的一个问题是为了赶商业机会,我们的重写必须在那3-6个月完成,那时候真的是异常痛苦。 也就是这个时候,我和王勇的关系才从以前一种盲目崇拜与被崇拜,变成了学生和导师的关系。记得非常清楚,无数个加班的夜晚,我跟兄弟们加完班以后,还得找王勇“倒垃圾”,这个事情有多难、有多坚持不下去、这方面有问题怎么办、那方面又问题怎么办……有时候王勇也不见得有什么好的办法,但是有一个人一直在支撑你走下去的感觉,会产生奇迹。这种经历一生也不会有太多。 那半年是我蜕变的半年,王勇在其中起了太多的作用。 所以要说王勇身上背负的不仅仅是自己的压力,还要背负兄弟姐妹们身上的压力,这个压力我自忖是完全承受不来的。这也是为什么当时猜出来王勇要离职的时候,我对他说“从公司员工的身份上我对你这个决定是接受不了的,但是从朋友的角度我觉得你做这个决定我很佩服”。他确实承受了太多事情,如果都这么决定了,我们能做的就是尽量不要给他压力。 王勇临离开之前做的最后一些事情,就是研发各个团队的负责人挨个谈了一遍,跟我说的内容很少涉及自己怎么样,更多的是帮我捋清方向。 就这样。 至于说深度会不会因此倒闭了,或者说deepin项目会不会凉了,我觉得至少短时间内不会。 一方面,王勇作为武汉研发总部的负责人,长期以来从来也没有忘记去培养人,培训和言传身教,影响了一部分有想法的同事,虽说我们现在没有能力像他一样作为个人去领导一方,但是目前在做的事情是可以承担起来的;另一方面,就像 张成前辈 的回答里面说的一样,深度前期能在完全没有盈利目标的情况下开始做,到现在依然坚持在为社区做贡献,王勇的热情是一部分、刘总(deepin)对社区的看重是另外一部分。现在王勇出走了,但是我没有看到刘总说社区就此打住、不再做了,实际上公司上下稍微有点Linux背景的人都没有质疑过社区这一条方向。所以deepin项目不会就此凉了,相反我们可能会在做国产化的同时去探索更多的面向社区和普通消费者的方向。 最后,致勇哥一声深深的谢谢!

使用 Perf 优化程序性能

因为原定deepin 15.7会做优化(能耗、资源占用等)方面的工作,所以在此之前,想提升一下团队整体的性能剖析、优化方面的水平,也就有了这次(周五)的培训。本来想用视频记录的,一个是自己回头能看看,反思和改进一下演说能力;另一个是以后有新人入职,我也就不用挨个再讲一遍,天不遂人愿,录制视频的软件半道挂了( 所以只能这里尽量回忆当时想表述的内容,这里文字稿记录了。 下面就是培训内容: 好,人到齐了我们就开始了。今天要培训或者说要分享的内容是程序性能优化方面的内容,其实我们对性能优化不陌生:最开始接触龙芯和申威平台,系统组件间调用不是异步导致系统卡得无法使用;好不容易交了一个版本,控制中心各个模块还是因为切换卡顿、使用体验不好等做改进;前段时间为2G内存机器做优化等等。现在我们因为程序设计问题导致的性能问题比以前少了很多,一方面我们还要对这些部分持续改进,另一方面我们需要掌握一些性能剖析工具的使用,来帮助我们改进一些更细粒度的程序性能问题,今天我们主要集中在程序执行性能、也就是CPU占用这部分的性能优化。 今天培训的内容比较基础,还是老规矩,我做敲门砖,其余的还需要各位发挥。 刚才说了我们以前做了几次优化,我们再来回顾一下为什么要做性能优化。第一点肯定是占用过多的系统资源,不论是CPU、内存还是IO,如果系统组件的资源占用比较高,那系统资源有限、程序间的资源又是会互相竞争的,必定导致用户使用的应用程序的可用资源减少,在一些配置普通的机器上,可能就会导致第二个问题,也就是系统使用不够流畅,当然导致系统使用不流畅也分两部分原因,一个就是我们刚才说的,系统组件占用资源过多,另外一个也是刚才提过的程序架构设计有问题,导致卡界面等等; 第三个是性能问题在低配置的机器上会被无限放大,就像我们在最初的龙芯和申威平台一样,在x86上可能感受不到或者感受不太强烈的问题,在龙芯和申威上就会严重到无法使用(当然,现在的龙芯和申威平台使用已经没有问题了);最后一个也是跟我们15.7想要解决的能耗问题息息相关,就是能耗高、发热大。主要是我们有些系统组件“不老实”,很多情况下随机“抽风”。 这个问题我们论坛用户提到的也不在少数: 当然了,大家可能也知道功耗主要跟系统配置关系很大,例如CPU开不开睿频、有没有设置节能模式,各个网卡、声卡驱动有没有设置节能模式等等,但是我觉得至少我们的程序至少不能成为能耗高的帮凶吧。 现在的情况是我们的程序不仅是帮凶,而且帮得很厉害,一会儿会给大家看一下。 刚才说了我们做了很多次性能优化,可能很多用户期待说我们能一次解决所有性能问题,但是实际上性能优化是持久战,它是一个需要持续做下去的事情。 另外主要还是因为性能优化很难,第一点主要就是性能瓶颈的定位很难,比如最开始我们系统登录的过程非常慢,所有程序都是并行启动,看着所有的系统资源占用都很高,换成串行启动以后,依然如此,这个定位当时就比较麻烦; 第二点是有时候优化的效果并不明显,虽然说我们看到有时候系统的资源占用挺高,但是可能分到每个程序中就不是特别多,做性能优化得慢慢抠,可能从单个程序来看效果并不明显;第三点是有时候做性能优化的技术和经验要求比较高,一方面是性能剖析工具的使用、对程序运行的本质要熟悉,另一方面就是要对被优化程序的代码要非常了解,不然就会导致我们说的第四个问题:优化可能影响正常功能。比如我上次给Dock提交了一个性能优化的提交,虽然有让sbw同学审核代码,但是最后还是导致了一个功能性bug。 虽说性能优化很难,但是……不积跬步无以至千里。所有复杂的系统都不是一天两天做好的,比如我们的桌面环境,到现在经过了四个版本,基本上就是四代人的心血堆积,才做成现在这个样子。 我们每个人都能做好自己那部分的话,众人拾材火焰高,解决系统性能问题我觉得没有那么麻烦,这其实也是为什么我这么迫切要组织这次培训/分享的原因,还是希望我做好敲门砖,像去年做高分屏支持一样,虽然是我开的头,但是其实最后基本上每个都比我做得好,最后我们做高分屏的效果也非常不错。 刚才说了性能优化很难,大家也不要害怕,其实性能优化也没有想象的那么复杂。 第一个是因为现在优秀的工具很多,比如右边这个非常出名的图,来自 Brendan Gregg 大神的博客。把系统性能优化每个部分对应的工具都清楚的标出来了。 第二个说实话是因为deepin的性能问题还比较多,比较容易发现,相应的上层的性能问题也多,所以说性能优化简单也是因为我们这次主要将注意力集中在 Applications & System Libaraies & System Call Interface这三部分即可。这部分的工具可以看到其实就是 perf、ltrace、strace这些,最多加上 bpfcc 、eBPF等。 说deepin性能问题还比较多是大家可以看到,静置状态下,我什么都不操作,几个组件就又可能时不时抽风一下(占用CPU部分)。 看到了有性能问题,但是我们总得有办法把这些性能问题优化掉吧。 性能优化一般分三个部分,第一部分就是查找程序性能热点,实际上一般我需要先定位性能瓶颈到底是在哪部分,是CPU?是内存还是IO等。不过我们这里目标很明确就是优化CPU占用,所以可以直接朝着有性能问题的程序去。 第二步是热点诊断和修复,找到了性能热点,我们肯定需要修复吧,看看导致这个热点的原因,正常进行修复即可。 第三步是回归测试,就像我们平常修bug一样,修了bug要测试,做了性能优化也一样,我们需要做回归测试、对比一下前后的性能数据。 我们先来看第一步,利用perf查找程序性能热点,这也是我们今天要说得重点。 perf这个工具最开始是作为Performance Counter的接口引入内核的,但是慢慢引入了一堆调试接口如 tracepoint、kprobe、uprobe等等,也就慢慢发展成为Linux几乎最好用的性能调试工具了。 我们平常使用的perf命令是用户态的工具,前面说得那些都是内核里面做的事情,内核态工具主要是对搜集到的数据和事件进行处理和统计。因为这个工具跟内核版本关系比较紧密,所以安装perf的时候需要注意跟内核版本对应的问题。当然,调试的时候装dbgsym包是必须的。 使用perf查找程序性能热点,一般主要用到三个子命令,第一个就是 perf top,这个很好理解,top命令大家都用过,那个top主要是针对进程或者线程级别的资源占用进行统计和展示,perf top可以理解为函数级别的top,可以动态展示系统目前占用资源最高的函数分布情况,它后面的 -g 是启用函数栈,-p 后面加上进程 PID就可以针对单个进程进行追踪,这个跟top命令一致,如果不加 -p 就是默认系统级的统计和展示。 第二个命令是 perf record,它跟第三个命令 perf report 是搭配使用的,record 用来记录一段时间内的程序执行情况,然后用 report 来进行展示。 -g 参数的意义跟 perf top一致,启用了函数栈以后,我们可以使用 –call-graph 来制定使用哪种方式来获取函数栈: fp 方式,是使用传统的方式 frame pointer来获取堆栈,这个我在之前的文章中也介绍过; Read On →

自制 Profiler 第二部分——调用栈回溯

书接上篇,我们现在已经能在其他程序中执行我们自己的代码,并且也做到了以固定的频率去执行采样代码(我们的printf),但是如何采样还是一个问题,这篇文章会就这这个问题继续探讨接下去我们面临的挑战——调用栈回溯。 为什么要获取函数调用栈?一方面是因为profiler除了要分析程序存在的性能问题,即函数执行热点以外,还需要帮助我们可怜的程序员找到问题的原因,这时候能提供问题函数的堆栈信息就非常必要了;另一方面,我们上一篇文章其实说了,是为了通过堆栈信息尽量还原程序的执行过程:试想一个程序执行的过程是 main->funca->funcb->funcc,我们第一次采样 main->funca,第二次采样 main->funca->funcb->funcc,假如我们没有堆栈信息,我们只会统计一次 funca 和一次funcc,但是这并不能反应事实,相反,我们有堆栈信息的话,就会把 funca 、funcb 和 funcc 各计数一次,更能反应实际的执行过程。 概念 函数调用栈(Call Stack)和相应的栈帧(Stack Frame)我们其实都不陌生:在使用 gdb 调试程序的时候,bt(backtrace)命令打印出来的就是函数调用栈;而函数调用栈列表中的每一项则代表一个栈帧,我们执行 frame 命令跳转到某一个栈帧,其实就是一次回溯的过程。 想要在内存中解析出我们想要的函数调用栈,首先我们需要知道的就是一个程序的stack 段里面各个栈帧是如何布局的,要搞清楚这个,我们还需要了解一个概念叫:调用约定(Calling Convention),调用约定主要约定了(好绕): 函数的参数是如何传递的,是全都放到寄存器,还是全都放在 stack 段,还是混用两者; 函数的参数是按什么顺序放置到内存中的; 函数中的本地变量是如何分配的; 子函数调用是如何返回的; 子函数的栈帧是如何清理的; 等等 所以,调用约定基本上决定了函数调用中每个栈帧的产生、压栈、出栈对内存布局的影响,而这个约定是因架构和平台而异的。我们这里只关注x86 平台下的 cdecl 约定。 在这个约定下,假如我们有一个函数 DrawSqure 调用了 DrawLine (例子来自Wikipedia),那么程序内存布局中的 stack 段就应该是类似下图所示: 每个函数调用即创建一个栈帧,每个栈帧一次压入 stack 中。 其中,Stack Pointer(esp) 永远指向栈顶, Frame Pointer(ebp) 指向当前栈帧的中一个固定的地方(基地址);函数参数以从右往左的顺序依次压栈,然后是压入Return Address ,它是当前函数(或者栈帧)执行完成后,程序要继续执行的指令地址, 同时压入父函数的栈帧基地址(Saved EBP),它是当前函数执行完成以后,Stack Pointer 和 Frame Pointer 将会指向的地方,基于这个地址,程序指令可以方便地访问函数本地变量(ebp负向偏移)和函数参数(ebp正向偏移)。 结合上面两张图,其实可以看出,每个栈帧其实都保存了上一个栈帧的基地址,因此所有的栈帧最终组成了一个链表,这也就是我们能拿到函数堆栈的理论基础了。 (注:上面只是粗略的讲解,参考链接 [1] 非常详细的描述了函数调用的过程中栈帧、stack 段和esp、ebp寄存器的变化,如果感兴趣,可以详细了解一下。) 参考方案 看完上面一大串概念以后,我们发现如果我们要按照函数约定的方式去获取函数调用堆栈,可以,但是太过蛋疼,而且不跨平台,很难受。 所以秉承不要重复造轮子的优良传统,我们发现有几个方式可以简单地获取到函数调用栈: Read On →

自制 Profiler 第一部分

​ 最近对性能剖析的技术颇感兴趣。好不容易来了三分钟热度,自然不能浪费,因此在余热消失之前研究并实践了其中一部分细节,对于其中一些知识点,个人感觉对于自身编程能力提升还是比较有益的,因此在这里写出来,抛砖引玉。 Linux profiler简介 ​ 性能剖析的工具,其实在Linux平台还是挺多的,比如小巧实用的strace、ltrace、latrace,大名鼎鼎的google-perftools、gprof、valgrind,以及瑞士军刀型的linux-perf等等,它们主要分为三个阵营,一个是针对程序执行的性能进行剖析,对程序执行的热点进行分析,如*trace、gprof这些工具;另一个是针对程序运行过程中内存的使用进行剖析,方便针对性地做内存优化,如valgrind;最后一部分就是“脚踏两条船”的,两个我都做,比如google-perftools、linux-perf这些,我们这个系列主要集中在“针对程序执行的性能进行剖析”方面。 Profiler的本质 ​ 要自制Profiler,首先要知道Profiler的本质是什么。简单来说,Profiler的本质其实就是在程序执行的过程中对程序正在“做什么”进行搜集和统计,如何搜集呢?无非两种: Instrumentaion - 程序主动Profiler告诉它在做什么; Sampling - Profiler自己间断性地去看程序在做什么; 前者的实现主要依靠程序运行时提供的某些钩子机制、代码插桩等方式,例如gprof主要是依靠 gcc 在编译程序的时候”夹带私货“来达到程序运行的时候主动提供给gprof采样样本,来达到事后分析的目的[1]。这种方式相对来说虽然比较可靠、准确,但是对于无法控制编译条件的程序就比较无可奈何了。 后者的实现则主要是定期对程序当前执行的指令和对程序执行的函数堆栈进行回溯(unwind)来尽量还原程序执行的过程,例如google-perftools就是采用这种方式,这种情况下,采样的周期就显得尤为重要。 ​ 对比以上两种方式,我们果断采用第二种。 ​ PS: 这里需要说明一下的是,利用ptrace系统调用完成工作的strace和ltrace,虽然不依赖编译器夹带私货,但是相当于依赖了内核的“钩子”,不属于sampling的范围;同样,latrace则是依赖了ld的LD_AUDIT“钩子”,也不属于sampling的范围。 Profiler启动 ​ 那么问题又来了,ptrace没得用,我们怎么去获取被剖析程序的执行状态呢?总不至于profiler要搞成root权限的吧?答案是:不,内核管天管地,总管不到程序自己偷看自己的数据吧?我们想办法把我们的代码塞到被剖析程序中去就可以了! ​ 刚才提到了ld的LD_AUDIT,这次就轮到它的兄弟——大名鼎鼎的LD_PRELOAD——登场了。想法是这样的,我们的profiler其实只需要在程序开始的时候执行一个定时器,以后每次定时器执行的时候去抓取我们的样本就OK了,所以我们完全可以把自己伪装成一个人畜无害的动态库,等到别个程序有意无意加载到我们,哼哼……事实上,很多profiler都是采取类似的策略,比如google-perftools,再比如heaptrack等等。 编码实战 ​ 废话少说,放码过来! ​ 我们在QtCreator中创建一个动态库项目 simple-profiler,主类 SimpleProfiler。首先,我们需要设置好我们的定时器: void SimpleProfiler::enableProfile() { int ret = setitimer(ITIMER_PROF, &m_tick, nullptr); if ( ret != 0) { fprintf(stderr, "failed to enable profiler: %s", strerror(errno)); } } 根据 setitimer 的man文档,计时器主要有三种类型: ITIMER_REAL 这个计时器是根据墙上时间进行倒计时,最终触发 SIGALRM 信号; ITIMER_VIRTUAL 这个计时器是根据进程花费在用户空间的 CPU 时间进行倒计时的,最终触发 SIGVTALRM 信号; ITIMER_PROF 这个计时器是根据进程话费在用户空间和内核空间的 CPU 时间进行倒计时的,最终触发 SIGPROF 信号; 个人认为,假如都是用在 profiler 上的话,第一种计时器用来查找程序执行慢(某个函数有IO等情况)的瓶颈比较有效果;后两种计时器用来查找程序 CPU 占用瓶颈比较有效果。不过使用第一种计时器的话,对被追踪程序的执行影响相较于后两者就比较大了,所以这里采用第三种计时器。 Read On →

初探Linux内核态——通过proc文件系统作快速问题定位

文章翻译自 Peeking into Linux kernel-land using /proc filesystem for quick’n’dirty troubleshooting 这篇博客的内容完全是关于现代Linux内核的。换句话说,指的是与RHEL6一样使用的2.6.3x系列内核,而不是古老的RHEL5所使用的2.6.18内核(都什么鬼了?!),虽然大部分企业都还在使用RHEL5。另外,这篇文章也不会涉及内核调试器或者SystemTap脚本之类的东西,完全是最最简单地在有用的proc文件系统节点上执行“cat /proc/PID/xyz”这样的命令。 定位一个程序“运行缓慢”的问题 下面要举的这个例子是这样的:一个DBA反映说他们的find命令一直运行缓慢,半天都没有什么输出,他们想知道这是为什么。听到这个问题的时候我就大概有直觉造成这个问题的原因,但是他们还是想知道怎么系统地追踪这类问题,并找到解决方案。刚好出问题的现场还在…… 还好,系统是运行在OEL6上的,内核比较新,确切地说是2.6.39 UEK2。 首先,让我们看看find进程是否还在: [root@oel6 ~]# ps -ef | grep find root 27288 27245 4 11:57 pts/0 00:00:01 find . -type f root 27334 27315 0 11:57 pts/1 00:00:00 grep find 跑的好好的,PID是27288(请记好这个将会伴随整篇博客的数字)。 那么,我们就从最基础的开始分析它的瓶颈:如果它不是被什么操作卡住了(例如从cache中加载它所需要的内容),它应该是100%的CPU占用率;如果它的瓶颈在IO或者资源竞争,那么它应该是很低的CPU占用率,或者是%0。 我们先看下top: [root@oel6 ~]# top -cbp 27288 top - 11:58:15 up 7 days, 3:38, 2 users, load average: 1.21, 0.65, 0.47 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie Cpu(s): 0. Read On →

15.5研发心得

迟到的经典 2017年11月29日,农历十月十二,经过一番挣扎,deepin 15.5的ISO终于安静地躺在了内网服务器上,静待着属于它的时刻的到来。 是的,deepin在重新定义了十月一日为农历十月初一以后,甚至连“保证月底发布”的底线也没有守住,妥妥地把发布时间拖到了十一月(阳历)中旬。即便如此,我也觉得这次“迟到”是值得的,在“手机不赚钱,交个朋友”的时代,PC操作系统的研发需要特别用心,才能留住那些对我们期待了那么久的用户朋友。我想,在未来可以预见的时间内,所有deepin的用户都会记住这个特殊的版本号:15.5。这个能让我们在视觉体验上有质的飞跃,在应用包格式上走在世界前面,自带修复工具箱——live修复系统,并且在稳定性和易用性上大幅提升的版本。 deepin15.5注定成为经典。 故事 按照传统,一年中各大版本的主要功能都是预先定义好的,搭配一点重要的bug修复和用户体验改进,基本上就妥妥的了。但是15.5是个奇葩。在七八月份定义15.5详细需求的时候,我们梳理github上的issue,发现一条一岁半“高龄”的主题,大意是“跪求高分屏支持”;同样早在16年初,公司成立了一个神秘的组织叫“Alpha Team”,这个小组的第一个任务就是“独立包格式”;在记忆都稍微有点模糊的14年,就有用户想要在deepin下创建热点……这几个严重拖延的任务让人汗颜,所以我们当时就任性地决定15.5主要来解决这些问题。虽说是决定,但是并没有人特别自信,“毕竟是拖了这么长时间都没有解决的问题”,再加上高分屏涉及面太广,深度全家桶都要“挨刀子”;独立包格式本身社区也不统一;WiFi热点挑硬件,Linux下的网卡驱动又不都是那么好……越想越恐怖。 “要不再加点其他任务?”,我提议。 众人惊恐状。 “这样万一前面几个任务完成不了,做点其他任务应付一下老王嘛”。 逆向思维有时候还是挺管用的。 就这样,像是一锅羊肉火锅一样,15.5的配菜变成了主菜,也就是前面提到的三个点;又加入了新的配菜,VPN导入导出、应用代理、触摸板手势、色温调节、bug修复和其他一大波新应用等。 当所有人都以为15.5就这样的时候,一个不识趣的朋友跟老王说我们系统的恢复模式进不了root,所以系统一旦出了问题就只能靠重装大法解决。我闻风一边心想绝对不可能,一边赶紧试了下,结果是果然不好用。 还没等我返回神儿来,老王已经在Tower上建好了“live系统支持”的任务。 高分屏 高分屏支持的话题由来已久,大概是在我刚进入deepin(14年)的时候就有人在“布局”:图片资源一定要用svg、尺寸不能写死等等,然而坚持了一段时间以后,大家发现这种坚持似乎毫无意义,因为没有人用高分屏,自然发现不了高分屏那种细腻到看不到“痘痘”的美,于是乎慢慢地各种png、死尺寸就满天飞了。 俗话说“出来混总要还的”,因为以前的任性,在适配高分屏的过程中,deepin团队可谓吃尽了苦头。不仅几乎所有程序中用到的图片资源都要重新绘制(还好图标主题一直坚持svg),还差点在x2.png的道路上栽了个跟头,还好悬崖勒马,及时止损。 普通应用适配高分屏在如今的环境下,Qt和GTK等界面库的高分屏支持已经比较成熟,还算是比较简单的。但是桌面环境和一些特殊应用,如启动器、截图、录屏等,就需要些功夫了,在适配的时候还要考虑缩放前后的窗口大小、窗口位置等等,恰巧这些地方Qt的处理又比较坑,有时候实在受不了了,只能patch Qt来处理。 看图的适配也比较麻烦,很多地方都用到了缩略图。缩略图也要支持高分屏!听起来有点好笑,但事实是不仅是缩略图,很多情况下一条线、一个圆角的瑕疵,在高分屏下都可能被放大,变得非常恼人。 15.5的细腻就是在这种情况下“磨”出来的。 Flatpak Flatpak其实原名叫“xdg-app”,可能后来觉得不够高端大气,配不上“The future of application distribution”的名头,遂改名Flatpak。 按照官网的说法: Flatpak is the next-generation technology for building and installing desktop applications. It has the power to revolutionize the Linux desktop ecosystem. Flatpak将会改变Linux世界的生态。 不谋而合,同样这样想的还有snap技术。 snap是Ubuntu为了布局服务器和容器市场推出的一套解决方案,与Flatpak类似,它也是利用Linux内核提供的沙盒机制和方案,再加上一套包分发、安装、更新和卸载的辅助系统,来实现应用与系统隔离的想法,以解决目前Linux世界包分发过程中经常让人头疼不已的依赖问题和系统安全问题。 在两者之中,deepin毅然选择了Flatpak,为什么?因为从Mir vs Walyland的例子中,我们发现一个非常真实地存在于开源世界的“潜规则”:“政治不正确”的项目,在开源世界中一般是无法长久的,其中所谓的“政治不正确”其实就是“g家族”已经有同样的项目存在,又有人造了“轮子”。所以,与其寄希望于一个可能不能长久的项目,还是在Flatpak上孤注一掷来得靠谱一点。 想法虽然显得投机了点,但是像往常一样,deepin团队做起实事来一点也不含糊。深度全家桶中的成员,非系统级的应用,全数被打成了Flatpak包。重要的是,这些Flatpak包已经在15.5的ISO中替换了原来的deb包,也就是说deepin 15.5可能是全球第一个预置了Flatpak和自家应用的Flatpak包的发行版了。 “少数人活在未来,人们中的大多数则是静待着未来的降临,这是整个人类文明的演进方式”,最近耳朵里总是充斥着这样的声音。我想deepin团队在推动Flatpak上是走在世界前列的,为身处这样的团队感到骄傲。 live修复系统 对于喜欢折腾系统的用户来说,这次可能最期待的就属live修复系统了,它是个什么东西呢?可以这样简单理解,live修复系统就是一个超级mini版的deepin系统:除了量身裁剪过的DDE外,只预装几款必要的系统工具。最重要的一点是,live修复系统独立于你所安装的deepin系统,完全运行于内存中,这样,你就不会遇到在你修复系统到一半的时候系统弹出警告框,告诉你需要卸载某个磁盘之类的尴尬情况了。 在live修复系统中,预置有深度全家桶的一位新成员“深度备份还原工具”。这个工具具有化腐朽为神奇的超级牛力,它可以助你轻轻松松地把老系统上的数据迁移到你的新硬件上:全新的机器内部,还是熟悉的老伙计——deepin。 live修复系统为了保持简单、简洁,目前除了必要的浏览器、备份还原工具和终端外,并没有预置更多的工具和应用,毕竟要完全跑在内存里嘛。在系统中安装上live修复系统,打开启动器,你甚至感受不到它的存在!因为它的入口确实不在启动器里面,而是在grub菜单。好的功能/用户体验就是这样,需要它的人一定知道它在哪,不需要它的人完全没必要因为每天都能看到它而感到不自然。 在可预计的将来,应该会有更多实用工具登陆live修复系统,让你进入live修复系统,就感觉到自己像是被武装到了牙齿。 其他 每次介绍新功能,都不得不辟一个“其他”的栏目,因为新的变动实在太多,其中有些像网易云音乐新版一样,内部真刀实枪地大改造(用qcef替换原来的webkit),但是用户可能不会有太多直接感知的;还有一些“彩蛋”类的像是本次的“自动色温调节”,有些用户发现这个功能后溢于言表,幸福感可能都超过了使用这个功能本身的;另外的一些工具类,如Wi-Fi热点、VPN导入导出的工具类功能,天生就是理科男的命——绿叶。 在deepin系统的完整度方面,指纹识别算是这次的另外一个亮点了,如果你的电脑配备了指纹识别器,那么升级到15.5,你将从输入密码这项繁琐的工作中解放出来,一切都是那么顺滑。 Read On →

给小崔的基础管理课

最近小崔的日子好像不太好过,负责一个项目的同事发了farewell letter,于是她被莫名其妙地选中来担任整个项目的负责人。 这突如其来的变动,打了小崔一个措手不及:因为给同事分配任务不顺利气哭、因为担心第二天的工作是否能很好完成而失眠……就跟我刚开始担任深度桌面组组长的时候一摸一样。看着实在心疼啊,于是趁着今天天气好出去晃悠的时候顺便跟她传授了一点小小的经验,这里顺便记录一下,希望对有需要的朋友有所帮助。 在说初级管理的经验之前,我想强调一下“自信”,因为这是我觉得一个人能做成一件事情最基础的基础。如果连自信都做不到,那就不要妄谈管理了,你甚至连自己都做不好。小时候我妈一直说谦虚使人进步、骄傲使人落后,让我平时谦虚一点。我当时想不通,现在依然想不通,我甚至觉得自负要比自卑强得多,这是因为自信心实在是太难培养了。比如我虽然一直对自己的学习能力和技术比较(盲目)自信,但是我刚做管理的时候,其实也不自信能把所有人捏到一起、团结起来,但是因为心里面有执念觉得不能把做不到跟自己扯上关系,所以还是努力地去尝试,很清楚地记得有一次我当着所有人的面把自己的完整解决方案说出来那一刻,我的自信心才完全建立起来,之后的管理就相对容易了很多。说到小崔,我大概是不担心的,她只要把自己在镜子前臭美的状态转化一下,自信心应当是爆棚的 😄 自信做好了,用来做什么呢?这就是管理的内容了,管理不再是扎头自己的事情,而是掌握大局,在掌握大局以后在处理非自己处理不可的事情。什么是掌控大局?我觉得分两个部分:承上和启下,承上就是了解清楚上级的需求和工作内容;启下就是把需要做的事情分配给自己的组员,让他们清楚自己工作的内容,这个部分其实是管理的核心,后面会提到我的秘诀!什么又是非自己处理不可的事情?这绝不是自己什么都不做,所有事情一股脑塞给下属同事,而是在了解清楚工作内容以后,把那些能提升团队工作效率的事情或者实在是只有自己才能做的事做了,自身做则才能做到服人。 因为初级管理承上启下的特点,所以这种工作其实有时候特别难做。我从朋友那里学到了十个字,感觉对我的管理工作有着非常关键的指导作用:对上要有胆,对下要有心。仔细揣摩一下,其实不难发现这其实是在约束一个管理者的行为:面对上级领导的时候,不要老感觉自己是个小兵,要大胆跟对方进行沟通,因为你代表的不仅仅是你自己,还有自己的下属同事;面对下属同事的时候,不要感觉自己官大一级压死他们,其实你跟他们是与荣俱荣与损具损的共生体;这对初级管理尤其重要,因为初级管理更像是战场前线的班长,你连面对自己上级的胆量都没有,何谈面对敌人的炮火?你不把自己的班子成员当兄弟,谁会给你当炮灰? 当然,就算你做好这些了,做得非常好了,也不一定能让团队里面所有的人都服你,你一样会遭受挫折、遇到不顺利;这里首先要想到的就是:“如果这件事情简单,哪还需要老子上?” 在这种心态/格局下,再去看待问题可能会更容易接受一些;做管理,容忍度一定是要有的,因为林子大了什么样的鸟都有,在一时半会改变不了别人的情况下,只能让自己学会接受现实,伺机而动。情绪控制也是要有的,下属情商不够,也不能让自己失控,有情绪很正常,不然变成一个冷血的混蛋,没有人会跟你真诚,这样的管理就像是古代的暴政,总会被推翻的。有情绪代表你是一个有血有肉的人,但是也不要让情绪化过多干扰自己的理智,最最基础的也是要做到不要让情绪影响到工作。 这看起来很难,但是只要转换心态就可以让自己好过很多,比如你给对方分配任务,对方无理由拒绝或者态度恶劣,你可以想:“对方拒绝做或者做不好的事公司的事情,又不是自己的事情,犯不着跟对方闹情绪”。对,管理就是要这么灵活,该把公司的事当成自己的事的时候,拼死了干;该把不相干的事情甩出去的事情,就要爽快的甩出去。至少这个时候你无能为力了,这样安慰安慰自己,让自己平复情绪还是很有用的。不要怕沟通,尤其是跟刺头的沟通!那天做到了“今天就算是吵翻了天,明天还是要像一个没事人一样去跟对方相处”,基本上在这方面算是合格了。 还有一部分没有跟小崔聊的,大概涉及到项目管理的事情,还比较重要,所以提一下。分出去的任务,要定期做检查,毕竟公司有管理是为了管人,但是最终的目的是把事情做好。分出去的任务,反馈回来的至少需要有完成的时间和安排,拿到安排后按照自己的经验核算一下是否合理,如果不合理就需要跟对方再进行沟通,合理的话还要提前检查,不检查的时间相当于没有定!其实项目管理的精髓就是这个:计划、检查和沟通,其他的方法论都是技巧性的表皮罢了。 根据我这几年的工作和生活经验,说一下我的“困难观”。面对困难一般有两条路可选,第一是消极面对,相信这个事情总会能熬过去的,等熬过去了,又是春光明媚。这种一般在面对自己完全非自愿但又不得不去抗的事情时用来安慰自己,让自己不至于分裂、崩溃;另一个是积极面对,相信自己的聪明,找到问题的关键,搞定它,解决这个困难,你自己也会有所提升;这种情况我一般都把困难拆分成一个一个的难题(拆解问题的能力也很关键,因为暂时不需要,等以后再聊),像福尔摩斯一样运用自己的智慧去解开每个难题的答案,这样的面对困难重重的生活才不会觉得枯燥无味。 最后,不管使用哪种方式处理现在项目上的问题,我觉得都是对自己的一种磨砺吧,希望小崔可以顺利度过难关 :3

神奇的isatty

前些日子才从apt-get命令系列换成更为时尚的apt系列,作为一个debian系发行版——deepin的开发者,我表示很汗颜……新的apt命令除了在功能上将apt-get、apt-cache等几个命令统一到了一个命令上外,更是有了不错的TUI,如文档所说: The `apt` command is meant to be pleasant for end users and does not need to be backward compatible like apt-get(8). 毕竟,还多了进度条呢…… 😂 不过这不是今天要说的重点,换到apt以后,把apt操作的一些结果跟管道结合一起用,经常会收到警告,例如: (ssh) hualet@hualet-PC : ~ [0] % apt search deepin | grep -i superstar WARNING: apt does not have a stable CLI interface. Use with caution in scripts. CLI的输出也算是API要保持stable么?汗颜again……dtk作为一个系统级的开发库都还没有到stable的状态、某in公司的CTO写得命令行工具,第二天接口就全变了😂……敬畏之余,困惑我的倒不是这个警告的内容,毕竟新的东西都不保证稳定么,但是apt是怎么知道它的输出被连到管道了呢? 一直没空处理,直到昨天,又一次遇到了,遂记下,晚上思来想去没什么想法,遂请教前文提到的不靠谱CTO,丫直接甩过来一句: “istty检测output啊,很多命令行程序都会根据这个做不同的反应” 我:“man istty没有结果啊“ 他:”你man page没装全吧?“ 我默默敲下sudo apt install manpages-dev,显示已经安装了…… 我:“装全了啊,我Google一下吧” 他:“肯定没装全,应该是在libbsd或者termios里的吧……“ 信誓旦旦。 我默默Google了一圈,发现那个函数其实叫isatty,在unistd.h里面定义 我:“你是不是记错了,有isatty,unistd.h里面的……” Read On →

输入法消失之谜

最近不少用户在deepin论坛上报告说搜狗输入法的图标不见了,收到反馈我就心想坏了,我的输入法图标很早前就消失不见了,之前发现这个问题但是没有去跟踪是因为没有看到其他同事出现类似情况,我的电脑平常为了调试用户反馈的bug又经常XJB装软件,觉得是个例。现在收到多人反馈,大概又是什么“更新事故”? 带着沉重的心情,首先要确定的是这个问题影响的范围: 15.4.1的ISO是不存在这个问题的; 不用输入法的老外是没有受到影响的; 只有少量论坛用户报告了这个问题,大部分人表示更新到最新也没有这个问题; 还好影响范围还比较小,那么下一步就是找解决办法了: 想办法绕过?对于这个问题来说好像不太好使; debug找到问题的根本原因; (注:其实用户反馈是集中在这两周的时间甚至更短,如果是其他人的话可能会去排查最近更新了什么包,但是我刚好很早以前遇到了这个问题,受其干扰,所以走了一条冤枉路……) 下面进入本文主题,怎么去debug?以前压根儿没有调过输入法的问题啊,遂去请教公司大神,大神表示:”我也不知道啊 (无奈脸 ”~ 那么我们只能瞎猜了: 第一步:卸载掉搜狗,排除是否是搜狗输入法(问题多多,值得怀疑)导致的。 结果显示卸载掉搜狗输入法以后,小企鹅的图标可以正常显示,看来果然是搜狗输入法导致的? 第二步:下载官方搜狗搜狗输入法,重新安装,排除搜狗输入法版本的问题。 重新安装后没卵用。但是突然想起来搜狗在家目录下的.config/sogou-qimpanel/skin 里面有皮肤缓存,据Google说是皮肤有可能导致输入法图标不见的问题……我们在做2D极速版适配的时候,玩了点黑魔法,替换了一些资源文件,可能是改坏了什么东西? 第三步:删除皮肤缓存,排除修改皮肤的问题。 没卵用…… 陷入僵局,但是发现如果将sogou-qimpanel这个进程杀掉,输入法的图标就会显示出来了……那么估计是这个进程负责读取sogou的皮肤文件然后更改输入法图标,中间可能出现了什么岔子? 第四步:使用strace跟踪sogou-qimpanel,感觉胜利在望。 $ killall sogou-qimpanel && strace -e open sogou-qimpanel 打印着打印着,吭哧,sogou-qimpanel尼玛居然退出了……什么鬼,再次尝试,还是退出了。看来是daemonize了?那么strace attach到子进程呢?貌似关键的信息已经丢了……陷入僵局…… 如何在系统级别追踪呢??? 第五步: 看来要祭出大杀器systemtap了,随手写(抄)了一个stp: probe syscall.open.return { printf("%s %s", filename, execname()) } 运行失败…… WARNING: never-assigned local variable 'filename' (similar: name, __nr, retstr): identifier 'filename' at sogou_qimpanel_open.stp:2:20 source: printf("%s, %s", filename, execname()) 请教公司另外一大神,大神表示“你装一下kernel的debug包就行了……” 结果,还是不行……坑…… Read On →

2016年终总结

自从开始上班,每年年终总结都少不了,因为都是给老板看的,内容无非是今年我做了什么事情、多牛逼、对公司贡献多大云云,万一老板看到一件他不记得但是你写下来的工作贡献一高兴,说不定给你升职加薪,一年也就不算白干了。但是,写给自己的年终总结哪能这么应付,梳理整理自己一年的得失,做好权衡,最重要的是吸取经验做来年的规划。 2016关键词:累、读书和成长 2016年是挺累的一年,不知道是不是整个前半年和2015年的后半年都在加班的缘故还是什么,即便是后半年没怎么加班的时候,也没感觉怎么轻松。其间必然有些成绩,但也带来了很多严重的问题,例如我长期状态不佳、思维不清楚等,总是感觉有点得不偿失。最后的两个来月,我都在认真思考这些现象产生的原因,总结下来问题可能出在两个地方: 一、工作方式不佳,最主要的问题是贪多和多任务并行; 从年初接下来整个社区版的发布和维护工作以后,整个人进入了一种所有事情都想帮着处理的状态,写代码、管理、调试问题、支持售前、支持工程、社区反馈等等,一天到晚地干,似乎没有什么尽头;以至后面养成了多任务并行的坏习惯,做什么事情都集中不了精神,长此以往,不要说提高工作效率了,整个人都快废了。 二、生活方式不佳,最主要的问题是不够自律; 深度一天的工作时间如果不算加班其实到不了8小时,但是这个不到8个小时中我几乎有7.5个小时都在写代码(大部分工作日,有些需要讨论产品需求、开会等略去),中间几乎没有任何break,这几乎回到了14年中的工作生活状态——我几乎丧失了良好的口头交流的能力;这样的一天下来,晚上能干嘛呢?吃饭、游戏和睡觉呗……但是,问题是有些时候还要加班,加班完了回到住的地方连玩儿会儿电脑都不能就睡觉也太“亏”了吧?于是控制不住自己的玩儿过了睡觉时间,长期睡眠不够,这也直接导致了我思维变得特别慢。 确定了问题根源,肯定要治病根儿啊,针对工作方式的问题,我开始强制自己使用番茄钟,并尽量将自己的任务分摊开来;针对生活方式的问题,除了尝试早睡早起外,我也开始尝试跟别人闲聊(主要在微信上),让自己的大脑变得活跃;顺便逼迫自己抽出时间来读书,读书这件事情既能涨知识,还能磨练耐性、让自己的注意力集中起来。 说起读书,16年后半年读的一本非常火的书《软技能——代码之外的生存技能》,它之所以火,我想主要是因为它似乎给程序员打开了一扇门,这些平常只会钻研技术、敲代码的人突然发现,卧槽原来这不是生活啊!一直觉得程序员们是一群很神奇的物种,他们自认为是世界的主宰,但是真相是他们简直是生活不能自理……同时,这群脑子很聪明的人,比其他人更容易接受改变和思想上的冲击。至少这本书让我开始反思自己对待生活的态度、对待薪资的态度、对待投资理财以及社交的态度;书与其说始给程序员写的,到不如说始给所有人写的人生规划课程:学习新技能、找到新工作、营销自己、自由职业、理财和投资等等,我觉得工作的人都应该看一下。 另一本值得一提的书《梁启超教子家书》,这本书我觉得我要么评0分,要么评100分,它好是好在书里面梁启超的家书原文,至于作者整理的一些结论,个人觉得没什么可以吸收的东西。从那么多的家书中,除了可以窥探一番我比较神往的民国生活,从中理解出来的梁启超让我对这个历史人物有了翻天覆地般的认知改变。梁的爱子、博学、社交和投资,这跟前面的《软技能——代码之外的生存技能》这本书似乎遥相呼应,就是在告诉我,你需要改变了! 当作故事读的书例如《红顶商人胡雪岩》和《老残游记》等,其实给我的启发也是蛮大的,胡雪岩的冷静、睿智和大方,老残的淡泊、生活观和使命感(包括作者刘鹗的经历),都让我在生活中处理一些事情的时候有了些个参考;带着功力目的去读的《旅行与读书》、《逻辑思维——成大事者不纠结》等,也能按照预期给我涨涨见识;不期而遇的《解忧杂货铺》,读起来酣畅淋漓,故事也够精彩;2016年(后半年),在微信读书上花费时间116个小时,完整读完的有8本书,还有些零散着读一些丢一些的,这一年也算是个好的收场了。 说起成长,首当其冲的就是经历了一次分手和复合,其中酸甜苦辣,旁人绝不能理解,对我也是一次比较大的考验,让我对待生活、对待另一半有了跟之前完全不一样的转变,我很庆幸这些事的发生在25岁,而不是更晚;2016年我也开始感受到了生活的压力、结婚买房的压力,这些压力促使我去做一些改变,去践行我在书中、在生活中学到的一些生活方式,去担负起责任;这一年通过工作,我更加了解自己的成熟范围和做事风格,我愈加能够掌握做事的分寸。 2016,这是非常精彩的一年。 2017目标关键词:高效、读书、旅行 高效分两个,一个是专注于一两件关键的事情,做好;一个是调整自己的工作状态;读书不消说,这是个会上瘾的东西,好书推荐好书,好书推荐好人,好人又推荐好书,无穷尽也;旅行业分两块儿说,一是出去走走,二是组织一些线下聚会;做到这些2017年也将是非常精彩的一年! 另外,2017年准备把份子钱都收回来,哈哈哈!