-
思考不完整
- 逻辑上下文更新慢, 逻辑修改太多次后, 出现混乱, 失忆
- 缺少完整的体系参考, 遗漏一些方面的思考
- 疲劳, 思维变懒
-
个人防御墙
由于情绪, 偏见引起的和他人的对立面, 导致无意义的争执
思考与说话
沟通交流时说话不经过思考, 容易说出一些不恰当的话.
先思考, 将要说的话过一遍, 再说出来, 这样又觉得思维速度跟不上说话速度, 容易出现卡顿.
说话时, 先产生一个念头, 是自己需要表达给对方的一个思想. 需要在说出之前整理, 过滤, 确认符合情理逻辑, 再说出口.
有时候我们能很流畅的和别人交流, 是因为我们知道对方在想什么, 接下来会发生什么, 应该说些什么.
所以我们需要整理思考什么呢?
- 人物
对方正在做什么
对方的背景, 知识面等
对方需要什么信息 - 情境
身处的环境
我的立场 - 上下文逻辑
已经表达过什么信息
我们需要掌握这些情况, 防止自己说完出洋相.
在还没掌握这些情况之前, 要么聆听, 要么提问获取信息之后再表达.
气场
有气场的人一般有什么共同点?
-
理性
沟通过程中非常冷静, 没有幅度太大的的情感波动和肢体语言, 说话匀速, 眼神坚定.
通常都是微笑表达友善, 说话有条理, 思考过程中也是看着对方, 目光不会偏移到别处. -
自信
有成功的经验和信念支撑, 不会轻易让对方知道自己的短处.
即使嘴上说的丧气的话, 表情和肢体语言上却没有太大变化, 似乎一切都在掌控范围内.
自信源于自己成功处理过某些问题, 那么再遇到类似问题的时候就有底气. 如果一直把问题放在那里不处理, 在没有解决前与人谈及相关问题时, 就会有心虚的表现. -
有阅历
似乎一切事情对方都能说出几分道理. -
仪态
着装看上去给人干净整洁, 舒适随和感.
站坐姿态大方得体.
redis-faq
1. Redis 是单线程的, 为什么快?
- 单线程没有线程上下文切换问题, 没有资源竞争
- 采用IO多路复用的方式并发处理任务
- 纯内存操作, 没有磁盘IO限制
- CPU 不是 Redis 的使用瓶颈, 一般内存和网络带宽才可能是.
2. Redis 和其他 key-value 存储有什么不同
- 所有命令都是原子性操作
- 数据结构多样, 且对使用者透明
- 运行在内存中, 可以持久化到磁盘
3. Redis 数据结构有哪些?
- string
- hash 表, H开头的命令
- list
- set
- zset 有序集合
4. Redis 慢怎么办?
延迟- 查看慢日志
1
2
3
4config set slowlog-log-slower-than 0 # 设置慢日志门槛, 到过这个值就会记录到慢日志中, 单位微秒
config set slowlog-man-len 100 # 存储的慢日志数量
slowlog show - 检查最大内存策略导致
对大对象进行删除, 过期和淘汰操作 (由于最大内存策略导致) 都属于阻塞操作
如果经常对大对象进行删除, 过期和淘汰操作, 可尝试把大对象拆分成多个小对象.1
config get maxmemory-policy
5. Redis 分布式锁
- 加锁
SET $resource_id $token EX $expired_time NX
resource_id: 锁名称, 用于标识资源的唯一ID
token: 随机值, 如果锁需要重入, 或者手动释放锁, 这个值必须保持一致.
expired_time: 锁自动过期时间
- 解锁
不使用 DEL 命令来释放锁, 而是发送一个 Lua 脚本, 这个脚本只在客户端传入的值和键的口令串相匹配时, 才对键进行删除.
比较 token 是否一致, 如果一致则可以解锁, 如果不一致, 说明锁已经被其他客户端获取了, 不能再操作.
1 | if redis.call("get",KEYS[1]) == ARGV[1] |
这个脚本可以通过 EVAL ...script... 1 resource_id token 命令来调用.
6. 常见问题
6.1. 缓存穿透
缓存穿透是指查询一定不存在的数据, 由于缓存没有命中时需要查询数据库, 查不到数据则不写入缓存, 这将导致这个不存在的数据每次请求都需要去数据库查询, 造成缓存穿透.
解决办法:
- 对所有可能查询的参数以hash形式存储, 在控制层先进行校验, 不符合则丢弃.
- 采用布隆过滤器, 将所有可能存在的数据哈希到一个足够大的bitmap中, 一个一定不存在的数据会被这个bitmap拦截掉, 从而避免了对底层存储系统的查询压力.
- 也可以采用一个更为简单粗暴的方法, 如果一个查询返回的数据为空 (不管是数 据不存在, 还是系统故障) , 我们仍然把这个空结果进行缓存, 但它的过期时间会很短, 最长不超过五分钟.
6.2. 缓存雪崩
如果缓存集中在一段时间内失效, 发生大量的缓存穿透, 所有的查询都落在数据库上, 造成了缓存雪崩.
这个没有完美解决办法, 但可以分析用户行为, 尽量让失效时间点均匀分布.大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线程 (进程) 写, 从而避免失效时大量的并发请求落到底层存储系统上.
解决办法:
- 在并发量不高的情况下, 可以使用加锁排队, 但是这样会影响系统吞吐量.
- 提前更新过期时间, 如果发现缓存即将失效, 则重新reload, 当然需要控制reload的数量
- 不同的key, 设置不同的过期时间, 让缓存失效的时间点尽量均匀
6.3. 缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据 (一般是缓存时间到期) , 这时由于并发用户特别多, 同时读缓存没读到数据, 又同时去数据库去取数据, 引起数据库压力瞬间增大, 造成过大压力
- 设置热点数据永远不过期.
- 查询时加互斥锁, 保证同一时间只有一个线程区查询; 没有获取到锁的线程则轮询等待获取数据
6.4. 缓存一致性
场景: 在分布式系统中, 有一个频繁更新的数据要做缓存, 该怎么处理?
方案: 先更新数据库, 之后直接淘汰内存. 那么其他线程查询缓存时, 发现没有命中, 则通过查询数据库获取并缓存结果.
- 使用直接淘汰, 而不是更新缓存, 是为了防止高并发下更新缓存的顺序问题; 而如果要保证更新的顺序性, 需要有更新数据的版本, data + version 同时更新, 会有原子性的问题.
- 查询数据库需要考虑缓存击穿问题. 通过分布式锁保证只有一个线程去查询, 其他线程自旋等待.
- 如果要考虑数据更新完后, 还没来得及淘汰缓存, 就服务崩溃的问题. 也就是说不能等到下次更新数据时更新缓存. 那么这种依赖事务的数据不要放在缓存中. 如果要保证缓存一致性, 需要保证业务能幂等重试.
6.5. 什么样的数据能放在缓存中
- 业务完全依赖缓存中的数据, 如果缓存中没有数据则无法工作, 或者能够通过查询数据库恢复的数据.
- 缓存数据不一致不会影响业务.
7. Resource
pagecache
1. pagecache
页高速缓存, 简称页高缓.
pagecache 是通过将磁盘中的数据缓存到内存中, 从而减少磁盘I/O操作, 从而提高性能.
1.1. pagecache 的管理
linux 通过 radix tree 和两个双向链表管理 pagecache.
radix tree 是一种搜索树, 用于快速查找脏的 (dirty) 或回写的 (writeback) 页面.
active_list 和 inactive_list 两个双向链表, 用于回收 pagecache.
active_list 中的 page 被认为是 hot, 内存回收时不能释放; 之后在 inactive_list 中的 page 才可以回收.
首次缓存数据的 page 会被加入到 inactive_list 中, 已经在 inactive_list 中的 page 再次访问就会移入 active_list 中.
这两个链表都使用了伪 LRU 算法, 从尾部加入, 从头部移除.
如果 active_list 中 page 数量远远大于 inactive_list, 那么 active_list 头部的就会被移入 inactive_list 中, 从而维持两个链表的平衡.
1.2. 读
当内核发起一个读请求时, 首先检查请求的数据是否在 pagecache 中, 如果没有命中 (cache miss), 则从磁盘中读取数据, 并缓存起来, 之后读相同文件的请求就能命中 (cache hit) 了.
pagecache 可以只缓存文件的部分内容, 不需要把整个文件都缓存起来.
1.3. 写
pagecache 缓存的存储设备称为后备存储 (backing store);
当内核发起一个写请求, 会直接往 page 中写入, 后备存储中的内容不会直接更新. 内核会将被写入的 page 标记为 dirty, 之后内核会周期性的写回到磁盘上.
2. Resource
Linux内核学习笔记 (八) Page Cache与Page回写java-faq
1. 如何在不改变代码的情况下, 改变类中方法的行为?
- 组合, 继承, 模板方法
如果开发时就能知道有这样的需求, 就可以通过这些方法实现可扩展的类
- 动态代理
通过 AOP 技术, 在运行期间动态代理对象
- ClassLoader
- 利用 ClassLoader 加载顺序的特性, 让别的实现类在原来的类加载前加载
- 加载时, 让他指向别的实现类
- Instrumentation
JTI 的 Instrumentation, 通过独立于程序的 agent, 修改和替换类的实现
很有道理的句子
Good judgment comes from experience, and experience comes from bad judgment
正确的判断来自于丰富的经验, 而大多数经验又来自于错误的判断.
自控力
如何从被游戏支配中解脱? 如果救治拖延症?
-
先要离开当前状态, 比如冥想, 运动, 让自己独处
然后脑中思考现在有什么事情要做, 怎么做, 定制一个计划
有了明确的目标和计划之后就能摆脱那些负面的状态了 -
重复的事情做多了就没有成就感, 变成了固定任务. 那由于人性的懒惰, 就开始变动逃避这些固定任务.
jcmd
jcmd
jstack
jstack