作者归档:songtianlun

《赵玉平说职场智慧》

阅读感悟

职场道路必经之路,通透一些人间的事情。

阅读摘录

《赵玉平说职场智慧》

赵玉平 137个笔记

第一章 好领导要送公明——宋江的团队领导策略

◆ 宋江这个没形象、没背景、没水平的人,凭什么领导了英雄团队?宋江的团队领导策略其实就在他的名字中,宋公明——送、公、明。

送——及时雨不是白叫的

◆ 宋江,绝对是一个会送的领导。你要钱我给你钱,你要机会我给你机会,你要感情我给你感情……而且送得很贴心,比如对李逵,李逵有母亲没父亲,是个缺少父爱的人。所以,宋江对李逵张嘴就骂,举手就打,转过身掏出钱来,你要多少钱我都给你。再如对武松,武松不光没有父爱,也缺少母爱。宋江对武松的管理,就要柔和得多,融合了很多母爱的因素

◆ 送得多、送得贴心,就稳定了团队,凝聚了人心,所以领导会送是很重要的。而且,给钱给物不能瞎给、乱给,升米恩,斗米仇,你必须要给得有策略、有道理

◆ 宋江有儒家思想。你看《水浒》里边有儒、道、佛各家的代表人物,像鲁智深是佛家,公孙胜是道家,宋江则是儒家

◆ 儒家有一个说法:要是遇到可怜人,能帮人家就帮人家;要帮不了人家,就快步从人家眼前通过,不要在人家面前嘚瑟、招摇

◆ 武松的性格就是心高气傲,瞧不起别人,平时闹别扭,喝点酒就和别人起冲突。武松眼前的处境和他自己的行为有着直接关系

◆ 在现代团队管理中,我们认为,一个团队成员应该有两种行为:第一种,关系行为,就是处理人和人之间的关系,搭建人脉平台,构造满意度和和谐氛围;第二种,任务行为,就是完成工作指标。很多没经验的人可能就把精力都用到关系行为上面,或者都用到任务行为上面。精力用到一个方面是不对的,必须两条腿走路,平衡前进

◆ 武松就是片面的人,他觉得,只要我有本事,只要我把工作完成了,只要我能力上去了,我怕什么?我才不理你们呢。所以武松跟其他人的关系处得非常不好。再加上武松脾气大,比较骄傲,喝点酒,张嘴就骂,抡拳就打。整个公司除了董事长柴大官人之外,剩下的副总以下他都打过,报销个差旅费也能把财务科打一遍。所以说,武松就属于能力很强、人际关系特差的人

◆ 人际关系差,就产生了巨大问题,下面的人总到柴大官人那儿汇报说,武松这个人有问题。有本事还得有名声,名声没了,本事就被埋没了

◆ 在团队当中,特别是有本事的人,要很融洽地处理好与周围人的关系。企业的“企”字怎么写?上面一个“人”,下面一个“止”,这叫无人则止。把人脉关系搞垮了,事业就要停顿了。

◆ 武松就是这样有本事但是不会处理关系的人,结果呢?汇报的人多了,柴大官人就对武松有意见了。这一下,职位不给了,工资不发了,奖金扣除了,连医药费都不报了,所以武松发烧只能烤火,饿着肚子。这一方面体现了,武松这个人,没处理好关系行为;另一方面,也体现了柴大官人这个领导,对下面有本事的人关心不够啊。

◆ 宋江的做法值得称道,这叫“把名给在明处,把利给在暗处,当众给面子,背后给红包”。为什么给好处、给实惠的时候要悄悄地?因为宋江很深刻地理解一个道理:看重名的人想要过好日子,他的排场、他的花费,要比一般人大。但是和这些人能直接谈钱吗?不能,一提钱,脸面就没了。所以这些人的苦恼在于既离不开钱,又不能谈钱。宋江高明啊,把形象和面子给在明处,把实惠和利益给在暗处。当众发一张大奖状,给朵大红花,大家热烈鼓掌,宣扬他的事迹,给一个好待遇,安排一个好职务;散了会之后,私下里没人的地方,悄悄给一个大口袋,口袋里装的全是金子。给完之后,转身就走了。这是宋江的贴心之处。很多领导舍得给,但是不会贴着心给。而宋江的做法让武松心里特感动

◆ 在心理学层面有一句话叫,日常交往拉近距离,关键事件深化感情

◆ 现代心理学有个分支,叫人际关系心理学,其中有一个特别棒的理论:要跟一个人拉拢感情,拉近心理距离,最有效、最简单的方法是什么呢?就是请对方吃饭。吃饭能交流感情,吃饭能造就亲密的氛围。我们一般都跟家里人吃饭,所以一起吃饭,能造就认同感,形成家里人的感觉

◆ 什么叫感情?所谓有感情,就是有回忆呀。感情可以消失,只要你忍住不去回忆,感情就会消失;感情可以创造,只要你跟一个人一起,做很多值得回忆的事情,终究有一天,他会对你产生感情。所以你要对一个人积累感情,就一定得跟他做很多值得回忆的美好的事情。你要激发一个人的感情,怎么办呢?就跟他一起回忆美好的过去,回忆得越多,这人对你的感情就越深

◆ 在这个高明的策略中,有四点可以借鉴:第一,根据对方的需求,打造差异化的激励方案;第二,日常工作拉近距离,关键事件升华感情;第三,先制造回忆,后产生感情,有了感情以后再做大事;第四,精神的内容要有物质的载体

公——大公无私才能成就大公司

◆ 什么叫公?公的第一层含义就是在做公事的时候,能够把情绪放在一边,不管有多么不良的情绪,一旦面对工作,都能把情绪调整过来,能用工作态度、工作眼光对待人和事

◆ 人至少要有三个频道:有一个工作频道,正襟危坐、慷慨激昂;有一个娱乐频道,开开心心、又蹦又跳、活力四射;还有一个体育频道,认真锻炼、生龙活虎。不同的频道得用不同的情绪,人家宋江就是有不同频道的人。

◆ 很多团队领导没这个频道,家里的烦恼带到公司去,公司的烦恼带到家里来。公司里有事朝家里发火,家里有事朝公司发火。一天到晚,主要的工作状态就俩字——“串台”。这是不对的。领导的工作千头万绪,接触那么多的人,得学会转频道。一个人有若干个格子,这件事装在这个格子里,那件事装在那个格子里,绝不干扰别的格子

◆ 在宋江的团队当中,基本上都是黑社会分子,很多人都像张横一样,曾经威胁过他的性命,而且差一点就要了他的命。比如“矮脚虎”王英,那王英当初在清风山上,就差一点要了宋江的命,宋江却积极给他找媳妇。这些事情宋江居然都可以放下,把私人恩怨搁在一边

◆ 刘邦平定天下以后,下属都急着要待遇,不给就要谋反。但刘邦又没时间各个都给。事实上,很多领导面临这一情况,金山银山在这儿搁着,时间紧、任务重,大家都闹着要,你又不可能都给。当领导不能“天女散花”,得作考核算指标,这需要时间啊。但员工急,等不起。如何让又哭又闹的孩子等着排队,不抢眼前的饭,这是团队领导的高明之处

◆ 这个策略叫给待遇由远及近。你还就得先给那些跟你有过节的、闹过对立的、跟你拍过桌子瞪过眼睛的、平时不服气的人。你给这样的人一个公公正正的待遇,可以让整个团队稳定,这叫稳定的力量、凝聚的力量。刘邦跟张良的交往当中,张良有定汉四策。这四策当中,封雍齿排在第一位。古书上讲这叫“封一人而安天下”。

◆ 所以,“公”的含义也就是:给感情立个频道,学会用公心对待私人恩怨。给待遇设个顺序,能够由远及近,先给不顺眼的人公正待遇。你能做到这些,那就是“公”了。

明——看到大节,也看到小处

◆ “大树将军”因此成为典故,形容有才华、有水平、有贡献,但是不爱过度炫耀的人

◆ “老黄牛”要是挨饿了,就没人愿意再当“老黄牛”了;英雄要是死了,就没人愿意再当英雄了。所以,要让“老黄牛”披红戴花、有草有料,要让英雄不死,只有这样,才能有更多的人去做基础工作。

◆ 这就是为什么伯乐不常有:当伯乐不快乐,当伯乐没待遇。当完伯乐之后,千里马闪光了,我自己连饭都没得吃了,那我当伯乐干什么?

◆ 这叫不要让发现和培养人才的人被冷落。于是,齐国人就发现了,虽然我们自己没本事,但没关系,我们发现培养一个人才照样可以过好日子。于是,齐国伯乐辈出;于是,千里马辈出。

◆ 在团队管理中,建议大家:第一,别让默默无闻在一线的人受冷落;第二,别让发现和培养人才的人受冷落。做到这两点了,你的团队才能够有足够的后劲。

◆ 我们说,没有人干不成事,但人一扎堆,没干事,先出事,所以不能让人闲下来

◆ 人没事做,感觉被冷落,就要闹事;感觉有闲心,就要捣乱

◆ 老员工没事做,身体会垮掉;年轻人没事做,不长本事

◆ 人就像一辆自行车,天天骑没事,要是扔在楼下两个月,准垮

◆ 现代团队管理管这叫“人人有事做,处处忙起来”。没什么事做怎么办?先找点正事,学习培训、技能提升都行

◆ 企业可以有闲事,但不能有闲人,你得让大家都忙起来

◆ 这个策略叫“不断搅动锅里的水,让所有员工总在运动当中”。中国古人讲“流水不腐,户枢不蠹”。运动是进步的基础,停顿了就麻烦了

◆ 生命在于运动,管理在于折腾

第二章 给你一个干的理由——宋江的精神激励策略

◆ 干工作,没有物质是不行的,只有物质是不够的

◆ 带领团队谨记“要做一个会树大旗的领导”。

◆ 人为什么会工作?工作的驱动力在哪儿?结论很简单,人做工作、干事业,驱动力有两个:利益驱动和价值承诺。

屁股决定脑袋的理论根源

◆ 《聊斋志异》里的书生代表中国男人,特别是知识分子,在恋爱过程中的六大劣根——分别是“胆小、怕事、吃软饭、花心、好色、不负责”。

◆ 问:为什么狐狸精那么喜欢书生?答:因为写书的人是个书生

◆ 要是杀猪的写《聊斋志异》,狐狸精一定喜欢杀猪的;打铁的写《聊斋志异》,狐狸精一定喜欢打铁的;你要写《聊斋志异》,那狐狸精肯定喜欢你这个类型的;我要写《聊斋志异》,狐狸精肯定喜欢上了《百家讲坛》、身高1.8米以上,尤其是正在研究《水浒》的博士。这叫利益点决定观点,通俗化地讲,就是屁股决定脑袋。这人哪,屁股坐在哪个利益点上,脑袋中就会自然有哪种想法。这是不受主观意志控制的。

◆ 所以看人先看利益点,看完利益点,他即使不说话,也能知道他是怎么想的

◆ 要改变一个人,先改变他的利益点,只要利益点变了,观点自然就会变

◆ 要了解人,先要了解他的利益点,观点是会撒谎的,但利益点不会,一看就准

◆ 利益是一个人在团队中,做工作、表达观点主张时最主要的驱动力

◆ 我们带小团队要看个人利益,带大团队要看分利集团

◆ 《水浒》的基本团队模式就是共享财富,即“大秤分金,小秤分银;大碗喝酒,小碗吃肉”

◆ 所以一个公司在制定战略的过程中,一定要加上这一条:“关注一线。”假如不包含这一条,你的战略就是一纸空文

◆ 为什么有本事、够忠诚、有能力的人不出业绩?我认为主要原因是他对公司没有认同感

◆ 人的积极性从哪儿来?第一,在工作中有个人利益、有实惠;第二,让他觉得有价值、能认同

愿景规划——另类的激励

◆ 当团队领导的,得让他们看到砖和烂泥背后壮丽的大厦。

◆ 你有资源。还要拿到开采证或者正好有一个团队,他们要开采。这就是资源加机遇,保证你赚第一桶金。从第二桶金到第五桶金靠坚固的社会平台、稳定的人脉关系。从第五桶金到第十桶金靠有效的内部管理

◆ 题。第十桶金以后靠文化建设

◆ 普通员工有实惠了,那么他就因自己已经拿得很多了,出于良心、出于回报、出于情感,会帮忙盯着。高层的人因为有理想了,他会出于责任、价值观、个人主动性而帮你盯着

◆ 管理中有一句话,“一个人的问题是个人问题,几个人的问题是领导问题,一群人的问题是制度问题”。

◆ 实在的领导做小事,高明的领导做大事

◆ 光实在不行,把实在的问题展示了,把眼前实惠讲完了,只能调动低层次的人,不是思想水平低,而是生活层次低的人

◆ 高明的领导,在实在的基础上,还得设计一个远大的理想

◆ 工作如同建设一栋大厦,一到十楼叫实惠,十楼以上那叫境界。如果没有实惠,上来就讲境界,讲理想,那是空中楼阁。但是一直在讲一到十楼的事,没有更高的境界,只能是低矮的楼房

第三章 找对人才能做对事——领导必备的小班底

◆ 和,即条件相容,和平共处。同,即结论一致,观点一致

◆ 高水平的人,追求条件相容,和平共处,不强求观点一致,结论一致;低水平的人不考虑条件、对象和场景,非得强求结论一致,观点一致,结果会引发更多的矛盾冲突

◆ 宋江在给英雄排位的时候,实际上搭了两个班子:一个小班子,一个大班子

做不好人事就做不了大事

◆ 一个领导在带队伍、做工作、做事业的时候,一定既要有大班子,又要有小班子。大班子管工作,小班子管生活;大班子管战略,小班子管事务

◆ 所以,不谋心、不利私、不越权,这样的人去给我们当替身是最合适的

◆ 领导用贴身助手,就得用背景简单、资历比较浅的年轻人

◆ 所以领导用助手,要用资历浅、背景简单的年轻人,又安全又好用,过两年就提拔他,提拔起来之后再用一个,这是正确的方法

◆ 二把手给一把手管事务,一把手安排自己的人给二把手管事务,再找个年轻、没背景的人给自己管事务,这就是梁山在班子搭建上的智慧,这智慧很值得玩味呀。

◆ 宋江在选择替心、替口、替身、替手、替脸这五种角色上,颇费心思,但收获颇丰。其中,替心、替口这两种人最重要,也最难找。

摇扇子的做领导不会做的事

◆ 聪明的人只是聪明,高明的人会使用自己的聪明

◆ 聪明人会做傻事,这叫智慧。努力的人会慢半拍,这叫高明。聪明容易,高明难

◆ 在现代团队管理中,做事业就像开车,你会踩油门,那是力量,你会踩刹车,那叫智慧

◆ 孔子的学生里,道德风范最高的是颜回,最有勇气的是子路,最聪明的要属子贡。

◆ 垂头丧气的人和得意扬扬的人,都有问题。中医讲,草木得天地之偏气而茂盛,人得天地之和气而茂盛。得正气人才能不卑不亢,喜气洋洋,一团和气,而且,才能守得住富贵

◆ 主张一种东西,但是,完全不按这种主张去做,这种人就不是什么好人,而且早晚得给自己惹祸

◆ 在团队管理中,有些事情我们做不到,可以不主张,但主张了就一定得做到,怕就怕自己主张自己做不到,还让别人去做,这种人在领导岗位上早晚得出问题。

◆ 这就叫“主张一套,自己做的是另一套”,这样的领导都会出事

◆ 一般来说,聪明人最大的优点是聪明,最大的缺点是太聪明

◆ 聪明人有三道难关:第一道叫认同关;第二道叫感情关;第三道叫安全关。这三道关都过了,你才能活下来。笨人只需要过感情关,跟人家成为好朋友就可以了,聪明人却要过三关。所以看看我们周围,笨人活下来的可能性大,聪明人活下来的可能性小

◆ 真正聪明的人,真正有水平的人,面临一个共同问题就是,做事情在哪个节骨眼上入手,最能得到认可

◆ 我们生活在一个认可的年代,不让员工认可你得“死”,不让领导认可你得“死”,不让客户认可你得“死”。所以获得认可非常重要

◆ 从古到今的所有厉害的人,都要过认可关,再有本事,没人认可也是白搭,会委屈死的。

◆ 。《论语》中也说过:“不愤不启,不悱不发。”即你不着急我不给你提意见,我提了意见,你不认可,你的评价就比较低。我非得等你着急了,才给你提意见,而且我的意见特别到位,一句话就把你的火给扑灭了,那你就认可我了。

◆ 这叫你不疼,我不给你下药;你不苦,我不给你下糖;你不发烧,我不给你退烧,你没烧,我给你吃两片退烧药,你还说我害你呢。所以,吴用就等着关键时刻

◆ 关于掌握工作节奏,给大家引述另外一个反面例子,他俩一对照,你就知道工作节奏的重要性。这个反面例子也是四大名著里的名人,就是《西游记》里的孙悟空

◆ 关于工作节奏,总结两句话:第一句,积极但不能着急。

◆ 第二句,被动而不主动。

◆ 你再有本事,你也是个下属,中国古人有一句话叫“干活不由东,累死也无功”。

◆ 聪明人的第二道难关是感情关

◆ 举个例子,我们雇了一个财务经理,如果是自己人,水平越高,我们越放心;如果是个外人,水平越高,我们越不放心。这叫感情引路,聪明跟进

◆ 聪明人的第三道难关是安全关。

◆ 聪明的人不跟公司的上级领导们谈领导艺术,你谈完了,他们就该担心你的谋略那么多,万一跟他们玩心眼,怎么办?

◆ 其实吴用是在偷偷地帮宋江,但是吴用不把这事说明了,他从来没有让宋江感觉过他知道宋江愿意当一把手,这就叫装傻

◆ 聪明人能做傻事,聪明人能躲在暗处,聪明人做事能慢半拍,这叫智慧。

抡板斧的做领导不能做的事

◆ 一个领导,身边最好有两个人,一个是出主意的,我们叫摇扇子的人;另一个是帮你出头,拍桌子,瞪眼睛的,叫抡板斧的人

◆ 作为一把手争得太急、说得太绝,又会伤害自己的面子和尊严。这时你身边就得准备一个李逵这样的人,让他站出来替你说,帮你争

◆ 这种人应该有三个特点:第一,是鲁,敢发脾气,拍桌子,能使用差异化的手段震慑对手。第二,是忠,一心干事业,一心对领导,怎么骂,怎么打,都不留阴影,他能理解领导。第三,是直,竹筒倒豆子,装什么子弹开什么枪,让怎么说就怎么说。

◆ 吴用好找,李逵不好找,管理学就是这样,团队当中每个岗位都有合适的人,每个岗位都有合适的事。你看这人鲁莽,用好了就是优点。没有不合适的人,只有不匹配的工作,人在匹配的岗位上工作就会很合适。

晁盖的第一桶“人”

◆ 所以建团队,第一条,也是最根本的一条,叫作彼此的信任

◆ 信任成本是团队的最大成本,很多事情本来可以低成本、高效率地完成。为什么完不成?没有信任

◆ 我们现在往往用契约和法律手段来建立信任,但是契约和法律有漏洞,必须还有更深入的东西来弥补信任

◆ 古人有一句话叫“树怕扒皮,人怕见面”。见重要的人谈大事,怎么能发条微信,聊个QQ呢?那叫儿戏。你得亲自去,在正式场合寒暄几句,然后整整衣服,坐下再说

◆ 当天想到的事情得当天去做。在现代管理学中,这叫日落法则,即今天想到的事情,在太阳落山之前得开始行动

◆ 这叫认同公司、认同事业、认同领导、认同任务,只有这四个认同都做到了,此人才能参与我们的工作。

◆ 所以,要上梁山:第一,你喜欢梁山这个公司吗?第二,你喜欢落草当黑社会这份事业吗?第三,你喜欢梁山首领宋江吗?第四,宋头领让你下山抢劫,你去吗?只有这四条都点头了,你才算是我们的人。

◆ 吴用就要考核三阮这四个问题,但是,谈的是风险任务,又不能直接考核,所以,吴用使用了旁敲侧击法。这种方法,我们在选重大人事岗位时可以用,在非正式场合使用闲聊的手段旁敲侧击,问问他这四条行不行

宋江的用人“妙招”

◆ 在重大的商务谈判之前,千万不要接受人家的礼物、吃人家的饭,否则你心里就解除武装了,就已经投降了。等你再说话的时候,你的谈判能力、你的原则立场,都会不自觉地发生变化

◆ 对有才华、有水平的年轻人才,可以给权力,给重担,但是级别一定要逐级提升。

亲贤治小,胜过“高人”的管理之道

◆ 多样化团队中,既要有君子,也要有小人;既要有神,也要有鬼。你看庙里,菩萨、佛祖慈悲为怀,普度众生,慈眉善目。但是庙门口的护法面目非常凶。

◆ 第三步,换副笑脸劝住他。最后还得用温暖的手段解决,不能激化矛盾,不能真动手打,但你要不镇他、不吓他,他不服气。你要是上来就赔个笑脸,他觉得你软弱可欺,就可能抡圆了给你一嘴巴。不能做软弱可欺的人,实力还是很重要的

◆ 这叫君子做不了小人的事,高人做不了低事。管得住一个国、一个省,不见得能管得住一个村。小人的事由谁来做?由车老板来做,正合适

◆ 当领导的得记住,你虽有很多文明手段,但不能没有野蛮手段。当你遇到野蛮人,用文明手段解决不了,得靠别的手段。你碰见狗,狗冲你叫,你不能冲狗叫。你的员工抬手给你一个嘴巴,你还不能还手,挨打不还手,丢人,还手更丢人。这时候怎么办?很简单,我们身边养条藏獒,就能管住天下的狗。怕挨打,我们身边带一个大汉,谁打你他挡着。宋江为什么走到哪儿,都带着李逵?在黑社会下基层,身边要带一更黑的,这叫震慑力。

◆ 所以,小人不好管,你得管着;小人不顺眼,你得忍住;小人不爱干,你得把他激励起来

◆ 做大事,能用君子叫人品,会用小人叫水平。我们要做既有人品,又有水平的领导,才能把天下大事摆平

◆ 小人虽然有他的用处,但对小人必须小心。让小人办事,小人就可能会提许多无理的要求。你若是满足,他会贪得无厌;你若是不满足,就会招小人忌恨。怎么办?该满足的就满足,不该满足的就委婉拒绝。拒绝的技巧是特别重要的

◆ 在团队冲突当中,大量的冲突原因都是人家向你提要求,你拒绝,而且拒绝得太直接、太生硬。

◆ 其一,龙颜无恩。真正做大事的领导只记你的坏处,不记你的好处,不管有多大的贡献,只要你敢违反纪律,都会动狠手杀你。不要以为人家会念旧情,要看眼前,看表现。其二,小人可怕。宁得罪君子,不得罪小人。君子相斗狠在当前,小人相斗狠在背后。小人要是恨上你,他眼前笑呵呵的,但是,过二三十年,再给你下狠招儿,这叫不怕贼偷,就怕贼惦记。其三,领导身边的人不能得罪。一个看大门的,你把他得罪了,说不定啥时候,他告你一状,你的人生和事业就崩溃了。所以,领导身边的人要敬而远之。不能给他好处,也别跟他有冲突,离远点比较好

◆ 夷射,不是死在龙颜无恩上,不是死在小人可怕上,也不是死在领导身边的人不好应付上,而是死在他自己没有拒绝的技巧上

◆ 他只会用简单粗暴的方法拒绝别人,那一定会出事的。人家跟你要酒,你不愿意给,有很多方法拒绝

◆ 第一,可以无限期拖延。“这个酒现在不能给你,人多眼杂,等将来有机会我一定给你”,什么时候有机会,不知道。第二,找个东西替代。“这个酒不能给你,没关系,赵老师那儿有酒,他又不喝酒,你去朝他要。”第三,设个条件来转移。“我现在不能给你,明天早上你过来,我再给你。”第二天早上跟秘书说:“那人来朝我要酒,就说我不在啊。

◆ 现在的人际沟通理论,给了我们拒绝的六个字口诀,适用于各种人际冲突。这六个字是:承认,苦衷,出路

◆ 承认,就是我不能给你东西,但我要承认你的要求是正当的,承认咱俩的关系是亲密的,承认你是有贡献、需要关照的。承认之后讲苦衷,说我愿意给你,但是,我不能给你,原因是……最重要的是出路,拒绝别人,不给别人指明出路,你的拒绝只能打一半分,必须指明出路

◆ 现代行为学给了我们一个基本框架,当我们跟一个人发生冲突的时候,应当使用以下几个手段:竞争,又叫直接拒绝,毫不犹豫,斩钉截铁,只关注自己,不关注他人。妥协,又叫答应,没有任何条件,无条件答应,只关注对方,不关注自己。回避,“这事现在说不清,咱别说了,过些日子再说”

取长补短,善待有缺点的人

◆ 一个团队要解散时,男人眼泪汪汪,女生稀里哗啦,都掉眼泪。但是原因不一样,这叫动情机制。女孩子动感情掉眼泪,一定是舍不得一个氛围、一个团队。所以团队解散时,女孩子掉眼泪,我们人人都感动,她的眼泪中有我们的一份。男人稀里哗啦掉眼泪,绝对是因为舍不得一个人,你甭感动,那人不是你。

◆ 我们常说,似水柔情。让一个男人脑子进水的感情,就叫似水柔情;而让一个男人脑子进开水的感情,就叫火热的似水柔情

◆ 真实的世界是有很多缺点、毛病和遗憾的。但因为真实,才稳定,要不真实,就反常

◆ 现代管理学有个基本结论:稳定的人际关系,是基于缺点展示和缺点认同的

◆ 不能光看优点,缺点是稳定的基础,优点是发展的基础。先有稳定才能发展,没地基哪行?

越是亲信越不能亲近

◆ 我们一定得记住,在团队管理中,就算有过命的交情,就算是掏心窝子的兄弟,你在他面前该讲理想就讲理想,该正襟危坐就正襟危坐,该谈人生就谈人生

◆ 管好自己身边亲信的人,有一个管理原则,叫近严远宽,先严后宽

错位的王伦:庸人能否当领导

◆ 领导就要像宋江那样,像刘邦那样,通过良好的待遇政策和激励政策,通过给理想、给实惠,调动比你强的专家、人才给你干工作。

◆ 从王伦这个小聪明,我们看到了狭隘领导的第二个错误——人为制造内耗,刻意增加自己的权力

◆ 现代团队管理认为权力有两类:一类叫职位权力,是上级给你的奖罚资源;另一类叫个人权力

◆ 个人权力,第一,看本事;第二,看人品、看风格。

◆ 关于获得人心,《孙子兵法》上有一种说法,当领导要做到四个字,“上下同欲”。什么叫上下同欲?上是上级,下是下属,同是相同,欲是个人的动机

不到位的晁盖:鸠占鹊巢的悲哀

◆ 晁盖犯了三大基本错误:第一,让二把手管重大人事安排;第二,让二把手主外,一把手主内;第三,在做事情上,跟二把手争一时之短长。

梁山公司的人与事

◆ 有本事的人发脾气,那叫个性;没本事敢发脾气,那叫找死。

— 来自微信读书

Rails 7 已有项目引入 Bootstrap 3

若是新项目,在 Rails 7 之后直接使用 rails new test -j esbuild --css bootstrap 即可,若是已有项目,使用下面步骤引入:

主要步骤

安装 cssbundling-rails 管理 CSS

bundle add cssbundling-rails
./bin/rails css:install:bootstrap

做了以下几件事情:

  • 它会创建 builds 文件夹,并在清单文件中链接它
  • 它会删除 application.css 文件,因为它会生成自己的文件。
  • 它添加了一个 package.json 文件来存储 Javascript 依赖项。
  • 它会安装 foreman gem,并为其生成一个配置文件。
  • 它添加了一个 bin/dev 脚本来启动 rails 服务器,并监视 CSS 文件的任何更改。
  • 它会创建特定于 Bootstrap 的 scss 文件,该文件将被捆绑到一个 application.css 文件中。
  • 它将安装 package.json 文件中列出的所有 Javascript 依赖项。
  • 它将 Bootstrap 字体路径附加到 assets 路径。
  • 它将 Bootstrap Javascript 导入添加到 application.js 文件中。
  • 最后,它配置 build:css 命令并运行它来构建 application.css 文件。

安装 jsbundling-rails 处理 JS 绑定

bundle add jsbundling-rails
./bin/rails javascript:install:esbuild

上述脚本做了这些事情:

  • 它会检查 builds 文件夹,但因为我们已经有了它,所以它不会做任何事情。
  • 它将 javascript_include_tag 添加到应用程序布局文件中。
  • 它在 foreman 配置文件中添加一个任务,以监视任何 Javascript 更改。
  • 它安装 esbuild 打包器,并尝试构建 Javascript 代码。

疑难问题

$ esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets
✘ [ERROR] Could not resolve "controllers"

    app/javascript/application.js:3:7:
      3 │ import "controllers"
        │        ~~~~~~~~~~~~~
        ╵        "./controllers"

  Use the relative path "./controllers" to reference the file "app/javascript/controllers/index.js".
  Without the leading "./", the path "controllers" is being interpreted as a package path instead.

1 error
node:child_process:866
    throw err;
    ^

Error: Command failed: /Users/cezar/Work/ror/bootstrap/node_modules/esbuild-darwin-arm64/bin/esbuild app/javascript/application.js --bundle --sourcemap --outdir=app/assets/builds --public-path=assets
    at checkExecSyncError (node:child_process:828:11)
    at Object.execFileSync (node:child_process:863:15)
    at Object.
<anonymous> (/Users/cezar/Work/ror/bootstrap/node_modules/esbuild/bin/esbuild:209:28)
    at Module._compile (node:internal/modules/cjs/loader:1099:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47 {
  status: 1,
  signal: null,
  output: [ null, null, null ],
  pid: 94418,
  stdout: null,
  stderr: null
}

Node.js v17.8.0
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

因为我们有一些 import maps 留下的代码,这与 jsbundling-rails gem 的工作方式相冲突。

因此,让我们解决这些问题。

修复安装

首先要做的是安装 turbo-rails 和 stimulus 包。

yarn add @hotwired/turbo-rails
yarn add @hotwired/stimulus

然后,我将调整 application.js 文件中的导入路径,并删除旧的刺激导入。

--- a/app/javascript/application.js
+++ b/app/javascript/application.js
-import "controllers"
+import "./controllers";

--- a/app/javascript/controllers/index.js
+++ b/app/javascript/controllers/index.js
-import { application } from "controllers/application"
-
-// Eager load all controllers defined in the import map under controllers/**/*_controller
-import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
-eagerLoadControllersFrom("controllers", application)
-
-// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
-// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
-// lazyLoadControllersFrom("controllers", application)
+import { application } from "./application";

在应用程序布局文件中,我将删除 javascript_importmap_tags 帮助程序,因为它不再需要。

--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
     <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
-    <%= javascript_importmap_tags %>
     <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
   </head>

最后,我将取消链接其他 javascript 文件夹,只在清单中留下 builds 文件夹和 images 文件夹。

--- a/app/assets/config/manifest.js
+++ b/app/assets/config/manifest.js
 //= link_tree ../images
-//= link_tree ../../javascript .js
-//= link_tree ../../../vendor/javascript .js
 //= link_tree ../builds

安装 Bootstrap3

以上命令默认会安装最新的 Bootstrap, 如果像我一样需要安装旧版本,则按照以下步骤:

首先安装 Bootstrap 3 和 jquery

yarn add bootstrap@3
yarn add jquery

之后创建一个 js 文件 app/javascript/add_jquery.js :

import jquery from 'jquery'
window.jQuery = jquery
window.$ = jquery

最后在 app/javascript/application.js 中引入即可:

...
import './add_jquery'  

import "jquery/dist/jquery"  
import "bootstrap/dist/js/bootstrap"
...

css 则是在 app/assets/stylesheets/application.bootstrap.scss 中写入:

+ @import 'bootstrap/dist/css/bootstrap';
@import 'bootstrap-icons/font/bootstrap-icons';

链接 debugger

以上操作后就可以使用 bin/dev 启动项目,会自动起来三个服务,这时如果使用 debugger 启动调试,就可以使用以下命令链接:

rdbg --attach

References

Ruby 多版本管理工具 rbenv

rbenv (Simple Ruby Version Management) 允许您在 Ruby 的多个版本之间轻松切换。它简单、不引人注目,并遵循 UNIX 的传统,即只做一件事的单一用途工具。

安装方法

安装 rbenv

# Archlinux
sudo pacman -S rbenv
# macOS
brew install rbenv
# Debian/Ubuntu
sudo apt install rbenv
# Fedora/RHEL
sudo dnf install rbenv

安装 ruby-build

使用 rbenv 安装 ruby 版本需要用到 install 命令,但是该 rbenv install 命令不是开箱即用的 rbenv 提供的,而是由 ruby-build 插件提供的,下面一同安装:

# Archlinux
sudo pacman -S ruby-build
# macOS
brew install ruby-build

使用方法

# 首先初始化
rbenv init

# 查看可安装版本
rbenv install -l # list latest stable versions
rbenv install -L # list all local versions

# 安装某个版本
rbenv install 3.1.2

# 使用某个版本
rbenv global 3.1.2 # set the default Ruby version for this machine
rbenv local 3.1.2  # set the Ruby version for this directory

References

使用 GCOP AI 助力提升 git commit 效率

最近在 阮老师博客 看到一款这个 GCOP,一个基于 LLM 的 Git 提交消息生成和 Git 工作流程优化工具,试用了一下确实不错。接入 LLM 即可自动分析 git 修改生成 commit 消息,比我之前做的 git-commit 生成器好用多了。

以下是一些简单介绍:

简介

GCOP (Git Copilot) 是一个 Git 智能助手,它使用 AI 来自动生成 Git 提交消息,帮助开发者优化 Git 工作流程。

主要功能

  1. 智能提交消息:自动分析代码变更,生成高质量、定制化的提交消息,并提供多种细粒度配置,确保团队提交标准的一致性
  2. 灵活的 AI 集成:支持配置各种 LLM 模型(如 OpenAI GPT、Claude、Deepseek 等)
  3. 简化的 Git 命令:内置 20+ 直观的 Git 快捷操作和命令,提供直观的命令别名,如 git c 用于 AI 辅助提交,优化 Git 工作流程
  4. 无缝工作流集成:增强现有 Git 工作流程,无需改变使用习惯

优点

🎨 高度可定制化体验

  • 提供全局配置和项目级配置,配置项目特定设置,确保团队标准的一致性
  • 设计专属提交模板以匹配项目需求
  • 通过自定义提示优化 git message 的风格

⚡ 流畅的开发者体验

  • 内置 20+ 直观的 Git 快捷操作和命令,智能别名让复杂的 Git 操作轻而易举
  • 支持各种 LLM 模型(OpenAI、Anthropic、Deepseek 等)
  • 零配置集成至现有的 Git 工作流

📚 智能学习能力

  • 自动学习您的代码库提交历史
  • 随时间适应团队的提交习惯
  • 通过持续学习提升信息质量

项目完全开源,使用 MIT 协议,基于 Python 开发。

Github: https://github.com/Undertone0809/gcop
官网: https://gcop.zeeland.top/

使用方法

安装配置参考官网 Quick Start Guide 即可,mac 下可以结合 conda 安装,之后大概按照这样配置:

model:
  model_name: openai/gpt-4o-mini
  api_key: sk-xxxx
  api_base: https://api.xxx.io/v1

即可使用。

效果

(base) songtianlun@songtianlundeMacBook-Air sample_rails_app % git ac
[Code diff] 
diff --git a/.gitignore b/.gitignore
index afd85fd..daa7023 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,5 @@
 !/app/assets/builds/.keep

 /node_modules
+
+.idea
[On Ready] Generating commit message...
[Thought] The changes involve the removal of several .idea configuration files and the 
addition of .idea to the .gitignore file. This indicates a cleanup of IDE-specific files 
that are not necessary for version control, which can help reduce clutter in the repository.
[Generated commit message]
chore: remove IDE configuration files

- Deleted .idea/misc.xml, .idea/modules.xml, and .idea/sample_rails_app.iml files
- Added .idea to .gitignore to prevent future IDE files from being tracked

This commit cleans up the repository by removing IDE-specific configuration files that are 
not needed for the project. It also ensures that any future IDE files will be ignored, 
keeping the repository clean and focused on the actual project code.
? Do you want to commit the changes with this message? yes
[main d86005c] chore: remove IDE configuration files
 6 files changed, 2 insertions(+), 373 deletions(-)
 delete mode 100644 .idea/.gitignore
 delete mode 100644 .idea/misc.xml
 delete mode 100644 .idea/modules.xml
 delete mode 100644 .idea/sample_rails_app.iml
 delete mode 100644 .idea/vcs.xml
(base) songtianlun@songtianlundeMacBook-Air sample_rails_app % git push

常用命令

$ git ghelp                
/opt/homebrew/Caskroom/miniconda/base/lib/python3.12/site-packages/pydantic/_internal/_config.py:345: UserWarning: Valid config keys have changed in V2:
* 'fields' has been removed
  warnings.warn(message, UserWarning)

gcop is your local git command copilot
Version: 1.7.3
GitHub: https://github.com/Undertone0809/gcop

Usage: gcop [OPTIONS] COMMAND

Commands:
  git p          Push the changes to the remote repository
  git pf         Push the changes to the remote repository with force
  git undo       Undo the last commit but keep the file changes
  git ghelp      Add command into git config
  git gconfig    Open the config file in the default editor
  git gcommit    Generate a git commit message based on the staged changes and commit the 
changes
  git c          The same as `git gcommit` command
  git ac         The same as `git add . && git gcommit` command
  git acp        The same as `git add . && git gcommit && git push` command
  git cp         The same as `git gcommit && git push` command
  git amend      Amend the last commit, allowing you to modify the commit message or add 
changes to the previous commit
  git info       Display basic information about the current git repository

改好代码之后 git ac && git push 两行命令搞定标准格式提交,很方便。

References

VirtualBox VERR_NO_LOW_MEMORY 解决

Archlinux 下内存有很多,但 VB 报错内存不足 VM 无法启动,free 可以看到内存大部分被 buffer 占用。

free -h
              total        used        free      shared  buff/cache   available  
内存:          30Gi        13Gi        1Gi       2.3Gi       18.7Gi        17Gi  
交换:          31Gi       1.7Gi        30Gi

论坛找到一种强制驱逐 buffer 占用的方法:

echo 3 > /proc/sys/vm/drop_caches

执行后可正常启动。

References

Linux buffer-cache 占用过高性能调整

什么是 buff/cache?

在 Linux 2.4 的内存管理中,buffer 指 Linux 内存的:Buffer cache。cache 指 Linux 内存中的:Page cache。一般呢,是这么解释两者的。

  • A buffer is someting that has yet to be ‘written’ to disk.
  • A cache is someting that has been ‘read’ from the disk and stored for later use.

翻译过来就是说:

  1. buffer (buff) 是用来缓存尚未 “写入” 磁盘的内容。
  2. cache 是用来缓存从磁盘 “读取” 出来的东西。

所以 buffer 被用来当成对 io 设备写的缓存。而 cache 被用来当作对 io 设备的读缓存。这里的 io 设备,主要指的是块设备文件和文件系统上的普通文件。

但是在 Linux 2.6 以后,它们的意义不一样了。

在 Linux 2.6 之后 Linux 将他们统一合并到了 Page cache 作为文件层的缓存。而 buffer 则被用作 block 层的缓存。
block 层的缓存是什么意思呢,你可以认为一个 buffer 是一个 physical disk block 在内存的代表,用来将内存中的 pages 映射为 disk blocks,这部分被使用的内存被叫做 buffer。

buffer 里面的 pages,指的是 Page cache 中的 pages,所以,buffer 也可以被认为 Page cache 的一部分。

或者简单来说,buffer 负责裸设备相关的缓存,cache 负责文件系统的缓存。

Buffer 的具体职责

在当前的系统实现里,buffer 主要是设计用来在系统对块设备进行读写时作为缓存来使用。这意味着对块的操作会使用 buffer 进行缓存,比如我们在格式化文件系统的时候。

但是一般情况下两个缓存系统是一起配合使用的,比如当我们对一个文件进行写操作的时候,cache 的内容会被改变,而 buffer 则用来将 cache 的 page 标记为不同的缓冲区,并记录是哪一个缓冲区被修改了。

这样,内核在后续执行脏数据的回写(writeback)时,就不用将整个 page 写回,而只需要写回修改的部分即可。

Cache 的具体职责

cache 主要用来作为文件系统上的文件数据的缓存来用,当进程对文件有 read/write 操作的时候。包括将文件映射到内存的系统调用 mmap,就会用到 cache。

因为 cache 被作为文件类型的缓存来用,所以事实上也负责了大部分的块设备文件的缓存工作。

怎么回收 buff/cache?

Linux 内核会在内存将要耗尽的时候,自动触发内存回收的工作,以便释放出内存给急需内存的进程使用。

但是这种回收的工作也并不是没有成本。

理解 cache 是干什么的就知道,cache 中存在着一部分 write 操作的数据。所以必须保证 cache 中的数据跟对应文件中的数据一致,才能对 cache 进行释放。

于是伴随着 cache 清除的行为的,一般都是系统 IO 飙高。这是因为内核要将 cache 中缓存的 write 数据进行回写。

我们可以使用下面这个文件来人工触发缓存清除的操作,Linux 提供了三种清空方式:

  1. echo 1 > /proc/sys/vm/drop_caches # 仅清除页面缓存
  2. echo 2 > /proc/sys/vm/drop_caches # 清除目录项和 inode
  3. echo 3 > /proc/sys/vm/drop_caches # 清除页面缓存、目录项以及 inode

但是这种放时只能在执行的当时起作用,过一段时间之后又会发现内存被占满,怎么办呢?

实际上内核提供了 vm.vfs_cache_pressure 参数用来控制缓冲区的回收频率,我们可以调整它。

这个参数是用来控制内核回收 VFS 缓存的频率。修改这个值会提高或者降低回收 VFS 缓存的频率。值可以设置为 0-200 中的任意值。越大回收频率越快,可以把 vm.vfs_cache_pressure 赋值为 200 来获得最快的回收频率。这个值默认值一般为 100。

另外也可以使用 slabtop 分析内存使用情况。一般情况下,dentry 和 *_inode_cache 值越高回收的效果越好。

为什么是 dentry 和 *_inode_cache 呢,这是因为当读写文件时内核会为该文件对象建立一个 dentry,并将其缓存起来,方便下一次读写时直接从内存中取出提高效率。

一些措施

内核参数

可以通过配置 vm.vfs_cache_pressure 参数,控制系统回收 directory entries 和 inode 缓存的倾向程度

Linux Kernel 文档描述如下:

此百分比值控制内核回收用于缓存 directory 和 inode 对象的内存的趋势。 在默认值 vfs_cache_pressure=100 时,内核将尝试以 pagecache 和 swapcache 回收的“公平”速率回收 dentry 和 inode。减小 vfs_cache_pressure 会导致内核更倾向于保留 dentry 和 inode 缓存。当 vfs_cache_pressure=0 时,由于内存压力,内核永远不会回收 dentry 和 inode,这很容易导致内存不足的情况。将 vfs_cache_pressure 增加到 100 以上会导致内核更喜欢回收 dentry 和 inode。 将 vfs_cache_pressure 显著增加到 100 以上可能会对性能产生负面影响。回收代码需要使用各种锁来查找可释放的目录和 inode 对象。当 vfs_cache_pressure=1000 时,它将查找比可用对象多 10 倍的可用对象。

可尝试将该值调整为 200 使得比默认值更积极地回收缓存,要持久化配置 vm.vfs_cache_pressure 为 200,你可以通过以下几种方法:

  1. 通过 /etc/sysctl.conf 文件(推荐方法):
# 使用文本编辑器打开 /etc/sysctl.conf
sudo vim /etc/sysctl.conf

# 添加或修改以下行
vm.vfs_cache_pressure = 200

# 使配置生效
sudo sysctl -p
  1. 通过创建 /etc/sysctl.d/ 目录下的配置文件:
# 创建新的配置文件
sudo vim /etc/sysctl.d/99-vfs-cache-pressure.conf

# 添加以下行
vm.vfs_cache_pressure = 200

# 使配置生效
sudo sysctl --system

手动清理

$ sync
$ echo 1 > /proc/sys/vm/drop_caches
$ echo 2 > /proc/sys/vm/drop_caches
$ echo 3 > /proc/sys/vm/drop_caches

自动定时清理

不推荐这么做

1、创建脚本cleanCache.sh

#!/bin/bash#每两小时清除一次缓存
echo "开始清除缓存"
sync;sync;sync #写入硬盘,防止数据丢失
sleep 10#延迟10秒
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches

2、创建定时任务

crontab -e #弹出配置文件

3、添加定时任务执行频率

#分  时  日  月  周  命令
0 */2 * * * /usr/local/bin/cleanCache.sh

4、设置crond启动以及开机自启

systemctl start crond.service
systemctl enable crond.service

5、查看定时任务是否被执行

cat /var/log/cron | grep cleanCache

References

GitHub 个人仓库批量备份到自建 Gitea

这是一个自动将 GitHub 仓库镜像到 Gitea 的 Shell 脚本。支持批量同步所有仓库,可以设置跳过特定仓库,并具有良好的错误处理机制。

由于 GitHub 仓库较多,因为各种原因担心数据风险和访问困难。代码托管在自建 gitea 虽然访问快,但是脱离了生态很难跟其他的 PaaS 平台对接。

于是就编写了一套脚本,这套脚本从 Github api 获取 repo 清单,逐个 mirror 后推送到 gitea,最后收集同步报告发送邮件通知。结合 crontab 可实现自动化的 git repo 同步备份。

花了一点时间来写,干脆分享出来,可以i根据自己的需求定制。

邮件效果:

邮件截图

运行效果:

运行截图

支持 helm 的 harbor 版本

Harbor在v1.6版本开始支持Helm Chart仓库功能,- 从v2.6.0 开始弃用Chartmuseum,并在v2.8.0中开始删除。更多详情,请参阅讨论:https://github.com/goharbor/harbor/discussions/15057 从 v2.6.0 开始弃用 Notary(签名者和服务器),并在 v2.8.0 中开始删除。更多详情,请参阅讨论:https://github.com/goharbor/harbor/discussions/16612

安装Chartmuseum组件

修改配置文件

  在absolute_url​参使用ChartMuseum​组件时,客户端获取到的Chart的index.yaml​中包含的URL是否为绝对路径。在不配置该项时,ChartMuseum组件会返回相对路径,默认为disabled。

$ vim  harbor.yml
chart:
  # Change the value of absolute_url to enabled can enable absolute url in chart
  absolute_url: enabled

enabled表示使用绝对路径!

停止Harbor

$ docker-compose stop

注入配置

  执行./prepare将新的配置注入到各个组件中。

$  ./prepare

安装chartmuseum

  在执行install.sh安装时,通过–with-chartmuseum参数安装chart插件,安装完后会自动启动Harbor。

$ ./install.sh  --with-notary --with-trivy --with-chartmuseum
✔ ----Harbor has been installed and started successfully.----  #输出该信息则表示安装成功

查看组件服务状态

  通过docker-compose ps命令可以看到harbor的组件中多了个chartmuseum的容器。

$ docker-compose ps

验证是否安装了chartmuseum组件

登录Harbor UI管理界面:【项目】==>【library】==> 【Helm Charts】

References

#Harbor #Docker

配置 harbor 及 docker 等使用 https

默认情况下,Harbor不提供证书。可以在没有安全性的情况下部署Harbor,这样您就可以通过HTTP连接到它。但是,只有在没有连接到外部internet的空间隙测试或开发环境中才可以使用HTTP。在没有空间隙的环境中使用HTTP会暴露给中间人攻击。在生产环境中,始终使用HTTPS。如果启用带公证人的内容信任对所有images进行正确签名,则必须使用HTTPS。

要配置HTTPS,必须创建SSL证书。您可以使用由受信任的第三方CA签名的证书,也可以使用自签名证书。本节介绍如何使用OpenSSL创建CA,以及如何使用CA签署服务器证书和客户端证书。您可以使用其他CA提供程序,例如:Let’s Encrypt。

下面的过程假设您的Harbor注册表的主机名是 yourdomain.com,并且它的DNS记录指向运行Harbor的主机。

生成证书颁发机构的证书

在生产环境中,应该从CA获取证书。在测试或开发环境中,可以生成自己的CA。若要生成CA证书,请运行以下命令。

生成CA证书私钥。

openssl genrsa -out ca.key 4096

生成CA证书。 

调整 -subj选项中的值以反映您的组织。如果使用 FQDN 连接Harbor主机,则必须将其指定为 common name(CN)属性。

公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。

例1:打算为“chinassl.net”申请SSL证 书,那这个公用名(Common Name)就要填写“chinassl.net”,而不能填写 “www.chinassl.net”,因为在申请SSL证书时发证机构认为“www.yourdomain.com”和 “yourdomain.com”是不同的两个域名;

例2:如将要为bill.chinassl.net申请SSL证书,那么这里公用名(Common Name)就 要填写“bill.chinassl.net”而不能填写“chinassl.net”或“www.chinassl.net”
openssl req -x509 -new -nodes -sha512 -days 3650 \
 -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \
 -key ca.key \
 -out ca.crt

生成服务器证书

证书通常包含.crt文件和.key文件,例如yourdomain.com.crt和yourdomain.com.key。

1、生成私钥。

openssl genrsa -out yourdomain.com.key 4096

 2、生成证书签名请求(CSR)。

调整-subj选项中的值以反映您的组织。如果使用FQDN连接Harbor主机,则必须将其指定为common name(CN)属性,并在key和CSR文件名中使用它。

openssl req -sha512 -new \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \
    -key yourdomain.com.key \
    -out yourdomain.com.csr

 3、生成 x509 v3 扩展文件。

无论您是使用 FQDN 还是使用IP地址连接到您的 Harbor 主机,都必须创建此文件,以便您可以为 Harbor 主机生成符合使用者替代名称(SAN)和 x509 v3 扩展要求的证书。替换DNS条目以反映您的域。

cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=yourdomain.com
DNS.2=yourdomain
DNS.3=hostname
IP.1 = 192.168.25.8
EOF

 4、使用 v3.ext 文件为您的港口主机生成证书。

将 CRS 和 CRT 文件名中的 yourdomain.com 替换为 Harbor 主机名。

openssl x509 -req -sha512 -days 3650 \
    -extfile v3.ext \
    -CA ca.crt -CAkey ca.key -CAcreateserial \
    -in yourdomain.com.csr \
    -out yourdomain.com.crt

向 Harbor 和 Docker 提供证书

生成 ca.crt 、 yourdomain.com.crt 和 yourdomain.com.key 文件后,必须将它们提供给Harbor和Docker,并重新配置Harbor以使用它们。

1、将服务器证书和密钥复制到Harbor主机上的 certcificates 文件夹中。

cp yourdomain.com.crt /data/cert/
cp yourdomain.com.key /data/cert/

 2、将 yourdomain.com.crt 转换为 yourdomain.com.cert ,供Docker使用。

Docker守护进程将 .crt 文件解释为 CA 证书,.cert文件解释为客户端证书。

openssl x509 -inform PEM -in yourdomain.com.crt -out yourdomain.com.cert

 3、将服务器证书、密钥和CA文件复制到港口主机上的Docker certificates文件夹中。必须先创建适当的文件夹。

cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.key /etc/docker/certs.d/yourdomain.com/
cp ca.crt /etc/docker/certs.d/yourdomain.com/

 如果将默认nginx端口443映射到其他端口,请创建文件夹 /etc/docker/certs.d/yourdomain.com:port或 /etc/docker/certs.d/harbor_IP:port。

4、重新启动Docker引擎。

systemctl restart docker

您可能还需要在操作系统级别信任证书。有关详细信息,请参阅harbor安装疑难解答。

下面的示例演示了使用自定义证书的配置。

/etc/docker/certs.d/
    └── yourdomain.com:port
       ├── yourdomain.com.cert  <-- Server certificate signed by CA
       ├── yourdomain.com.key   <-- Server key signed by CA
       └── ca.crt               <-- Certificate authority that signed the registry certificate

部署或重新配置harbor

如果尚未部署Harbor,请参阅配置Harbor YML文件,以获取有关如何通过在Harbor.YML中指定主机名和https属性来配置Harbor以使用证书的信息。

如果您已经使用HTTP部署了Harbor并希望将其重新配置为使用HTTPS,请执行以下步骤。

1、运行prepare脚本以启用HTTPS。

Harbor使用nginx实例作为所有服务的反向代理。使用prepare脚本将nginx配置为使用HTTPS。prepare 位于Harbor安装包中,与 install.sh 脚本处于同一级别。

./prepare

2、如果Harbor正在运行,请停止并删除现有实例。

images数据保留在文件系统中,因此不会丢失任何数据。

docker-compose down -v

3、Restart Harbor:

docker-compose up -d

验证HTTPS连接

在为Harbor设置HTTPS之后,您可以通过执行以下步骤来验证HTTPS连接。

1、打开浏览器并输入 https://yourdomain.com。它应该显示 harbor 界面。

某些浏览器可能会显示一条警告,指出证书颁发机构(CA)未知。使用非来自可信第三方 CA 的自签名 CA 时会发生这种情况。您可以将 CA 导入浏览器以删除警告。

2、在运行Docker守护进程的计算机上,检查 `文件,确保没有为https://yourdomain.com设置-unsecure-registry` 选项。

3、从Docker客户端登录到Harbor。

docker login yourdomain.com

 如果您已经将nginx 443端口映射到另一个端口,请在login命令中添加该端口。

docker login yourdomain.com:port

其他工具接入

Docker

cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.key /etc/docker/certs.d/yourdomain.com/
cp ca.crt /etc/docker/certs.d/yourdomain.com/

cp x.x.x.x:xxx.cert /etc/docker/certs.d/x.x.x.x:xxx/
cp x.x.x.x:xxx.key /etc/docker/certs.d/x.x.x.x:xxx/
cp ca.crt /etc/docker/certs.d/x.x.x.x:xxx/

Containerd

cp yourdomain.com.cert /etc/containerd/certs.d/yourdomain.com/
cp yourdomain.com.key /etc/containerd/certs.d/yourdomain.com/
cp ca.crt /etc/containerd/certs.d/yourdomain.com/

cp x.x.x.x:xxx.cert /etc/containerd/certs.d/x.x.x.x:xxx/
cp x.x.x.x:xxx.key /etc/containerd/certs.d/x.x.x.x:xxx/
cp ca.crt /etc/containerd/certs.d/x.x.x.x:xxx/

# example
mkdir -p /etc/containerd/certs.d/192.168.25.8:10443
cd /etc/containerd/certs.d/192.168.25.8:10443
wget http://192.168.25.9/raw/general/wz_harbor_ssl/192.168.25.8%3A10443.cert
wget http://192.168.25.9/raw/general/wz_harbor_ssl/192.168.25.8%3A10443.key
wget http://192.168.25.9/raw/general/wz_harbor_ssl/ca.crt
systemctl restart containerd.servic

skopeo

直接支持 /etc/docker/certs.d/ 目录下的证书。

helm

References

[转] 编程十年的感悟

前言

马尔科姆·格拉德威尔的“一万小时定律”指出,持续投入一万小时的努力,足以使人在某个领域达到专家水平。 按照每周20小时的练习量计算,每天大约需要投入3小时,十年左右才能达成这一目标。

从我写下第一行C代码算起,至今已超过十年。 期间,我编写了超过三十万行代码,其中一部分在微信编写的代码,曾服务过超过一亿的用户。

尽管写了这么多代码,我仍不敢自诩为专家。 但多年的“打工”生涯,日复一日地敲代码,也让我积累了不少感悟。 “工多艺熟”,这些感悟既是对编程技术的思考,更是对职场人生的体味。 毕竟,除了最初在学校学习的几年,我的编程生涯几乎都伴随着“打工”的酸甜苦辣(多是苦辣)。

持续学习

虽然大学是从C语言入门编程的,但是我在大学时主修的语言是Java ,毕竟Java是门非常成熟的工业语言,有非常丰富的框架,在国内的企业非常受欢迎,工作岗位也多。

我当时从Java Servlets入门Web开发,再学习了非常流行的JavaEE 企业开发框架SSH, 即 Structs2 1+ Spring 2+ Hibernate 3, Struct2 负责控制逻辑关系,Spring 负责解耦, Hibernate 负责操作数据库.

而到我开始找工作时,SSH的概念就变了, Struct2 被SpringMVC 4所取代, SSH 变成了 SpringMVC + Spring + Hibernate.

到我实习入职蚂蚁金服的时候,发现组里代码库操作数据库的ORM框架用的并不是Hibernate,而是 Ibatis 5, 后面又切换成了新的 MyBatis 6

而蚂蚁金服内部使用的也并不是Spring/SpringMVC, 而是自主研发出发的 Sofa框架 7, Spring 社区后来觉得Spring框架过于重量级,不利于快速开发,又开发了更轻量级的 SpringBoot 8, 而蚂蚁内部又推出了Sofa版本的 Sofaboot 9

去了微信支付后,前期都是在写C++, 使用微信内部自研的svrkit 框架,到后期因为负责数据治理相关项目的缘故,开始使用 Spark + Python + Hive SQL

现在在AWS S3, 因为业务对性能和资源使用有非常高的要求,又开始使用Rust, 而历史业务又是使用Java, 兜兜转转之后,又回到Java的路子上。

细数下来, 这些年来,我写过Java,C++,Python,Rust,Javascript/Typescript 这些语言的生产代码.

除去工作之外, 我还因为学习SICP 学习了Scheme, 因为使用Emacs 而学习了Emacs Lisp, 想做独立开发赚钱学习了Swift, 想感受Ruby on Rails的魅力而学习的Ruby, 还有以前为了压测写的Golang, 还有各种语言对应的框架和库.

自我学习编程以来,学过的编程语言没有10种也有半打了.

我也从来不会把自己定义为某门语言的程序员,如Java程序员,C++程序员等等, 我只叫自己做Software Development Engineer. 语言从来只是工具,只要你持续学习,遇到新的场景,自然就会学习新的编程语言了.

计算机的世界日新月异,可能几个月就会出个新框架,几年又会流行一门新语言,只有持续学习,才能持续保持自己的竞争力。

学好英语

领袖常说,「东升西降」,虽然不知道此种变化何时才能实现,但起码说明,目前是「西尚在上,东尚在下」,在计算机领域,尤其如此。

最前沿的技术都是英文资料,英语又是世界通行的语言,来自不同国家的开发者又会不约而同地使用英语来交流, 因此学好英语既可以了解最新的技术潮流,又可以融入社区,建立自己的影响力。

疫情之后,越来越多的公司都开始推行远程办公,从全世界招聘开发者. 这就意味着如果你英文过硬,甚至可以离开一线城市,避免高额的生活开销,在老家工作,陪伴在父母身边,同时赚取外汇;这对于饱受996困扰的程序员来说,未尝不是一条出路.

于我个人而言,坚持学习英语可能是我收获最大的投资之一。

熟悉我的朋友,尤其是我的高中同学可能知道,十年以前,我的英文可以说着实挺烂的: 满分150分的英语,只考个及格的90分可谓是家常便饭,后来也只会笨学英语,到高三的时候能考个120分已经是巅峰水平。

但上大学之后,我也没有就此懈怠放下英语,大一还每天去晨读英语。

没有口语交流的条件,就自己创造,去网上找人聊天, 当时还在一个叫 Interpals 10 聊天网站认识了全世界好多的人, 其中还有一个是年龄相仿的土耳其女孩,我们还加了Facebook, 经常用Skype 视频聊天.

大学毕业后就没有那么多的时间闲聊后就断了联系, 最近看Facebook的动态,看她也穿上婚纱了.

工作后也一直阅读英文的技术文章,用英文搜索内容,在Stackoverflow 和 GitHub 用英文回答问题,在Discord 的英语学习频道找人聊天, 把电脑和手机系统语言都换成英文的,从学习英语变成用英语。

后来在机缘巧合之下,从国内找到了加拿大AWS的工作,幸而有机会来加.

人们常说,路应该要越走越宽,而不是越走越窄;

而在我看来,英语就是夜里走路时手上拿着的手电筒,可以让我们走自己的路的同时, 扫一下旁边那条道的情况,需要时及时转向,不至于一条路走到黑.

独立思考

微信以前一直有发最新iPhone手机的传统,但是那已经是4年前的美好时光了。

记得2021年是小龙明确年会不会发手机的第一年,他当时透露,那一年会发个铝片。

当时同事之间还在讨论,iPhone也是一块铝片冲压而成的嘛,那发的是否还是iPhone呢,不发手机只是烟雾弹?

拆开年会礼物之后发现,的确是一块铝片,上面写着「2022保持独立思考」.

{{

}}

小龙一直强调「独立思考」对微信的重要性,认为如果要选择一个最重要的品质,他会选择「独立思考」。

上级说的不一定是对的,老师说的不一定是对,学术机构说的也不一定是对,媒体说的也不一定是对,声音大的更不一定是对,毕竟有理不在言高。

比如微服务架构非常流行,许多公司都在搞微服务,那么单体架构是否就应该不使用?

作为初创公司或小团队,新业务是否要上微服务架构呢?还是先使用单体架构,业务发展起来再迁移到服务呢?

开发过程免不了要做各种决策,比如技术选型,针对你的需求,你可能会找到一打「看似」符合要求的组件, 可能还会去网上找找对各个组件的评价,会发现众说纷纭,就需要自己独立对每个组件做出分析,找出其优劣,再结合自身团队的特点,做出决策.

关于独立思考,我最喜欢的是一句话是HBO出品短剧《切尔诺贝利》里面, 科学家瓦列里·列加索夫希望克格勃释放调查真相同事乌拉娜·霍缪克的要求,说可以保证她是没问题的,克格勃头子回答的那句话:

Trust, but verify.(相信,但要核实)

先跑起来再说

这句话还有一个广为人知的变种:「又不是不能用」

很多的程序员都是完美主义者,尤其是读过《重构》和《设计模式》的程序员,会倾向于把很多时间来优化代码,做重构。

以前的我也会有类似的冲动,总会想时间去优化代码, 但是项目肝多了之后,有种强烈的感觉,还是先把MVP上线,及早让用户体验。

如果没有用户使用,再好再漂亮的代码也没有任何意义了。

所以经常看到社区有人问做副业的时候,应该用什么语言和框架,PHP/Python/Ruby 会不会太慢,我的观点一直都是,先做个原型跑起来,先找到第一个用户再说。

当运行速度成为瓶颈时, 你的业务已经非常大,肯定有足够的钱可以招一打的程序员把你的项目换成Golang/Java了。

对此,我很赞同坐我旁边大佬关于代码质量的说法:

make it run, make it fast, make it beautiful.

最近在做副业的尝试,有个深刻的体会,技术可能是商业里面最不重要的。

从零把产品做出来,推广给用户,用户只会关注你的产品是否好用,能否解决他们的问题.

他们既不会关注你是用C++/Java还是Javascript 写的,也不会关注你代码写得是否优雅,与其执着于技术选型,不如先把产品干出来让用户试用。

顺手的才是最好的

经常会看到有人在社区提问,什么语言最好,什么框架最好,什么编辑器最好,什么操作系统最好。

「最好」是个相当主观的结论,也并没有针对所有场景的「最好」的解决方案, 但是经常能看到社区有人因为哪个语言更好而吵起来.

或者有人在分享A的时候,有人会在下面回复B/C/D更好, 然后又争吵起来.

让不禁让我想起《社会性动物》这本著名的社会心理学著作里面提到的团队认同现象, 当球迷与某支球队产生强烈的认同感后,会将球队视为自我认同的一部分,这里他们会:

  1. 用「我们」而不是「他们」来称呼球队
  2. 将球队的成功视为个人的成功
  3. 对批评球队的言论产生防御性反应,将这些批评视为对自我的攻击

如果有人问我这个问题,我会回答「你顺手熟悉的工具的最好」。

即使是出于乐趣,编程的目的还是利用计算机解决问题,而解决问题最好的工具就是你最熟悉的工具。

除非你了解的工具不适用于你的问题,那么自然就需要一个新工具,也不要削足适履,矫枉过正。

当然,如果是为了满足求知欲而想去学习一个新的语言,那选择你感兴趣的就可以了。

当初在2017年学习Rust, 也只是因为大四没有课,时间充裕, 想学点有趣的新东西,那时候Rust1.0才发布2年, 可没指望能靠Rust找到工作

记不清在哪里看过的一段话:

我也曾问过自己类似的问题:

  1. 是不是好的东西就能流行?不一定
  2. 是不是我喜欢的东西就是好的东西?不一定
  3. 我会不会花时间精力在一个不一定会流行但是我喜欢的东西上?会

多与人交流

程序员固然是和机器打交道,但是本质解决的还是人的问题.

当初学习编程的时候,曾经有个误区,认为自己只要把技术搞好,就可以不去关心什么「人情世故」。

因此初入职场之后,我既是这么持有这样的想法,又是这样行动的,虽然不至于对其他人冷脸相对,但是难免会如好友形容那般:「孤傲」

但是被毒打时间久了才会发现,无论是在国内或国外,都难免会有「人情世故」,用英文来说,那叫 network and connection.

即使我技术能力过硬,也需要被人见到才行,和同事领导相处关系好,才可以在做出成绩的时候,「花花轿子被众人抬」。

所以我现在都是有事没事都和同事们聊天,既可以提升下熟悉度,也可以了解到许多部门八卦, 还可以从同事们抱怨中找到潜在优化点,践行自己「Work hard and be nice to people」的理念.

这行做久了,会发现软件工程其实说到底,就是人的系统工程。

代码不是万能的

程序写多了之后就会有种幻觉,就是觉得什么事情都可以用代码来解决。

手里拿着锤子的时候,把什么都当成钉子来砸。

被毒打多才认清的事实就是,有很多事情是无法用代码来解决,代码只是个工具,只能在个合适的场景使用, 避免路径依赖.

酒香也怕巷子深,只会写代码没啥用,还要写文章,在公司内部做分享,让别人能「看到你」。

编程肝项目的专业能力固然重要,但是也要有营销自己的软实力,就像一位长者说的那样: 两手抓,两手都要硬.

不知道是中国人讲究谦虚内敛的品质,还是程序员「木讷呆板」的刻板印象,导致大家都不怎么营销自己。

有事没事和老板聊下天,增进下交流,经常露个脸,可能比肝十个项目还有用。

与优秀的人共事

从业多年,去过蚂蚁金服,微信支付和AWS 搬砖, 和各种各样的同事都共事过,有个越发强烈的感悟:

要与优秀的人共事

不仅能从他们身上学到非常到的优点,提升技术能力,可以学到最佳实践和工程经验,在Code Review 的时候可以学到更好的编程方式,遇到问题时又有靠谱的队友帮忙和指导。

由优秀的程序员开发出来的系统的独特之处,知道什么叫简单好用的系统,形成自己的技术品味。

品味与美感这个词是很抽象,但是用过了好用的系统,自然就不会对那些粗制滥造,还靠老板背书强行推广的系统感兴趣。

而提高技术品味在提高我们的技术认知的前提下,又能反过来帮我们提高设计能力.

和优秀的同事共事的另外一个好处是可以建立高质量的人脉网络,利于职业发展,跳槽换赛道也多个选择。

虽然初始公司也有优秀的开发者,但是平均而言,大公司优秀程序员的比例会更高,毕竟他们更有竞争力的薪资福利,自然也有更高的招聘门槛。

比如微信就有所谓的面试委员会,除了招聘部门的面试官之外,还要通过面委面试官的考核,避免为了快速招人而降低标准。

所以个人建议应届毕业生,有机会还是去大公司,见识下。

虽然离职微信快两年了,我仍然想念当初同组共事的同事们,他们真的是技术过硬,人又超nice, 还乐于帮忙.

正如孔子所言:与善人居,如入兰芷之室,久而不闻其香,则与之化矣;与恶人居,如入鲍鱼之肆,久而不闻其臭,亦与之化矣

身体是一切的本钱

编程这么多年,落下一堆的职业病。

大学时候就有的鼠标手(腱鞘炎), 工作几年之后「喜提」腰椎间盘突出,久坐下半身会麻痹,还有我曾经浓密黝黑的头发,现在也日渐凋零。

因为腾讯总部有免费的健身房,所以我基本工作日都会去健身房薅公司羊毛,2天有氧慢跑,2天无氧器械,坚持了快3年。 也开始注意自己的饮食,尽量少油少糖不喝酒。

健身虽然不是包治百病,但是起码人显得有精神了,也有精力应付高强度的工作了。

只有失去才会懂得珍惜,也真的只有在开始吃药,去医院复诊,才会开始注意身体。

虽然编程很有趣,虽然养家很重要,但是还是要注意身体,毕竟身体是一切的本钱,垮就没有其他的精彩故事了。

总结

无论是编程,还是其他的技能,我感觉都是「马太效应」,你学得越多,你懂得越多,再学新的东西,你就会学得越快。

代码写多了才意识到,程序员的竞争力并不是写代码,也并不是哪门语言或者框架, 其核心竞争力是通过技术解决问题的能力,又何必再去拘泥于哪门具体的编程语言或技术呢。

希望编程十年只是个起点,十年后可以再写一篇「编程二十年的感悟」

推荐阅读

来源 编程十年的感悟 作者 Ramsay