原文出处:常用逻辑结构

在工作和生活中,沟通是重要的一环。想把事情叙述清楚有几个常用的逻辑结构。主要分为四种类型:传统型、流程型、情境型、要素型。

传统型

传统型是知识点按照常用逻辑,抽丝剥茧般的展示出来。又有三种主要的结构。

流程型

知识点按照完成一项任务的顺序来呈现。

情境型

知识点按照一项能力在不同情境中的应用来呈现。

要素型

知识点按照一个问题在不同方面上的体现来呈现。

思考

Q: 《面试专家职位面试官会问什么》这篇文章使用了什么逻辑结构?

A: 要素型结构。

Q:《代码荣辱观-以运用风格为荣,以随意编码为耻》这篇文章使用了什么逻辑结构?

A:传统型结构中的:是为什么->为什么->怎么做

Q: 《平时代码中用不到设计模式?Are you kidding me?》这篇文章使用了什么逻辑结构?

A: 情景型结构

Q: 本文使用了什么逻辑结构?

A: 传统型结构中的:概念->原理->应用


原文出处:面试专家职位面试官会问什么

考察实践经验和方法

很早之前阿里打电话过来面试我,是一个架构师的职位。当时问我一个问题:在review代码的时候,如果代码特别长,比如几千行几万行,你如何去review呢?
我的回答角度是这样的:

  1. review PR我一般不会review所有的代码,而是变更点。整体的代码review会以模块review的形式来做。项目成员介绍自己这块的架构是怎样的,解决了什么问题,有什么问题是待解决的。架构优势和不足等。然后再由开发人员自己去讲解代码。

  2. 我建议开发人员用好工具。比如作为一个git用户,非常重要的技能是必须能够维护一个清晰的语义化的变更历史暴露出来。review代码的时候可以通过历史清晰的看到代码的变更思路。如果一个开发人员还不具备这样的意识或不知道怎样做,我会建议他给开源社区贡献几个PR,相信这会对他影响很大。

  3. 我们整个团队的主要迭代策略是:小步快跑,小迭代。一次性提交的代码过多,很可能意味着阶段划分过粗。这时候应该和开发人员一起梳理一下合理划分流程。

  4. 我review代码的主要核心聚焦在防护代码上。就是代码一旦出现了问题,里面有没有紧急预案的措施进行控制。比如有没有加开关、报警,异常处理等。

考察蓝图

看过《浪潮之巅》的朋友们不知道有什么这样的感受:所有这些站在浪潮之巅的企业都是在其创始人实现了其最初的蓝图之后才开始走下坡的。因为这之后,很大的精力和努力都用来解决下一步怎么走的问题。

所以如果招聘者本身就有一个蓝图,他招人是很好招的。他只需要招有方法的人,这种人是可以培训出来的。但是有想法的人是很少的。按照我的世界观宇宙理论,这种人心里有一个强大的宇宙,在释放能量。

PS:我认为AI目前的发展方向永远不可能代替智能。人的思维、感情是量子层面的。用数字信号来模拟,就好比用大锤子击打一个原子,完全不在一个层面。

考察方法体系

这时一般会把考察放在两个层面。一个是理论,看面试者的讲述成不成体系,有没有漏洞。另外一个一般会考察在实际中的运用,一般用STAR来设立一个场景。

比如:手下有个同事,态度很好,也很上进,但是总是出这样那样的问题,这时候该怎么做。

这个场景是非常开放的,把这个人开了也是一种解决方法。把这个人安排做一些低风险的项目也是一种解决方法。建立更加规范的流程和工具也一种解决方法。

我的回答角度是这样的:

从两个方面着手。首先,如果出了问题,流程上肯定是有漏洞的。这是个极好的机会,去发现这方面有哪些不足并加以修正和改善。

另一个方面,从对同事本身的提高入手帮他分析根本原因。首先列举一段时间发生的事情。每件事情背后的本质。最终会有几条:

  1. 对结果负责而不是对行为负责。
  2. 对线上操作存有敬畏之心,三思而后行。
  3. 准确性来源于深度和逻辑。
  4. 可以慢,可以少,做对,做好。

总结

应届生面试要考察算法、源码,越往后反而越不问了,问的都是书里代码里没有的。


原文出处:平时代码中用不到设计模式?Are you kidding me?

引子

平时我是个反应非常慢的人。有多慢呢?大概是两年前有次团队内部开会时,我听到同学说平时代码中用不到设计模式,我当时没有回答。两年后我终于反应过来了:“Are you kidding me?我每天都在用!”

应用场景

建造者模式

写一个接口,入参是一大堆,什么都有。这是长期积累下来的代码,参数都提供给外部用了。只能做加法,不能做减法。这时候接口就这样了,内部能不能好看点呢?

可以啊,重构,留壳抠瓤啊!

这一堆参数可以封装成一个有意义的类,再往下传递处理。这时候就用到了建造者模式,对参数进行封装。构造一个静态builder函数,将参数传进去,返回是一个对象。

例子如下:

这是构造一个“人”的对象。builder函数建议放到“人”这个对象里,因为这样从领域上来说更合理更清晰。

@Data
@Accessors(fluent = true)
public class Person {
    private String name;
    private int armCount=2;//胳膊数默认为2
    private int legCount=2;//腿数默认为2

    private Person(String name) {
        this.name = name;
    }

    public static Person builder(String name) {
        return new Person(name);
    }
}

适配器模式

大家现在用mysql都喜欢用mybatis-generator工具自动生成部分代码。里面的对象一般称为领域对象。在上层给用户返回结果的时候一般不直接用。因为信息太多了。比如数据库中固定结构的字段:创建时间、更新时间、是否为逻辑删除列这些,更好的一个方式是对外不可见。这时候就要对领域对象和传输层对象之间做一个转换,这时候用到适配器模式。

下面是使用BeanUtils将对象之间做适配的例子:

private static QuotaResponse toQuotaResponse(Quota quota) {
    QuotaResponse quotaResponse = new QuotaResponse();
    BeanUtils.copyProperties(quota, quotaResponse);
    return quotaResponse;
}

观察者模式

数据库设计时常用的一种表结构设计方式是子母表。比如可以为“人”设计一张数据表。军人、工程师、特工有各自不同的属性,它们是“人”这张数据表的关联子表。为了展示时候的效率,将这些子母表展开,另外做一张展示表。

在写一个定时任务时,如果扫描到“人”的状态状态更新了。比如“人”的胳膊数变了,这时候可以通知这些展示表,状态都更新了。

举个例子:

因为九头蛇在街头横行,见人就砍,出现了一些残疾人。神盾局特工Fitz(菲兹)正在研制一种肢体再生技术,这个技术完成将会是包括人在内的所有动物的福音。因此,人类医院和动物医院都作为观察者都订阅了Fitz的项目状态。一旦完成,这些医院都会得到通知。

定义医院作为观察者的通用接口

public interface Observer {
    void update(boolean isFinish);
}

Fitz开放了一个attach方法,任何单位都可以实现Observer接口后通过这个方法被加入通知列表,一旦完成,Fiz将通知所有观察者:

public class Fitz {
    private List<Observer> observers = new ArrayList<Observer>();

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void finish() {
        notifyAllObservers();
    }

    public void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update(true);
        }
    }
}

总结

代入思考,技术提升的关键

推荐阅读

「前任的50种死法」开发踩坑案例--慢就是错

一个请求过来都经过了什么?(2017年http版)

测测你是《花千骨》里的谁-业务代码里常用的设计模式