左耳听风
1. 如何技术变现?
2. 怎样成为一个可以更好技术变现的人?
3. 如何防止信息泄露,保证数据安全?
4. 什么是技术领导力?
5. 什么样的人具有技术领导力?
6. 如何拥有技术领导力?
7. 什么样的技术会成为主流技术?
8. 如何成为一个大家愿意跟随的leader?
1. 如何技术变现?
技术变现的本质是 你能帮助别人解决问题,并且你解决的问题别人解决不了。
2. 怎样成为一个可以更好技术变现的人?
1)千里之行,积于跬步:leetcode练习,大话数据结构学习,极客课程,架构师之路,英文阅读能力
2)关注有价值的东西:关于社会需求,关于技术趋势。多关注大公司JD要求,熟悉流行技术。
3)找到能体现价值的地方:在一家能高速发展的公司中,技术人员的价值可以达到最大化。
4)动手能力很重要:多动手实践
5)关注技术付费点:一个是帮别人挣钱的地方,一个是帮别人省钱的地方
6)提高自己的能力和经历:大公司
7)找到有价值的信息源:英文阅读能力,谷歌搜索
8)输出观点和价值观:博客,关注公司遇到的问题
9)朋友圈很重要
3. 如何防止信息泄露,保证数据安全?
1)关注技术框架和数据库漏洞。理解你的软件产品中使用了哪些支持性框架和库,它们的版本号分别是多少。时刻跟踪影响这些产品和版本的最新安全性声明。
2)日志不记录敏感信息。
3)敏感数据只入不出。通过提供服务接口来让别的系统只能在这个区域内操作这些数据,而不是把数据传出去,让别的系统在外部来操作这些数据。如:手机号不外传,发短信传主键,只能由本服务发短信。
4)防止代码注入等。例如:SQL注入、XSS攻击(Cross Site Script,跨站脚本攻击)、CSRF攻击(Cross Site Request Forgery,跨站请求伪造)等取得用户权限。XSS与CSRF攻击
5)使用更合理的密码加密方式,非对称加密等,加密的时候加盐,密码设置过期时间,多因子验证等。散列一则需要用目前公认安全的算法(比如 SHA-2 256),而已知被攻破的算法则最好不要使用(如 MD5,能人为找到碰撞,对密码验证来说问题不大),二则要加一个安全随机数作为盐(salt)。
6)限制外部系统的数据访问量,超过访问量后,需要报警或是拒绝访问。
7)隔离安全级别高的数据,所谓安全级别非常高的地方,即这个地方需要有各种如安全审计、安全监控、安全访问的区域。
8)建立多个安全层。就算表示层被攻破,也不会直接提供出重要(或所有)后台信息资源的访问权。
9)建立一个流程,来快速地部署带有安全补丁的软件产品发布版。自动化测试来回归老的功能,保证版本兼容。
10)针对公网资源,建立对异常访问模式的监控机制。现在有很多侦测这些行为模式的开源和商业化产品,一旦发现异常访问就能发出警报。
11)提高内部人员安全意识,不点击钓鱼邮件等。
12)不保存不必要的东西。
13)数据库访问权限分级:开发人员只有查看权限,并且大量数据导出需要审批。只能通过查询系统查看数据,不能通过客户端访问数据。删除、修改数据需要审批,数据量大的只能DBA执行。
当黑客的投入和收益大大不相符时,黑客也就失去了入侵的意义。
所谓的安全方案基本上来说就是能够把这个风险控制在一个很小的范围。对于在这个很小范围出现的一些数据安全的泄露,我们可以通过“风控基金”来做业务上的补偿,比如赔偿用户损失,等等。因为从经济利益上来说,如果风险可以控制在一个——我防范它的成本远高于我赔偿它的成本,那么,还不如赔偿了。
4. 什么是技术领导力?
技术领导力是一种可以获得绝对技术优势的技术能力。有如下表现:
1)尊重技术,追求核心基础技术。
2)追逐自动化的高效率的工具和技术,同时避免无效率的组织架构和管理。
3)解放生产力,追逐人效的提高。
4)开发抽象和高质量的可以重用的技术组件。
5)坚持高于社会主流的技术标准和要求。
5. 什么样的人具有技术领导力?
1)能够发现问题。能够发现现有方案的问题。
2)能够提供解决问题的思路和方案,并能比较这些方案的优缺点
3)能够做出正确的技术决定。用什么样的技术,什么解决方案、怎样实现来完成一个项目。
4)能够用更优雅,更简单,更容易的方式来解决问题
5)能够提高代码或软件的扩展性、重用性和可维护性
6)能够用正确的方式管理团队。所谓正确的方式,一方面是,让正确的人做正确的事,并发挥每个人的潜力;另一方面是,可以提高团队的生产力和人效,找到最有价值的需求,用最少的成本实现之。并且,可以不断地提高自身和团队的标准。
7)创新能力。能够使用新的方法新的方式解决问题,追逐新的工具和技术。
是的,一句话,总是在提供解决问题的思路和方案的人才是有技术领导力的人。
6. 如何拥有技术领导力?
1)扎实的基础技术。你要吃透基础技术。基础技术是各种上层技术共同的基础。
a. 编程部分:C语言、编程范式、算法和数据结构
b. 系统部分:计算机系统原理、操作系统原理和基础、网络基础、数据库原理、分布式技术架构
2)非同一般的学习能力。提高学习能力。所谓学习能力,就是能够很快地学习新技术,又能在关键技术上深入的能力。
a. 学习的信息源
b. 与高手交流
c. 举一反三的思考
d. 不怕困难的态度
e. 开放的心态
3)坚持做正确的事。做正确的事,比用正确的方式做事更重要,因为这样才始终会向目的地靠拢
a. 提高效率的事
b. 自动化的事
c. 掌握前沿技术的事
d. 知识密集型的事
e. 技术驱动的事
4)高标准要求自己。只有不断地提高标准 ,你才可能越走越高,所以,要以高标准要求自己,不断地反思、总结和审视自己,才能够提升自己
a. Google 的自我评分卡。Google 的评分卡是在面试 Google 时,要求应聘人对自己的技能做出评估的工具,它可以看出应聘人在各个领域的技术水平。我们可以参考 Google 的这个评分卡来给自己做评估,并通过它来不断地提高对自己的要求。(该评分卡见文末附录)。
b. 敏锐的技术嗅觉。这是一个相对综合的能力,你需要充分利用信息源,GET 到新的技术动态,并通过参与技术社区的讨论,丰富自己了解技术的角度。思考一下是否是自己感兴趣的,能解决哪些实际问题,以及其背后的原因,新技术也好,旧技术的重大版本变化也罢。
c. 强调实践,学以致用。学习知识,一定要实际用一用,可以是工作中的项目,也可以是自己的项目,不仅有利于吸收理解,更有利于深入到技术的本质。并可以与现有技术对比一下,同样的问题,用新技术解决有什么不同,带来了哪些优势,还有哪些有待改进的地方。
d. Lead by Example。永远在编程。不写代码,你就对技术细节不敏感,你无法做出可以实践的技术决策和方案。
7. 什么样的技术会成为主流技术?
1)学习难度是否低,是否上手快
2)有没有解决软件开发过程中的痛点
3)有没有一个较好的社区
4)有没有一个或多个杀手级应用
5)有没有一个工业化的标准
6)是否有一个或者多个巨型的技术工作作为后盾
7)有没有一个不错的提高开发效率的开发框架
8. 如何成为一个大家愿意跟随的leader?
1)帮人解决问题
2)被人依赖
3)赢得他人信任
4)开放的心态 + 倾向性的价值观
5)Lead by Example
6)保持热情和冲劲
7)能抓住重点,看透事务的本质
8)描绘令人激动的方向,提供令人向往的环境
9)敢当铺路石,为他人创造机会
9. 故障团队一般使用哪几种手段来恢复系统?
1)重启和限流:重启和限流主要解决的是可用性的问题,不是功能性的问题。重启还好说,但是限流这个事就需要相关的流控中间件了。
2)回滚操作:回滚操作一般来说是解决新代码的 bug,把代码回滚到之前的版本是快速的方式。
3)降级操作:并不是所有的代码变更都是能够回滚的,如果无法回滚,就需要降级功能了。也就是说,需要挂一个停止服务的故障公告,主要是不要把事态扩大。
4)紧急更新:紧急更新是常用的手段,这个需要强大的自动化系统,尤其是自动化测试和自动化发布系统。假如你要紧急更新 1000 多台服务器,没有一个强大的自动化发布系统是很难做到的。
出现故障时,最重要的不是 debug 故障,而是尽可能地减少故障的影响范围,并尽可能快地修复问题
10. 故障前需要做哪些准备?
1)以用户功能为索引的服务和资源的全视图
2)为地图中的各个服务制定关键指标,以及一套运维流程和工具,包括应急方案
3)设定故障的等级
4)故障演练
5)灰度发布系统
11. 故障复盘需要做哪些?
1)现场进行复盘会议
2)回顾总结故障处理的整个过程:就像一个 log 一样,需要详细地记录几点几分干了什么事,把故障从发生到解决的所有细节过程都记录下来。
3)故障原因分析:需要说明故障的原因和分析报告。
4)Ask 5 whys :需要反思并反问至少 5 个为什么,并为这些“为什么”找到答案。
5)故障后续整改计划:需要针对上述的“Ask 5 Whys”说明后续如何举一反三地从根本上解决所有的问题。
6)形成文档,这个文档要提交到管理层,向公司的 VP 级的负责人进行汇报,并由他们来审查。
12. 应对故障有哪些优化原则?
1)举一反三的解决当下故障:为自己赢得更多的时间。
2)简化复杂、不合理的技术架构、流程和组织:你不可能在一个复杂的环境下根本地解决问题。
3)全面改善和优化整个系统,包括组织:解决问题的根本方法是改善和调整整体结构。而只有简单优雅的东西才有被改善和优化的可能。
13. 如何管理自己的时间?
1)主动管理:避免同事打扰,避免干扰信息源
2)学会说“不”:
a. 当你面对做不到的需求时,你不要说这个需求做不到。尤其是,你不要马上说做不到,你要先想一下,这样让别人觉得你是想做的,但是,在认真思考过后,你觉得做不到,并且给出一个你觉得能做到的方案。这里的诀窍是—— 给出另一个你可以做到的方案,而不是把对方的方案直接回绝掉
b. 当你面对过于复杂的需求时,你不要说不。你要反问一下,为什么要这样做?这样做的目的是什么?当了解完目的以后,你可以给出一个自己的方案,或是和对方讨论一个性价比更好的方案。你可以回复说,这个需求好复杂,我们能不能先干这个,再做那个,这样会更经济一些。这里的诀窍是——我不说我不能完全满足你,但我说我可以部分满足你
c. 当你面对时间完全不够的需求时,你也不要说不。既然对方把压力给你,你要想办法把这个压力还回去,或是让对方来和你一同分担这个压力。
d. 这个时候,我惯用的方式是给回三个选择:a. 我可以加班加点完成,但是我不保证好的质量,有 bug 你得认,而且事后你要给我 1 个月的时间还债。b. 我可以加班加点,还能保证质量,但我没办法完成这么多需求,能不能减少一些?c. 我可以保质保量地完成所有的需求,但是,能不能多给我 2 周时间?
我不能说不,但是我要有条件地说是。而且,我要把你给我的压力再反过来还给你,看似我给了需求方选择,实际上,我掌握了主动。
这就是学会说“不”的方法。说白了,你要学会在“积极主动的态度下对于不合理的事讨价还价”。只有学会了说“不”,你才能够控制好你的时间
3)加班和开会:开会,不是讨论问题,而是讨论方案,开会不是要有议题,而是要有议案
14. 如何利用好自己的时间?
1)投资自己的时间:
a. 花时间学习基础知识,花时间读文档。
b. 花时间在解放自己生产力的事上:在自动化、可配置、可重用、可扩展上要多花时间。对于软件开发来说,能自动化的事,就算多花点时间也要自动化,因为下次就不用花时间了。让自己的软件模块可以更灵活地配置和扩展,这样如果有需求变更或是有新需求的时候,可以不用改代码,或者就算要改代码也很容易。
c. 花时间在让自己成长的事上:注意,晋升并不代表成长,成长不应该只看在一个公司内,而是要看在行业内,在行业内的成长才是真正的成长。所以,把时间花在能让自己成长,能让自己有更强的竞争力,能让自己有更大的视野,能让自己有更多可能性的事情上。这样的时间投资才是有价值的。
d. 花时间在建立高效的环境上:我相信你和我会有一样的一个习惯,那就“工欲善其事,必先利其器”。我们程序员在做事之前都喜欢把自己的工作环境整理到自己喜欢的状态下。比如使用趁手的开发工具,使用趁手的设备。
这里,我想把这个事扩大一下,花些时间在影响你身边的人上,比如你的同事,你的产品经理,你的老板,去影响他们,让他们理解你,让他们配合你来建立更好的流程和管理方法。在这个方向上花时间也是很值得的。
2)规划自己的时间:
a. 定义好优先级
b. 最短作业优先
c. 想清楚再做
d. 关注长期利益规划
你要学会规划自己的行动计划,不是短期的,而是一个中长期的。我个人建议是按季度来规划,这个季度做什么,达到什么目标,一年往前走四步,而不是只考虑眼下
3)用好自己的时间
a. 将军赶路不追小兔
b. 形成习惯
c. 形成正反馈
d. 反思和举一反三
15. 错误处理的最佳实践
1)统一分类的错误字典:无论你是使用错误码还是异常捕捉,都需要认真并统一地做好错误的分类。最好是在一个地方定义相关的错误。比如,HTTP 的 4XX 表示客户端有问题,5XX 则表示服务端有问题。也就是说,你要建立一个错误字典。
2)同类错误的定义最好是可以扩展的:这一点非常重要,而对于这一点,通过面向对象的继承或是像 Go 语言那样的接口多态可以很好地做到。这样可以方便地重用已有的代码。
3)定义错误的严重程度:比如,Fatal 表示重大错误,Error 表示资源或需求得不到满足,Warning 表示并不一定是个错误但还是需要引起注意,Info 表示不是错误只是一个信息,Debug 表示这是给内部开发人员用于调试程序的。
4)错误日志的输出最好使用错误码,而不是错误信息:打印错误日志的时候,应该使用统一的格式。但最好不要用错误信息,而应使用相应的错误码,错误码不一定是数字,也可以是一个能从错误字典里找到的一个唯一的可以让人读懂的关键字。这样,会非常有利于日志分析软件进行自动化监控,而不是要从错误信息中做语义分析。比如:HTTP 的日志中就会有 HTTP 的返回码,如:
5)忽略错误最好有日志:不然会给维护带来很大的麻烦。
6)对于同一个地方不停的报错,最好不要都打到日志里:不然这样会导致其它日志被淹没了,也会导致日志文件太大。最好的实践是,打出一个错误以及出现的次数。
7)不要用错误处理逻辑来处理业务逻辑:也就是说,不要使用异常捕捉这样的方式来处理业务逻辑,而是应该用条件判断。如果一个逻辑控制可以用 if - else 清楚地表达,那就不建议使用异常方式处理。异常捕捉是用来处理不期望发生的事情,而错误码则用来处理可能会发生的事。
8)对于同类的错误处理,用一样的模式:对象的错误,要么都用返回 null,加上条件检查的模式,要么都用抛 NullPointerException 的方式处理。不要混用,这样有助于代码规范。
9)尽可能在错误发生的地方处理错误:因为这样会让调用者变得更简单。
10)向上尽可能地返回原始的错误:如果一定要把错误返回到更高层去处理,那么,应该返回原始的错误,而不是重新发明一个错误。
11)处理错误时,总是要清理已分配的资源:这点非常关键,使用 RAII 技术,或是 try-catch-finally,或是 Go 的 defer 都可以容易地做到。
12)不推荐在循环体里处理错误:这里说的是 try-catch,绝大多数的情况你不需要这样做。最好把整个循环体外放在 try 语句块内,而在外面做 catch。
13)不要把大量的代码都放在一个 try 语句块内:一个 try 语句块内的语句应该是完成一个简单单一的事情。
14)为你的错误定义提供清楚的文档以及每种错误的代码示例:一个 try 语句块内的语句应该是完成一个简单单一的事情。
15)对于异步的方式,推荐使用 Promise 模式处理错误:
CompletableFuture.supplyAsync(Integer::parseInt) // 输入: "ILLEGAL" .thenApply(r -> r * 2 * Math.PI) .thenApply(s -> "apply>> " + s) .handle((result, ex) -> { if (result != null) { return result; } else { return "Error handling: " + ex.getMessage(); } });
16)对于分布式的系统,推荐使用 APM 相关的软件:对于分布式的系统,推荐使用 APM 相关的软件