松花皮蛋的黑板报
  • 分享在京东工作的技术感悟,还有JAVA技术和业内最佳实践,大部分都是务实的、能看懂的、可复现的

扫一扫
关注公众号

ARTS-20-敏捷开发之LinkedIn的高效代码评审技巧

博客首页文章列表 松花皮蛋me 2019-07-28 19:38

ARTS的初衷

Algorithm: 主要是为了编程训练和学习。

Review:主要是为了学习英文

Tip:主要是为了总结和归纳在日常工作中所遇到的知识点。学习至少一个技术技巧。在工作中遇到的问题,踩过的坑,学习的点滴知识。

Share:主要是为了建立影响力,能够输出价值观。分享一篇有观点和思考的技术文章

https://www.zhihu.com/question/301150832

一、Algorithm

LRU Cache

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

get(key) – Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(key, value) – Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

The cache is initialized with a positive capacity.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // returns 1
cache.put(3, 3); // evicts key 2
cache.get(2); // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4

class LRUCache {

    private int capacity;

    private Map<Integer,Integer> cache ;

    private LinkedList<Integer> list;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>(capacity);
        this.list = new LinkedList<>();
    }

    public int get(int key) {
        if(cache.containsKey(key)) {
             list.removeFirstOccurrence(key);
            list.addFirst(key);
            return cache.get(key);
        }
        return -1;
    }

    public void put(int key, int value) {
        if(cache.containsKey(key)) {
            list.removeFirstOccurrence(key);
        } else {
            if(list.size()==capacity) {
                int last = list.removeLast();
                cache.remove(last);
            }
        }
        list.addFirst(key);
        cache.put(key,value);
    }
}

二、Review

阅读和代码评审是每个工程师在日常工作中都要做的事情,然而一个标准的code review流程,实际上很难落地,它要求每次代码变更在部署到生产环境前,甚至是在提交合并前,都需要被另外一个小组成员进行正式的评审。在LinkedIn公司,自从2011年起code review成为了开发流程中法定、强制的一部分,也意味着它成为代码质量保证和知识分享中必不可少的一部分,目标是让团队成员能够迅速提升自己的技能水平

实施公司级的code review最大的一个收益是提升了研发流程的标准化,在LinkedIn公司每个团队使用相同的工具或者流程进行代码评审,意味着任何一个人对其他团队的项目可以提供评审帮助或者贡献代码,这消除了诸如“我可以修复代码中的错误,但如何构建代码并提交修复程序?”这样的问题,这反过来有助于增加工程组织中不同团队之间的协作

我们在将代码评审变成一项法定流程的过程中,为公司建立了良好健康的反馈文化,工程师在他们领域中乐于提出或者接收反馈,而不只是埋头苦干写代码。实际上,高质量的代码审查经验是在公司晋升参考中是举足轻重的,因为那是工程技能最直接的客观证据

通过过去很长一段时间实践,我们总结出了在代码评审中的一些最佳实践和技巧,如下面所示,通过问题的形式呈现,尽量让审查双方都能从中获得最大的价值

我真的明白代码变更的目的是什么吗?

为了加快高质量的code review流程和有效提高团队技能,每次变更提交的代码文件中应该包括变更概要,简要说明背后的需求或者动机是什么,而不是需要从代码更改本身反向推断。实际上,为提交代码写说明文档是重新梳理的过程,从中你可能会发现自己把需求实现搞复杂了,应该再简化下,于是就回头改代码,从而改善已有代码的设计,甚至培养出做事之前先进行推演等等好习惯

我提出的建议是积极反馈吗?

整洁的代码和高度测试覆盖率被视为理所当然的,然而有些code review过于关注代码问题,侧重点变成代码怎么修改才能变得更好,这非常不好,大部分人需要积极的反馈才能得到鼓舞和提高积极性,工程师也不例外,我们不能忽视正面赞赏的价值。当审查员发现代码中好的设计时,应该提出来并给予肯定,这种积极的反馈往往具有传染性,它能让整个团队变得更加有活力

我的代码评审评论表达清楚了吗?

和所有的代码提交一样,任何积极或者消极的反馈都不应该空谈,应该有针对性的解释,如果觉得代码提交者收到反馈后可能一头雾水,可以进行过度解释而不是简洁,不然会产生更多的问题,并需要更多来回沟通。当然,注释也可以非常简洁,比如”消除了重复代码”、“增加了测试覆盖率”,这种类型的解释有助于让团队的价值观得以明确

我是否需要感谢提交者的努力?

某些代码质量不高,需要返工重新编写,在这种情况下,重要的是仍然承认他为之付出的努力,他之前可能只是对业务熟悉程度不够,最佳方式是提供高质量的code review反馈和正确的解释,比如提出“谢谢你,每次代码提交中始终有好的设计”之类的话语,而不是帮他写代码,从长远来看,这其实是在一定程度上复制你的生产力

我们可以从代码评审中获益吗?

这个问题可以让我们非常强有力并且粗暴地评估code review是否有必要。在下班前,工程师应该像对待一个有帮助性的开发工具一样正视代码评审结果,优先级应该比其他工作还要高,如果认为没有作用,就将其删除。没有意义的code review评论的典型示例是与代码格式相关的,那些应该由自动化工具并且是在编写过程中验证,而不是最后由工程师来完成

“测试完成”部分是否足够彻底?

code review中,不但要审查提交者的代码,还要关注做过的测试,除了一些单元测试,还有一些可能是手动的测试。提交者最好列出所有测试过的案例,这样可以让审查者做出更多的测试建议,从而提高质量

在review反馈中,我是否太迂腐了?

一些code review在重要的问题上提出了相当多的修复意见,而不是强有力的建议,也就是说过于关注细节,过于炫技,从而拖慢了整个进度,甚至会造成双方的隔陔。建立一个清晰的、有明确目标、积极的、有吸引力的code review流程是避免上述问题的好方法

总结一下,一个标准的code review流程能够提升代码质量、团队技能和知识互通。当团队中每个工程师都意识到,其他人会阅读我的代码,同时我需要认真对待评审结果,下次代码编写要参考评论然后制作得更好,从而提高工作质量,这是增长和改善的关键

翻译修改自:https://thenewstack.io/linkedin-code-review/

三、Tip

五星级软件工程师的高效秘决,关键在于在日常工作中坚持实践精英的工作策略:积极主动、构建知识网络、自我管理、团队合作、领导力、跟随力、大局观、呈观与表达、组织智慧

四、Share

程序员都应该了解的运维知识经验