0%

说明

线程池通过对任务及执行线程的管理,复用资源。

主要包括:1. 任务队列; 2. 工作线程调度

常见问题

  1. 线程泄露

    a) 由于线程执行错误导致线程池中线程意外终止,耗尽线程池。ThreadPool中已经对此情况进行了处理。( 延申: 怎么处理的)

    b) 由于一些阻塞的任务,比如读取外部数据等,没有恰当的超时机制,导致线程池中工作线程均在等待,无法执行任务。

    c) 死锁,活锁等

  2. 饱和策略

  3. 队列不受限导致溢出

说明

主动对象将方法调用与方法执行进行解构,与该方法有关的上下文信息均会封装成一个对象,由另外的线程或调度管理来控制执行。

类图

ClientProxyasyncService( Object ) : FutureSchedulerdispatch()enqueue( methodReq : MethodRequest)ActivationQueueenqueue( methodReq : MethodRequest )dequeue () : MethodRequestMethodRequestcall()ServantdoSomething()Futurecreatecreatecall

说明

通过返回包含阻塞方法的凭据对象,使得调用方法无需等待即可继续执行,待需要结果时,通过调用凭据对象的阻塞方法获取结果。

类图

ClientPromisorPromise compute()TaskExecutorrun()ResultPromiseResult getResult()setResult( Result )isDone()

Sequence Diagram

ClientClientPromisorPromisorPromisePromise1 : computer()2 : <<create>>4 : getResult()

说明

将线程停止拆分成准备阶段及执行阶段两个步骤。

  1. 准备阶段

    通知相应线程需要停止,在线程池的场景,一般包括设置停止标志,调用可中断线程的interrupt方法,关闭等待IO操作的Socket等

  2. 停止

    检查准备阶段设置的停止信号,决定线程停止时机,进行适当清理等。

Java ThreadPoolExecutor就使用了此类模式来停止其维护的线程。

不可变对象及其作用

通过使用不可变对象表征对象状态,避免访问状态时的同步需求。

所谓状态不可变,并非指现实世界的实体状态不可变,而是我们建模时的一种决策,即可以用不可变状态表示某时刻的状态,事物状态变化可以用替换为其他不可变对象表示。

Immutable Object 类图

ClientManipulatorvoid changeStatusTo(int x, int y)ImmutableStatefinal int xfinal int yint getXint getYImmutableState( int x, int y)ImmutalbeState

Sequence Diagram

ClientClientImmutableStateImmutableStateManulatorManulatornew ImmutableStategetStateXStateXgetStateYStateYchangeStatecreatenew ImmutableStategetState()

动机

一般git rebase在过去项目中很少用到,最近阅读了如下blog, Git Rebase ,很赞同作者说的“提交历史质量与代码质量同等重要” ,因此在囫囵吞枣式地阅读了一下后,有了如下笔记。

Rebase的适用情形

  • Edit/rework a commit in the history
  • 修订提交历史
  • Add a commit into the history of a change set (or branch)
  • 增加一个改变集合或分支的提交到历史
  • Remove a commit from the history of a change set (or branch)
  • 删除一个改变集合或分支的提交到历史
  • Split a commit into several commits
  • 拆分一个提交到若干各提交
  • Combine a series of commits into one commit
  • 合并一系列提交为一个单独提交
  • Re-order commits
  • 重新排序提交

用于合并本地若干次提交

将本地近三次提交合并,可以通过rebase -i 进入交互式编辑

1
git rebase -i HEAD~3

之后,在文本编辑界面中,将看到最近几次提交的记录,类似

1
2
3
pick 09i3foe comments
pick jeo32jo comments
pick je323jo comments

此时,可以通过改变pick命令来完成多次提交的合并。相关指令说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue Rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.

显然,可以通过将第一个保留为pick,将其他的改为squash或者fixup来完成多条提交合并。

Guarded Suspension 保护性暂挂

当持有锁时,如果条件不满足,暂时挂起执行线程,等待条件满足时再次唤醒,判断条件后,执行操作。

伪代码

1
2
3
4
5
6
7
8
9
10
Lock lock = new Lock();
Conditon condition = lock.newCondition()
...
lock.lock();
while ( conditon not satisfied ) {
conditon.await()
}
doOperation();
lock.unLock()

Sequence Diagram

内部逻辑,图参考自<<Java多线程编程实战指南(设计模式篇)>> 黄文海 著

ClientClientGuardedObjectGuardedObjectGuardedActionGuardedActionBlockerBlockerPredicatePredicateConditionCondition1 : guardedMethod()2 : <<create>>3 : callWithGuard()getGuard()5: predicateloop[SuspendIfNecessary]6 : evaluate()7 : isPredicateTrue8 : await()9 :call()10 : actionReturnValue11 : actionReturnValue

简介

以下是读<<代码之殇>>的关于Bug提交的笔记,作为常识,应该是牢记于心的。Bug提交是一种确保软件质量的沟通手段,因此,信息的准确传达尤为重要。

Bug报告的定义

所有Bug报告,应该有如下要求

项目 说明
标题 要简略
指派 由谁来处理问题
重现步骤 问题再次出现的相关步骤。可采用图表、视频等。
优先级别 问题的紧迫程度与重要性,级别不应过多,准则应该简单,易区分,易记忆。一般可以定义 0-4 级,优先级依次降低。
严重程度 问题所产生的后果
解决方案 怎么解决问题

Bug 优先级

比如,可以定义如下优先级

级别 描述 修复时间点
Pri 0 一个需引起关注的致命错误,不存在变通方法,是一个不可逾越的bug 只有解决了问题,找到变通方法,才能安心。
Pri 1 一个需要引起严重关注的致命错误 必须在当前冲刺阶段解决
Pri 2 一个严重的错误 必须在产品发布前解决
Pri 3 一般性错误或者建议 最好在产品发布前解决

Bug 严重程度

严重程度一般指影响范围。注意,严重程度和优先级是相互独立的。

比如,可以定义如下

级别 描述
1 引起系统崩溃或者用户数据丢失
2 引起故障,阻断了后续操作
3 引起操作不便或界面显示不完整

Bug 解决方案

对于解决Bug的说明。除了具体方案细节,一般也会用如下关键字进行归类,比如 已修复,无法重现,不修复,延期之类。

当一个Bug被解决,将会自行指派给发现它的人,如果解决方案不令人满意,则有可能再次被激活。

简介

在使用Docker玩mysql 8.0时,发现默认的character collation变成了不认识的utf8mb4_0900_ai_ci,对相应问题做了一点搜索,记录如下。

说明

utf8mb4_0900_ai_ci为例,它是一个若干有意义的字段合并的collation名称。分解如下:

  • uft8mb4 指使用UTF-8字符集,每个字符最多使用4 byte来存储。
  • 0900 指Unicode字符校对算法版本。Unicode字符校对算法(Unicode Collation Algorithm) 是用来按照Unicode标准比较两个字符串的算法。
  • ai 指重音符号(Accent)不敏感,比如 e, è, é, ê and ë 在排序时均认为是同一字符。与其相对的是as
  • ci 指大小写(Case)不敏感。排序时a和A不做区分。与其相对的是 as

其他还有language identifer以及_bin标识,可以参考如下网站

Collation Naming Conventions

New Colllations in Mysql 8

展示所有Collation

1
SHOW COLLATION

如何确定当前表的Collation?

可以查询information_schema表

1
2
3
4
5
SELECT 
table_schema,
table_name,
table_collation
FROM information_schema.tables