清醒思考的艺术-checklist

清醒思考的艺术-checklist

  • 幸存者偏差:高估了成功的概率
  • 看清楚自己
  • 是否高估自己
  • 是否陷入从众心理
  • 是否与沉没成本难舍难分
  • 是否是互惠互利陷阱
  • 摆脱确认偏差,不要证明自己是正确的
  • 是否屈服于权威
  • 是否依据对比来判断(请不要怎么做)
  • 现成偏见
  • 是否故意营造一种危机气氛
  • 明确判断他人的能力范围
  • 警惕控制错觉
  • 警惕激励过敏
  • 是否是平均值会起作用?
  • 警惕公地悲剧
  • 切勿只以结果判断决定
  • 面对选择,遵守自己的标准
  • 排除对他人好感的影响
  • 禀赋效应 let it go
  • 无巧不成书,如果从不发生才令人感到意外
  • 唱反调的人也许是最重要的人
  • 0风险偏误
  • 稀有性谬论
  • 概率偏误-前车之鉴后事之师
  • 独立事件-赌徒谬论
  • 锚定效应,你的锚在哪里?
  • 警惕归纳法,警惕黑天鹅事件
  • 厌恶风险,但不要无视损失
  • 社会性懈怠
  • 赢家诅咒-你会得到什么、失去什么
  • 是否高估了人的影响
  • 相互关系不等同于因果关系
  • 避免光环效应过度影响总体印象
  • 合理不一定真实
  • 不要被框架效应限制注意力
  • 遇到不明情况,就会发生行动偏误
  • 不作为偏误,如果不解决问题,你就是问题的一部分
  • 自利偏误,为什么你从来不自责
  • 避免长时间负面影响
  • 自我选择偏误
  • 联想偏误,不要欠拟合也不要过拟合
  • 认知失调,是否在自我安慰
  • 即使行乐,只限周末,不要为了眼前的利益破坏未来的利益
高性能MySql 4至6章读书笔记

高性能MySql 4至6章读书笔记

第四章 Schema设计

选择优化的数据类型

更小的通常更好,但是要确保没有低估需要存储的值的范围,因为在schema中的多个地方增加数据类型范围是一个十分耗时的操作。

简单就好

简单的数据类型的操作通常需要更少的cpu时间。

尽量避免NULL

可为NULL的列使得索引、索引比统计和值比较都更为复杂。

当然也有例外,InnoDB使用单独的位存储NULL值, 所以对于稀疏数据有很好的空间效率。

选择标识符

一旦选定一种类型,要确保在所有的关联表中都使用同样的类型。类型之间需要精确匹配,包括像UNSIGNED这样的属性。尽量只用整型定义标识符。

注意可变长字符串

其在临时表和排序时可能导致悲观的按最大长度分配内存

范式与反范式

范式是好的,但是反范式有时也是必须的,并且能带来好处。

第五章 创建高性能索引

B-Tree 索引的查询类型
  • 全值匹配: 指的是和索引的所有列进行匹配
  • 匹配最左前缀: 查找索引前几列进行匹配
  • 匹配列前缀: 只匹配某一列的值的开头部分
  • 匹配范围值: 查找索引某一范围的值
  • 精确匹配某一列并范围匹配另外一列
  • 只访问索引的查询:覆盖索引
B-Tree 索引的限制
  • 如果不是按照索引的最左列开始查找,则无法使用索引
  • 不能跳过索引中的列
  • 如果查询中有某个列的范围查询,则其右边的所有列都无法使用索引:例如查询 索引为key(last_name, fisrt_name, dob)
    1
    where last_name = 'a' and first_name like 'J%' and dob = '1877-12-23'
索引的优点
  1. 大大减少服务器需要扫描的数据量
  2. 帮助服务器避免排序和临时表
  3. 将随机I/O变为顺序I/O
高性能索引-独立的列

如果查询中列不是独立的,则mysql不会使用索引

1
2
select actor_id from sakila.actor where actor_id + 1 = 5;

高性能索引-前缀索引和索引选择性

有时候需要索引很长的字符列,通常可以索引开始部分的字符,同时也会降低索引的选择性。

索引的选择性指的是,不重复的索引值和数据表的记录总数的比值。索引的选择性越高表示查询效率越高,因为选择性高的索引可以过滤掉更多的行。

前缀索引是一种能使索引更小,更快的有效方法,但是也有其缺点:前缀索引无法做order by 和 group by,也无法使用前缀索引做覆盖索引。

高性能索引-多列索引

最容易遇到的困惑是多列索引的顺序,正确的顺序依赖于使用索引的查询,同时需要考虑如何更好的满足排序和分组需要。对于如何选择索引的列顺序有一个经验法则:将选择性最高的列放在索引的最前列。只有不需要考虑排序和分组时,将选择性跟高的列放在最前面通常是最好的,但是考虑问题需要更全面,避免随机I/O和排序更加重要。

高性能索引-覆盖索引

如果一个索引包含所需要查询的字段的值,我们就可以称之为“覆盖索引”

覆盖索引的好处:

  • 索引条目通常远小于数据行大小,所以如果只需要读取索引,那mysql就会极大的减少数据访问量。
  • 因为索引是按照列值顺序存储的,所以对于I/O密集型范围查询回避随机从磁盘读取每一行数据的I/O要小的多
  • 由于Innodb的聚簇索引,覆盖索引对Innodb表特别有用,可以避免对主键索引的二次查询。

覆盖索引的陷阱:

1
select * from products where actor = 'SEAN CARREY' and title like '%APOLLO%';

  • 没有索引能够覆盖这个查询,因为查询从表中选择了所有的列
  • mysql不能再索引中执行like操作,只能做最左前缀匹配

高性能索引-使用索引扫描来做排序

mysql有两种方式可以生成有序的结果:通过排序操作;或者使用索引顺序扫描。mysql可以使用同一个索引既满足排序,有用于查找行。

只有当索引的列顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向都一样时,mysql才能使用索引来对结果做排序。如果查询需要关联多张表,则只有当ORDER BY子句引用的字段全部为第一个表时,才能用索引做排序。ORDER BY子句和查询的限制是一样的:需要满足索引的最左前缀的要求。

有一种情况下ORDER BY子句可以不满足索引的最左前缀要求:

1
2
select rental_id, staff_id from sakila.rental where rental_date = '2005-05-25'
order by inventory_id, customer_id;

索引为key(rental_date, inventory_id, customer_id),前导列为常量的时候,如果where子句或者join子句中对这些列指定了常量,就可以弥补ORDER BY的不足。

1
2
where rental_date > '2005-12-25' order by inventory_id, customer_id;
where rental_date = '2005-12-25' and inventory_id in (1, 2) order by cusomter_id;

对于索引上是范围查询,mysql无法使用之后的索引列

高性能索引-使用索引扫描减少锁

索引可以让查询锁定更少的行,如果你的查询从不访问那些不需要的行,那么就会锁定更少的行。但这只有当innoDB在存储引擎层能够过滤掉所有不需要的行是才有效。如果索引无法过滤掉无效的行,那么innoDB检索到数据并返回给服务器层后,innoDB已经锁定这些行了(mysql 5.6后没有这个问题)。

高性能索引-避免多个范围条件

下面的查询:

1
where last_online > date_sub(now(), interval 7 day) and age bwtween 18 and 25

这个查询有一个问题:它有两个范围条件,last_online和age列,mysql可以使用last_online的索引或者是age列的索引,但是无法同时使用它们。

高性能索引-延迟关联优化分页

如果一个查询匹配结果有上百万行的话会怎样?

1
select * from profiles where sex = 'm' order by rating limit 10;

即使有索引,如果用户界面需要翻页,并且翻页到比较靠后的地方也会非常慢,如:

1
select * from profiles where sex = 'm' order by rating limit 1000000, 10;

无论如何创建索引,这种查询都是个严重的问题,mysql需要花费大量时间来扫描需要丢弃的数据。其中一个解决的办法是限制能够翻页的数量。

优化这类索引的另一个比较好的策略是使用延迟关联,通过使用覆盖索引返回需要的主建,再根据这些主建回主表获得需要的行,这样可以减少mysql扫描需要丢弃的行数。

1
2
3
4
5
6
select * from profiles innner join 
(
select id fomr profiles p where p.sex = 'm' order by rating limit 1000000, 10

) as t using (id);

第六章 慢查询优化

优化数据访问

查询性能低下最基本的原因是访问数据太多。某些查询可能不可避免的需要筛选大量数据,单这并不常见。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化。对于低效的查询,我们发现通过下面几个步骤来分析总是很有效:

  1. 确认应用程序时候检索大量超过需要的数据。
  2. 确认mysql服务层是否在分许大量超过需要的数据行。

第一种情况可以使用limit和选择需要的列来解决。在确定查询只返回需要的数据之后,接下来应该看看查询为了返回结果是否扫描了过多的数据,对于mysql有三个衡量查询开销的指标:

  • 响应时间
  • 扫描的行数
  • 返回的行数

没有那个指标能完美地衡量查询的开销,但它们大致反映了mysql内部查询时需要访问多少数据,并可以大概推算出查询运行的时间。

在评估查询开销的时候,需要考虑一下从表中找到某一行数据的成本。mysql有好几种访问方式可以查找并返回一行结果。有些访问方式可能需要扫描很多行才能返回一行结果,也有些访问方式可能无需扫描就能返回结果。

在explain语句中的type列反应了访问类型。访问类型有很多种,从全表扫描到索引扫描、范围扫描、唯一索引查询、常数引用等。这里列的这些,速度是从慢到快,扫描行数也是从大到小。如果查询没有办法找到合适是访问类型,那么解决的最好办法通常是增加一个合适的索引。

一般mysql能够使用如下三种方式应用where条件,从好到坏依次为:

  • 从索引中使用where条件吗来过滤不匹配的记录,这是在存储引擎层完成的。
  • 使用索引覆盖扫描来返回记录(extra出现using index),直接从索引中过滤不需要的数据并返回命中结果。这是在mysql服务层完成的,但无需再回表查询记录。
  • 从数据表中返回数据,然后过滤不满足条件的记录(extra出现using where)。这是在mysql服务器层完成,mysql需要从数据表中读出记录然后过滤。

如果发现查询需要扫描大量的数据但只返回少数的行,那么可以使用下面的技巧去优化它:

  • 使用覆盖索引,把需要用的列都放到索引中
  • 改变库表结构。例如使用单独的汇总表
  • 重写复杂的查询, 让mysql优化器能够以更加高效的方式执行这个查询

重构查询方式-切分查询

有时候对于一个大查询我们需要分而治之,将大查询分成小查询。删除旧数据是一个很好的例子,如果用一个大的语句一次性完成,则可能一次需要锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞恨到重要的查询。

重构查询方式-分解关联查询

例如下面这个查询:

1
2
3
4
select * from tag
join tag_post on tag_post.tag_id = tag.id
join post on tag_post.post_id = post.id
where tag.tag = 'mysql';

可以分解成下面这个查询来代替:

1
2
3
4
5
select * from tag where tag = 'mysql';

select * from tag_post where tag_id = 1234;

select * from post where post.id in (123,456,567);

用分解关联查询的方式重构查询有如下的优势:

  • 让缓存效率更高。许多应用程序可以方便地缓存单表查询对应的结果对象。
  • 将查询分解后,执行单个查询可以减少锁的竞争。
  • 在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和高扩展。
  • 查询本身效率可能提升,使用in代替关联查询,可能比随机关联更高效。
  • 减少冗余记录的查询
  • 相当于在应用层实现了哈希关联

重构查询方式-优化关联查询

  • 确保on或者using子句上的列上有索引。
  • 确保任何group by和 order by 的表达式中只涉及到一个表中的列,这样mysql才有可能使用索引来优化这个过程
季度总结 如何管理自我时间

季度总结 如何管理自我时间

最近这个季度

最近比较忙,算了下自己可以利用的空闲时间,忙时一天可能只有1到3个小时空闲时间,甚至一天没有空余时间。一周大约只有30小时时间是可以利用的,如果算上玩手机时间只会更短,如果再把这些时间再浪费掉,可能最近半年的成长就只有一些项目经验而已了。所幸平常关注的博客和《软技能》这本书里有提及一些关于自我时间管理相关内容,我简单实践了2个月,分享下这方面的心得感悟。

计划和休息

《软技能》中作者是如何做计划的?

  • 季度计划 明确宏观目标,以及如何实现
  • 月计划 估算当月能完成多少工作量
  • 周计划 为每周安排必须完成的强制性任务
  • 日计划 排除干扰,按需调整
  • 休息 每隔一段时间休息,只做强制性任务

很惭愧,工作刚开始一两年我少有计划,单纯凭借好奇心学习到了不少东西。大约从去年写年度总结开始才刚刚做一些计划。目前我使用微软to-do跟踪自己的计划进度和deadline效果显著,治好了我的拖延症。

简单来说《软技能》中阐述的几个观点我感觉十分受益:

  1. 要有计划
  2. 完成计划时保持专注
  3. 使用番茄工作法可以保证保证一段时间的专注, 同时还可以确定自己的工作效率, 总结不足提高自身效率,从而帮助自己精确且高效的指定计划
  4. 只有你完成了计划的工作,接下来的休息时间才能安心

这边年读书情况

这半年看的书比较少,但是刷题和博客总结写的多了些

技术类:
《sql反模式》推荐, 应该叫数据库结构设计的最佳实践
《软技能,代码之外的生存指南》 有很多事比代码更重要的多,推荐

心理类:
《你的灯亮着吗》 解决问题前,先要搞清楚问题的本质。 一般般

[项目感悟] 读《再谈敏捷开发与延期风控》

本人本身不太喜欢方法论,感觉都是套路,生搬硬套不适合自己,敏捷开发就是其中让我保持谨慎态度的方法论之一。

敏捷开发与Scrum

对于一个项目来说,能够即快又好地完成当然是非常棒的,但是众所周知,受限于项目管理三要素:时间、质量、成本,只能折衷选择。因此「敏捷」作为一种方法论(虽然Agile自称为Culture)被提出,其中Scrum(/skrʌm/,一种球类比赛)是比较知名的实现类之一。

在Scum中,它主要强调将瀑布式开发流程转为多阶段小迭代,可以理解为CPU的多级流水线(Instruction pipeline)设计,流水线设计将CPU的计算逻辑拆分,实现了复用计算模块,进而提高了时钟频率,同时也引入了寄存器/分支预测等管理模块增加了复杂度。

类似于CPU流水线机制,敏捷开发本质是在保持时间、质量不变的情况下,通过投入管理成本降低开发过程的空转成本,进而提高时钟周期的方法。

用白话来说,可以把软件开放比作流水车间,把PM,SE比作流水线工人。

我见过的的假敏捷

然而到了现实,由于各种原因,却很容易成为假敏捷

  • 将工位的隔栏拆开变成网吧“敏捷岛”
  • 强行将Release计划拆成一个月一版,将Sprint拆成2周就看作快速迭代,照着人月神话反着搞
  • 招聘一堆无责任心的开发让你去“敏捷”,永远无法实现“全功能部队”
  • 客户难沟通,PO低估工作量,SE设计缺陷,编码质量低等原因,最终导致延期
    上述任何一个问题,都可能导致最终项目一锅粥,导致高层焦虑,中层跑路,底层混日子的结果。

敏捷能够提供强大高效的方法论,但是前提是需要本身基础过硬的团队,敏捷只能帮助存在进步瓶颈的团队。如果项目已经空心化,债务多,这不是敏捷方法论应该解决的问题。

代码外的生存之道-读书笔记-职业篇

职业发展的驱动力应该来自自身,工作属于公司,职业生涯属于自己。

第一要务 拥有正确的心态

大多数人形成的错误的心态: 认为在为公司打工,没有把自己的职业生涯当作生意来看待。铭记在心,开始积极主动的管理自己的职业生涯吧。

像企业一样思考

自己能提供什么:自己的能力就是创造软件
自己需要做什么:

  • 持续不断地改进和完善自己的产品

  • 传达自己的价值,和千万同行的独特之处

一头扎进工作不可能非同凡响,你应该:

  • 专注于你正在提供怎样的服务, 以及如何营销这项服务;
  • 想方设 提升你的服务;
  • 思考你可以专注为哪一 特定类型的客户或行业提供特定的服务;
  • 集中精力成为一位专家,专门为某一特定类型的客户提供专业的整体服务( 记住, 作为一个软件开发 人员, 你 只有真正专注 于一类客户,才能找到非常好的工作)。
  • 更好的宣传自己的产品,更好的找到你的客户

第二要务 设定自己的目标

无论因为何种原因你没有为自己的职业生涯设定目标, 现在都是时候设定目标了。 不是明天, 也不是下周, 就是现在。 没有明确的方向, 你走的每一步都是徒劳的。

如何设定目标?

先在心中树立一个大目标,然后分解成多个小目标

追踪你的目标

定期核对自己的目标,必要时还要调整。

人际交往能力

构建大型支付系统时分布式架构的关键点

SLA

在构建大型系统时,常常会遇到各种错误。在计划构建一个系统时,定义系统的“健康状态”十分重要。

“健康状态”必须是可度量的,一般做法是使用SLAs来度量系统的“健康状态”。最常见的SLA为

  • 可达性

    从时间维度衡量(99.999%可达性,每年下线50分钟)

  • 准确性

    对于数据的丢失或失真是否可以接受?可以达到多少百分比?对于支付系统来说,不接受任何数据的丢失和失真

  • 容量

    系统支持并发

  • 延迟

    响应延迟,一般衡量95%请求的响应时间和99%请求响应时间

确保新系统比被替代系统“更好”,可以使用上面四个SLA指标来衡量,可达性是最重要的需求。

水平和垂直伸缩

随着新业务的增长,负载也会增加。最常见的伸缩策略是垂直和水平伸缩。

水平伸缩就是增加更多的机器或节点,对于分布式系统来说水平伸缩是最常有的方式。

垂直伸缩基本上就是买更大/好的机器。

一致性

可达性对于任何系统都是很重要的,但是分布式系统一般都构建在低可达性的机器上(比如:服务的可达性要求99.999% 机器的可达性为99.9%)。简单的做法是维护一组机器组成集群,这样服务的可达性不依赖单独的机器。

一致性是在高可用系统中最需要关心的。一个一致性系统在所有的节点上看到和返回的数据在同一时间是相同的。如果使用一组机器来组成集群,它们还需要互相发送消息来保持同步,但是发送消息可能失败,这样一些节点就会因为不一致而不可达。

一致性有多个模型,在分布式系统最常用的是强一致性,弱一致性和最终一致性。一般来说,一致性要求越低,系统可以工作的更快,但是返回的数据不一定是最新的。

系统中的数据需要是一致的,但是到底是怎样的一致?对于一些系统,需要强一致性,比如一次支付必须是强一致的存储下来。对于没那么重要的部分,最终一致性是可以考虑的权衡。比如列出最近的交易。

数据持久性

持久性表示一旦数据成功添加到数据存储,它就永远可以访问到。不同的分布式数据库拥有不同级别的数据持久性。一般使用副本来增加数据持久性。

对于支付系统来说,数据不允许丢失。我们构建的分布式数据存储需要支持集群级别的数据持久型。目前Cassandra, MongoDB, HDFS和Dynamodb 都支持多种级别的数据持久性。

消息保持与持久性

分布式系统中的节点执行计算,存储数据,互相发送消息。发送消息的关键是消息的可靠到达。对于关键系统,经常需要消息零丢失。

对于分布式系统,发送消息一般石油分布式消息服务发送,如RabbitMQ,Kafka。这些消息服务支持不同级别的消息投递可靠性。

消息保持表示当节点处理消息失败时,在错误被解决前消息一直被保持着。消息的持久性一般在消息队列层被使用。如果在消息发送的时候队列或节点下线了,那在它们重新上线是还能接收到消息。

在支付系统中我们需要每一条消息投递一次,在构建系统中保证投递一次和投递至少一次在实现上是有区别的。最后我们使用了kafka来保证投递至少一次。

幂等性

在分布式系统中,很多东西都可能出错,连接会丢包或超时,客户端经常会重试这些请求。一个幂等的系统保证无论多少特定的请求被执行,一个请求实际的操作只会执行一次。比如支付请求,如果客户端请求支付并且请求已经成功,但是客户端超时了,客户端是能够重试相同的请求的。对于一个幂等的系统,一个个人的支付是不能被收取两次的。

对幂等的设计,分布式系统需要某种分布式锁机制。假设我们想要使用乐观锁来实现幂等性,这时系统需要强一致性的锁来执行操作,我们可以使用同一个版本的乐观锁来检查是否有启动了额外的操作。

根据系统的一致性和操作的类型,有很多方式来实现幂等性。在设计分布式系统时,幂等性时最容易忽略的。在支付系统中,幂等操作时最重要的,它避免了双花和双收问题。消息系统已经保证了消息至少消费一次,我们只需要保证所有重复的消息保证幂等性即可。我们选择使用乐观锁,并使用强一致性存储作为乐观锁的数据源。

分片和法定人数

分布式系统经常需要存储大量的数据,远超一台节点的容量。一般的解决方案时使用分片,数据使用某种hash算法被水平分区。尽管很多分布式数据库屏蔽了分片的实现,但是分片还是挺有意思的,特别是关于重新分片。

许多分布式系统在多个拥有数据和统计信息。为保证对数据操作的一致性,使用基于投票的方式是不行的,只有超过一定数量的节点操作成功,这个操作才是成功的,这个叫做法定人数。

Actor模型

描述分布式系统最普遍的做法是使用Actor模型,还有一种方法是CSP。

Actor模型基于actor互相发送消息并作出回应。每一个actor只能做少量的动作,创建其他actors, 发送消息或者决定如何处理下个消息。通过这些简单的规则,复杂的分布式系统可以被准确描述,可以在actor崩溃后自我修复。

使用akka提供了标准的分布式模型,避免我们重复造轮子。

反应式架构

当构建大型分布式系统时,目标常常是它们的弹性,伸缩性,和扩展性。反应式架构是在这个领域最流行和最通用的方案。

《重构-改善既有代码设计》读书笔记

1.1 一个简单的例子

一个计算顾客租赁影片费用的程序,能容易写成面条式的代码(流水账):顾客类调用影片类和租赁时长计算费用

对机器来言只要能运行正确没有好代码和坏代码之分,但是对(维护的)人来说很难找到修改点,容易引入bug

1.2重构前先写测试保证重构结果

利用单元测试保证重构正确性

1.3以微小的步伐修改程序,保证问题快速发现解决

不要为修改变量名感到羞耻,只有写出人能理解的代码才是好程序员

重构完可能 性能变差,但同时会带来更多的机会来优化

1.4干货-用多态代替switch

switch需要关心具体条件,多态具有switch不具备的优势:不需要关心具体类型

2.1重构的定义

重构:不改变运行结果下 提高理解性 降低修改成本

2.2重构的原因

  • 代码结构的流失是累积性的,越难看懂代码设计意图,越难保护其设计

  • 消除重复代码,方便修改

  • 我们编写代码时很容易忘记读者的感受,造成他人时间的浪费

  • 重构时犯错可以加深对代码意图的理解,可以帮助发现bug

  • 好的结构设计是加速开发的根本

2.3重构的时机

  • 添加功能时重构,在修改过程中把结构理清,也可以更简单的添加功能

  • 修复错误时重构

  • 复审代码时重构

2.4 重构的价值

程序有两面价值,今天可以为你做什么和明天可以为你做什么为了满足明天的需要,你会遇到:

  • 难以阅读,逻辑重复
  • 添加新功能许修改以前代码
  • 复杂的条件逻辑等代码

而你希望看到的是:

  • 容易阅读,所有逻辑在唯一指定地点,
  • 新的修改不会危及现有行为
  • 尽可能简单表达逻辑条件

重构就是把程序转变为这些特征的工具

2.5如何告诉(对付)经理

很多经理都是进度驱动,所以更加需要重构带来的好处,所以不要告诉他们 他们不会理解的

2.5.1引入间接层与重构的关系

间接层优点:

  • 允许逻辑共享

  • 增加解释意图和实现的机会-多了类名和函数名

  • 隔离变化

  • 多态封装条件逻辑

2.5.2何时不应该重构

  • 软件根本不工作
  • 最后期限已近

未完成的重构可以称之为债务,迟早要还

2.5.3重构与预先设计的关系

重构可以节约不必要的时间精力花在预先设计上,让软件设计向简化发展

3代码的坏味道

  • 重复代码

  • 过长函数

  • 过大类,过长参数

  • 修改一处程序的原因过多/一个原因修改过多的程序

  • 数据依赖过多

  • 重复的字段和参数

  • 总是放在一起的字段

  • switch语句

  • 平行继承关系

  • 不是所有分支下都需要的临时变量

  • 过度耦合调用链

  • 不必要的委托

  • 失血数据类

  • 频繁重写父类方法

  • 过多注释

4~12具体如何做

自己看书吧

2018下半年书单

经济金融类:

《斯坦福极简经济学》分微观和宏观经济学 没有教科书式的介绍 比较好读,推荐

《随机漫步的傻瓜》 经验之谈 观点可以接受

《买晾衣杆的小贩为何不会倒》 贴近生活 过于简单 不推荐

《富爸爸 穷爸爸》小白入门首选 推荐

《小岛经济学》 深入浅出 最后映射中国和美国关系 后面有点看不懂 推荐

小说类:

《解忧杂货店》 个人感觉一般 后半部分剧情我都猜到了

《人间失格》 遭受到了社会的毒打 很现实 有点致郁 心里承受能力低的不推荐

《三体》 第一部可以的,后面一部不如一部 但是比起其他网上大众喜欢的爽文好多了

技术类:

《java编程的逻辑》 温故而知新,基础好的不用看了 小白推荐

《kafka权威指南》正在看 但是真的写的不错 推荐

《mybatis从入门到精通》 一般般,只有入门吧

《netty权威指南》 一般般

《redis设计与实现》 真设计与实现 推荐

《深入理解java虚拟机》多读几遍也不为过 推荐

《SpringBoot实战》 读的比较早没影响了 不推荐

《算法图解》 程序=数据结构+算法 小白推荐(我就是小白)

心理类:

《乌合之众》 人在小范围为私利行动 在民族范畴会抛开私利做出些过于崇高或粗鲁的行为 推荐

《原生家庭》 一个人受童年家庭的影响是最大的,这本书能看懂是一回事,能做好是另一回事

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×