软件架构设计-读书笔记下

欢迎大家关注 github.com/hsfxuebao ,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈

第三部分:技术架构之道

第八章:高并发问题

任何问题都是殊途同归,到最后只能通过两种操作:读和写。

8.1 高并发读

1. 加缓存

缓存可分为 本地缓存 和 集中式缓存 。使用缓存的同时我们需要思考缓存的更新策略:

  • 主动更新:  当数据库中的数据发生变更的时候,主动删除或更新缓存中的数据
  • 被动更新:  当用户查询请求到来时,再对缓存进行更新

同样使用缓存可能会面临的几个问题:

  • 缓存雪崩:  即缓存的高可用问题。如果缓存宕机/过期,所有请求会瞬间压垮数据库
  • 缓存穿透:  查询缓存中不存在的数据,导致短时间内大量请求写入并压垮数据库
  • 缓存击穿:  缓存中热点数据过期,直接访问数据库,导致数据库被压垮

那么缓存的使用无外乎都是对数据进行冗余,达到空间换时间的效果

2. 并发读

单线程不行,通常就会使用多线程。这种明显治标不指标,容易达到性能瓶颈

3. 重写轻读

当微博这种大流量的平台,查看关注人和自己发布的微博列表看似很简单需求,通常只需要两张表,一个是 关注关系表 ,一个是 微博发布表。但是对于高并发查询的时候很容易将数据库打崩。

那我们就需要改成 重写轻读 的方式,不是查询的时候才聚合,,而是提前为每个 userId 准备一个 收件箱

当某个被关注的用户发布微博时,只需要将这条微博发送给所有关注自己每个用户的收件箱中,这样用户查询的时候只需要查看自己的收件箱即可。

但通过使用 重写轻读 容易带来一个问题,那就是如果一个人拥有了 500 万粉丝,那就意味着他需要往 500 万个收件箱中推送,这对系统来说同样是个不小的挑战,那这个时候就需要采用 推拉结合 的方式

对于粉丝量少的用户(设个阈值),发送微博后可以直接推送到用户的收件箱,对于粉丝较多的用户,只推送给在线的用户,对于读的一端,用户有些可以通过收件箱获取,有些需要自己手动去拉,这种就是推拉结合的方式

8.2 高并发写

1. 数据分片

常见的有: 分库分表Java的ConcurrentHashMapKafka的partition

2. 任务分片

数据分片是对要处理的数据(或请求)进行分片,任务分片是对处理程序本身进行分片。

常见的有:CPU 的指令流水线Map/ReduceTomcat 的1+N+M网络模型

1+N+M 模型

3. 异步化

通过消息中间件,分流处理

4. 批量处理

不管是Mysql、Redis、Kafka 通常上都不会将数据一条一条的进行处理,而是多条合并成一条,一次性写入

8.3 容量规划

高并发读写是一种定性分析,而压力测试和容量规划就是一种定量分析

1)吞吐量、响应时间与并发数

这三个概念都是比较常见的

  • 吞吐量:单位时间内处理的请求数,例如 QPS、TPS 等指标
  • 响应时间:处理每个请求需要的事件
  • 并发数:服务器同时并行处理的请求个数

三者关系:吞吐量 * 响应时间 = 并发数

关键点说明:谈论吞吐量(QPS)的时候,一定需要谈对应的响应时间是多少,随着QPS的增加,响应时间也在增加,虽然 QPS 提上来了,但用户端的响应时间却变长了,客户端的超时率增加,用户体验变差,所以这两者需要权衡,不能一昧地提升 QPS,而不顾及响应时间

2)压力测试与容量评估

容量评估的基本思路:

机器数 = 预估总流量/单机流量

其中分子是一个预估的值(通过历史数据预估),分母通过压力测试得到

在计算的时候需要使用峰值测算,而不能使用均值。尽管有时候峰值持续的时间很短,但不容忽视。

压力测试方法:

  1. 线上压力测试对比测试环境压力测试
  2. 读接口压力测试对比写接口压力测试
  3. 单机压力测试对比全链路压力测试

第九章:高可用与稳定性

高并发使系统更有效率,高可用使系统更可靠

9.1 多副本

不要把所有鸡蛋放到一个篮子里

1)本地缓存多副本

利用消息中间(发布/订阅机制),一条消息发出,多台机器收到后更新自己的本地缓存

2)Redis多副本

Redis Cluster 提供了 Master – Slave 之间的复制机制,当 Master 宕机后可以切换到 Slave。

3)MySQL 多副本

MySQL 之间可以用到异步复制或半异步复制,同步复制性能较差,比较少用

4)消息中间件多副本

对于Kafka类的消息中间件,一个Partition通常至少会指定三个副本,为此Kafka专门设计了一种称为ISR的算法,在多个副本之间做消息的同步

9.2 隔离、限流、熔断和降级

1)隔离

隔离是指将系统或资源分割开,在系统发生故障时能限定传播范围和影响范围,即发生故障后不会出现滚雪球的效应

  1. 数据隔离
  2. 机器隔离
  3. 线程池隔离:核心业务的线程池需要和非核心业务的线程池隔离开
  4. 信号量隔离

信号量隔离是 Hystrix 提出的一种隔离方式,比线程池隔离更要轻量,由于线程池太多会导致线程过多从而导致切换的开销大,而使用信号量隔离不会额外增加线程池,只在调用线程内部执行。信号量本质上是一个数字,记录当前访问某个资源的并发线程数,在线程访问资源之前获取信号量,访问结束时释放信号量,一旦信号量达到阈值,便申请不到信号量,会直接 丢弃请求,而不是阻塞等待

2)限流

限流可以分为技术层面的限流和业务层面的限流。技术层面的限流比较通用,各种业务场景都可以用到;业务层面的限流需要根据具体的业务场景做开发。

3)熔断

  1. 根据请求失败率做熔断
  2. 根据请求响应做熔断

注意点:  限流是服务端,根据其能力上限设置一个过载保护;而熔断是调用方对自己的一个保护。能熔断的服务肯定不是核心链路上的必选服务,如果是的话,则服务超时或者宕机,前端就不能用了,而不是熔断。熔断其实也是降级的一种方式

4)降级

降级是一种兜底方案,是在系统出故障之后的一个尽力而为的措施,比较偏向业务层面

9.3 灰度发布与回滚

频繁进行系统变更是个风险较高的操作。灰度与回滚可以使该操作变的相对可靠稳定

1)新功能上线的灰度

当一个新的功能上线时,可以将一部分流量导入到这个新的功能,如果验证功能没有问题,再一点点增加流量,最终让所有流量都切换到这个新功能上。

  1. 按 userId 进行流量划分
  2. 固定位数进行流量划分
  3. 属性或标签进行流量划分

2)旧系统重构的灰度

如果旧的系统被重构了,我们不可能在一瞬间把所有旧的系统下线,完全变成新的系统,一般会持续一段时间,新旧系统同时共存,就需要增加流量分配机制。

3)回滚

回滚的方式:

  1. 安装包回滚:  这种方式最简单,不需要开发额外的代码,发现线上有问题直接重新部署之前的安装版本
  2. 功能回滚:  在开发新功能的时候,可以配置相应的配置开关,一旦发现新功能有问题,则关闭开关,让所有流量进入老系统

9.4 监控体系和日志报警

1. 监控体系

  • 资源监控:例如CPU、内存、磁盘、带宽、端口等
  • 系统监控:RPC平响时间、失败率等
  • 业务监控:

2. 日志报警

  • 日志等级不分
  • 关键日志漏打

第十章:事务一致性

10.1 分布式解决方案

1)2 PC 理论

2 PC 中有两个角色:事务协调者事务参与者

每一个数据库就是一个参与者,调用方也就是协调者,2 PC 将事务的提交分为两个阶段:

  1. 阶段一:协调者向所有参与者询问是否可以提交事务,并等待回复,各参与者执行事务操作,将 undo 和 redo 日志计入事务日志中,执行成功后给协调者反馈 ack
  2. 阶段二:如果阶段一成功,则通知参与者提交事务,否则利用 undo 日志进行回滚

这种方式也存在了许多问题:

  1. 性能问题:所有参与者在事务比较阶段处于同步阻塞状态,容易导致性能瓶颈
  2. 可靠性问题:如果协调者出现问题,那么会一直处于锁定状态
  3. 数据一致性问题:在阶段2中如果协调者和参与者都挂了,有可能导致数据不一致

2)3PC 理论

解决了 2PC 同时挂掉的问题,将 2PC 的准备阶段再次一分为二

  • 阶段一:协调者向所有参与者发出包含事务内容的 canCommit 请求,询问是否可以提交事务
  • 阶段二:如果阶段一成功,协调者会再次发出 preCommit 请求,进入准备阶段,参与者将 undo 和redo 日志计入事务日志中。如果阶段一失败,协调者则发出 abort 请求,参与者便会中断事务
  • 阶段三:如果阶段二成功,协调者发出 doCommit 请求,参与者便会真正提交事务。如果失败,便会发出 rollback 请求,参与者会利用 undo 事务进行回滚,并结束事务

该方式依然会造成数据不一致问题:如果 preCommit 阶段存在部分节点返回 nack,那么协调者刚要中断事务便挂掉了,一定时间后参与者便会继续提交事务,造成数据不一致问题

3)补偿事务 TCC

TCC(try-confirm-cancel)是服务化的二阶段编程模型,核心思想是:针对每个操作都要注册一个与其对应的确认和补偿(撤销操作)。他同样也是分为三个步骤

  • try 阶段:主要是对业务系统做检测及资源预留
  • confirm 阶段:主要是对业务系统做确认提交。try 阶段执行成功并开始执行 confirm 阶段,默认情况下 try 成功,confirm 一定会成功
  • cancel 阶段:主要是业务执行错误,执行回滚,将预留的资源释放

例子:转账操作,第一步在 try 阶段,首先调用远程接口把自己和对方的钱冻结起来,第二步在 confirm 阶段,执行转账操作,如果成功则进行解冻,否则执行 cancel

它解决了数据最终一致性的问题,通过 confirm 和 cancel 的幂等性,保证数据一致性

4)最终一致性(消息中间件)

可以基于 RocketMQ 实现最终一致性。为了能通过消息中间件解决该问题,同时又不和业务耦合,RocketMQ提出了“事务消息”的概念

  1. 步骤1: 系统A调用Prepare接口,预发送消息。此时消息保存在消息中间件里,但消息中间件不会把消息给消费方消费,消息只是暂存在那。
  2. 步骤2: 系统A更新数据库,进行扣钱操作。
  3. 步骤3: 系统A调用Comfirm接口,确认发送消息。此时消息中间件才会把消息给消费方进行消费。

RocketMQ会定期(默认是1min)扫描所有的预发送但还没有确认的消息,回调给发送方,询问这条消息是要发出去,还是取消。发送方根据自己的业务数据,判断这条消息是应该发出去(DB更新成功了),还是应该取消(DB更新失败)

详见:分布式事务Seata-原理及四种事务模式

第十一章:多副本一致性

无论是 MySQL的 Master/Slave,还是 Redis 的 Master/Slave,或是Kafka的多副本复制,都是通过牺牲一致性来换取高可用性的

本章主要对 Paxos、Zab、Raft 三种算法进行解析。

详见:Zookeeper理论篇2-一致性算法详解(Paxos、ZAB选举数据同步、容灾、Raft算法、脑裂)

第十二章:CAP理论

  • 强一致性 Consistency:是指所有节点同时看到相同的数据。
  • 可用性 Availability:任何时候,读写操作都是成功的,保证服务一直可用
  • 分区容错性 Partition tolerance:当部分节点出现消息丢失或分区故障的时候,分布式系统仍然能够运行

CP的系统追求强一致性,比如Zookeeper,但牺牲了一定的性能

AP的系统追求高可用,牺牲了一定的一致性,比如数据库的主从复制、Kafka的主从复制

1)分布式锁

1. 基于 Zookeeper 实现

可以利用 Zookeeper 的 瞬时节点 的特性。每次加锁都是创建一个瞬时节点,释放锁则删除瞬时节点。因为 Zookeeper 和客户端之间通过心跳探测客户端是否宕机,如果宕机,则 Zookeeper 检测到后自动删除瞬时节点,从而释放锁。

2. 基于 Redis 实现

Redis的性能比Zookeeper更好,所以通常用来实现分布式锁。但 Redis 相对 Zookeeper 也存在些许问题

  1. 没有强一致性的Zab协议。如果Master 宕机,Slave会丢失部分数据,造成多个进程拿到同一把锁
  2. 没有心跳检测。在释放锁之前宕机,会导致锁永远不会释放

第四部分:业务架构之道

第十三章:业务意识

1) 产品经理与需求分析师

产品经理从某种意义上来说就称之为需求分析师。作为一个技术人员,不需要像产品经理或需求分析师那样对需求了如指掌,但具有良好的业务意识确是做业务架构的基本条件

那么什么业务意识?

  1. 了解需求来自何处

有时需求来自何处,技术为谁而坐,往往和公司的基因、盈利模式紧密挂钩,公司本身决定了需求从什么地方来

  1. 判断是真需求还是假需求

很多原因都会导致伪需求,比如老板的决定,面向 KPI 的需求。而其中存在一个因素便是:信息传播的递减效应

当发生一个事件时,第一个人 A 看到事件的全过程,掌握 100 的信息量,描述给 B 的时候,受制于记忆力、表达力等因素只能描述出 90 的信息,往下递推,到 D 的时候可能只剩 60 的信息。

所以,作为一个技术人员,当从产品经理接到需求的时候,一定要回溯,明确需求是在什么背景下提出的,究竟要解决用户的什么问题。

  1. 需求的优先级

人力资源和时间资源是有限的。如何合理分配尤为重要

2)业务是什么

一个内容能称为一个业务,往往具备一个特点,就是闭环。

什么是闭环?

  1. 团队闭环:有自己的产品、技术、运营和销售联合作战
  2. 产品闭环:从内容的生成到消费,整条链路把控
  3. 商业闭环:具备自负盈亏的能力
  4. 纵向闭环:某个垂直领域,涵盖从前到后
  5. 横向闭环:平台模式,横向覆盖某个横切面

3)业务架构的双重含义

业务架构既关乎组织架构,也关乎技术架构

  1. 从理论上讲,合理的团队的组织架构应该是根据业务的发展来决定的,不同的公司在不同的发展阶段会根据业务的发展情况,将壮大的业务拆分,萎靡的业务合并
  2. 支持业务的技术架构,业务架构和计数架构会相互作用,相互影响

第十四章:业务架构思维

1)伪分层

不管是业务架构还是技术架构,C端业务还是B端业务,我们都会用到分层技术

经典分层技术

伪分层的特征
  1. 底层调用上层:设计分层的时候应深入思考 DIP(依赖反转)原则
  2. 同层之间,服务之间各种双向调用:  这个很容易造成循环依赖问题,考虑是否要抽取 Middle 层来作为中间层
  3. 层之间没有隔离,参数层层透传,一直穿透到最低层,导致底层系统经常变动
总结
  1. 越底层的系统越单一、越简单、越固化
  2. 越上层的系统花样越多、越容易变化。要做到这一点,需要层与层之间有很好的隔离和抽象。
  3. 层与层之间的关系应该严格遵守上层调用下层的准则

2)边界思维

1. 对象层面(SOLID 原则)

一个函数、一个类、一个模块只做一件事,不要把不同的职责糅在一起,这就是边界思维的一种体现

2. 接口层面

首先想到的不是如何实现,而是把系统当做一个黑盒,看系统对外提供的接口是什么,接口也就是系统的边界,定义了系统可以支持什么、不支持什么。所以接口的设计往往比接口的实现更重要!

3. 产品层面

内部实现很复杂,用户界面很简单,把复杂留给自己,把简单留给用户

4. 组织结构层面

总结: 边界思维的重点在于约束,是一个  “负方法”  的思维方式。架构强调的不是系统能支持什么,而是系统的“约束”是什么,不管是业务约束,还是技术约束。没有“约束”,就没有架构。一个设计或系统,如果“无所不能”

3)系统化思维

系统化系统不在于头痛医头脚痛医脚,而是追溯源头,关注整体上的影响,把不同的东西串在一起考虑,而不是割裂后分开来看

4)利益相关者分析

当谈到系统的时候,首先要确定的是系统为哪几类人服务,同哪几个外部系统交互,也就确定了系统的边界。

5)非功能性需求分析(以终为始)

软件有功能需求和非功能需求,非功能性需求有:

  1. 并发性:关注点在于系统能抵抗多大的流量
  2. 一致性:数据一致性问题
  3. 可用性:是否保证服务一直处于可用状态
  4. 可维护性:关注点在于代码的可理解性
  5. 可扩展性:  系统功能是否能够灵活扩展,而不会遇到一个需求就需要大刀阔斧地修改
  6. 可重用性:  开发新的需求,旧的功能模块可以拿过来直接用

6)抽象

语言只是对现实中我们所注意到的事务特征的一种抽象,每一次命名,都是一个抽象化的过程,这个过程会忽略掉现实事务的许多特征。但是抽象的目的是为了交流提供便利,而不是给交流带来负担,因此我们需要对自己的每一次抽象负责,不能抽象到最后自己都不明白抽象的含义是什么。

抽象的几种特征:

  1. 越抽象的词,在词典中个数越少;越具象的词,在词典中个数越多。
  2. 越抽象的词,本身所表达的特征越少;越具象的词,特征越丰富。
  3. 越抽象的词,意义越容易被多重解读;越具象的词,意义越明确

7)建模

建模的本质:把重要的东西进行显性化,进而把这些显性化的构造块互相串联起来,组成一个体系

8)正交分解

分解是一个很朴素的思维方式,把一个大的东西分成几个部分。比分解更为严谨,更为系统的是 正交分解,需要保证两个原则:

  1. 分清:同一层次的多个部分之间要相互独立,无重叠
  2. 分净:完全穷尽,无遗漏

第十五章:技术架构与业务架构的融合

该章节主要是对 DDD(领域驱动模型)  做出解释,比较泛化,这里推荐一本好书 《实现领域驱动设计》 ,书中对 DDD 解说的相对具体,这本书小菜最近也在啃读中,后续会出相应的读书笔记,请伙伴们点点关注,后续不会迷路!

第十六章:个人素质的替身

1)能力模型

对于程序员来说,我们是干技术,很纯粹,技术很好表示你能力越强。但是当你慢慢职位上涨的时候,会发现技术不能代表你的全部。

1. 格局

打开格局,打开格局,平时常说的一句调侃的话却格外重要。

做技术我们需要开阔视野打开格局,我们才能了解更多的技术栈,更好的运用到项目中。

做产品我们需要开阔视野打开格局,我们才能了解市面上的竞品是什么样子,更好的借鉴到自己的项目中。

2. 历史观

格局 是从 空间 的角度看待问题,而 历史观 则是从 时间的角度看待问题。任何一种技术,都不是凭空想出来的,任何一个需求,都不是凭空捏造的,我们需要进行回溯,了解它诞生的背景,才能知其所以然。

3. 抽象能力

有些人抽象出来的事物可以让别人一眼贯通,有些人抽象出来的事物却连自己的看不懂。这就是抽象能力的表现。

很多写代码的人习惯利用 自底向上 的思维解决问题,讨论需求的时候首先想到的是这个需求如何实现,而不是这个需求本身合不合理,对于很多新人来说 需求的合不合理,依赖于需求好不好实现,这样的方式很容易导致 只见树木,不见森林,最后淹没在各种错综复杂的细节中。

4. 深入思考的能力

深入思考的能力主要考察技术的深度

深度并不表示要在所有领域都很精通,而是专注于某个领域,对于专家和全栈工程师的区别,想想哪个职位的薪资可能会更高

5. 落地能力

落地能力值的就是执行力,有空头画大饼的能力,却无落地去实现的能力,只会阻碍项目的正常前行。这大概就是技术不喜销售的原因吧

2)影响力的塑造

进入职场的前几年尤为关键,有的人平步青云,有的人却止步不前。那就是没能很好的塑造自己的影响力。影响力该如何塑造?

1. 关键时候能顶上

最怕的是 事不关己高高挂起 的心态,如果下次摊上事的是你如何?如果当团队中遇到问题,这个时候能够迎上,绝对可以让人知道还有你这一号人物(当然要斟酌抗下的风险,迎难而上并不意味着逞强

2. 打工思维和老板思维

虽然我们常说自己是打工人,但有的时候何不把自己当成合伙人?

打工的思维,安排的事需要干一件,绝不多一点,只管好自己的一亩三分地

老板的思维,这个产品的价值在哪?这个产品存在哪些问题,需要如何改进?为何用户一直投诉的事,还没及时处理?

3. 空杯心态

术业有专攻,水平再高的人都需要谨记山外有山人外有人,否则就会一直待在自己的舒适圈中,刚愎自用

4. 建言献策

不必害怕自己的回答是否正确,而瞻前顾后不敢发言,充分发挥 圆桌文化, 有建议有想法大胆提出,不然你是想留给自己的蛔虫知道吗

第十七章:团队能力的提升

1)不确定性与风险把控

技术管理的首要任务就是项目管理,通常存在以下几种不确定性

1. 需求的不确定性

由于各种外部条件,导致需求提议的想法不是很成熟(可能只是头脑风暴),处于需要不断优化的阶段,那么这个时候过早的进行开发容易浪费资源。作为技术负责人就需要和产品经理以及相关的业务方进行广泛的头痛,需要达成共识的情况,才能投入。

2. 技术的不确定性

启动新项目的时,最怕的就是一开始技术没有很好的选型,到中间开发阶段时候再进行替换,这种劳民伤财的事情还是尽量避免发生。必须在项目早期的时候就进行过多的调研和测试。

3. 人员的不确定性

现在的大多数职员都是面向金线开发,大多数在职情况并不是那么稳定,而将项目的大多权限与业务集中在一名成员上是个不明智的选择,能够进行 AB岗位开发是个不错的选择,两人之间的业务相互熟悉,哪怕是因为请假的原因也能很快的进行替代补充

4. 组织的不确定性

公司越大,业务越复杂,部门越多。随便做一个项目,都可能与好几个业务部门打交道。这些部门可能还在异地,平时只能即时通信,或者远程电话沟通。对于这种情况,在项目前期必须要做尽可能多的沟通,调研对方提供的业务能力,哪些目前有,哪些还在开发中,哪些还没有开发。在充分沟通的基础上,和对方敲定排期表,不定期地同步进度,保证对方的进度和自己在一个节奏上。

2) 以价值为中心的管理

image.png

  1. 第一个层次

程序员最熟悉且经常谈论的:系统有多少个业务模块,功能多么强大,采用了多少新技术,采用了某个先进的算法。

  1. 第二个层次

在所做的所有工作中,最核心的是采取了哪种措施?最终可能会抽象出一到两个。再追问

一下,这一到两个大的技术改进有什么价值,通常都会追问到软件的各个非功能性需求:

  • (1)可重用性。做了某个Jr包、组件、服务,别人不再需要重复造轮子。

  • (2)可扩展性。来了一个新的需求,只需要配置一下或做很简单的代码开发即可实现,不需要改动很多系统。

  • (3)可维护性。整个系统解耦做得很好,代码也很整洁。叠加功能或找人接手都比较容易。

  • (4)高性能。用户体验很好,所有请求都在100ms内返回。

  • (5)高并发。能支持千万到亿级的用户并发访问。

  • (6)稳定性。系统时不时出问题、宕机,己经把这些问题都解决了,还增加了监控,出问题会立即报警。

  • (7)高可靠。做了灾备方案,即使某个机器宕机,系统也不受影响。

  • (8)一致性。做到了强一致性,极大地提高了业务体验。

  1. 第三个层次

所做的系统为公司带来了什么业务价值:

  • 极大提升了用户体验?因此促进了用户增长?

  • 提高了用户的活跃度?

  • 为公司增加了收入?

  • 降低了公司的研发成本?

  • 提升了公司的运维效率?

  • 为公司开辟了一个新的市场?

  1. 第四个层次

站在公司的角度来看,公司是一个在市场经济中追求利润最大化的组织。从这个角度来看,技术也好,产品也好,运营销售也好,最终目的都是要增加公司的利润,即使短期不盈利,长期也是要盈利的。而增加利润,要么“开源”,要么“节流”。所以做的任何东西的价值,基本都会被归结到从这个层次去评判。当然,还有一类是“战略性投入”的项目,虽然它本身不直接挣钱或挣钱很少,但是为了支撑其他盈利的核心业务而能发挥重要作用。

以“价值”为中心的管理,会让人避免陷入“无效忙碌”的状态:整个团队天天忙得不亦乐乎,做各种功能,解决各种问题,但回过头来想想,到底有多少东西是有“价值”的?

3) 团队培养

1. 技术能力

image.png

独立意识

独立意识独立非常的关键,无论对于任何级别的人,都需要独立。所谓独立,就是能掌控事情。交给一个功能开发,交给一个模块能独自把功能做得很好;,能把模块快速开发完,运行稳定;交给一个项目,能带领一个小团队从需求开始一直到上线完成整个项目,不需要上级操心,按时按质地交付。做到这一步,意味着团队的每个人在自己所处的层次都是可“托付”的

思维能力

解决项目中遇到的问题只达到及格分数,需要上升一层,也就是培养思维能力。

思维能力的培养只能靠平时,在面对一个个的问题时,通过一次次的讨论来言传身教。面对问题要刨根问底,深挖问题的背景,掌握解决问题的办法背后的技术原理,研究是否有更好的解决办法。如此一来,思维能力慢慢就会提高。






© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYQsfjaQ' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片