依依成长日记201808

依依本月1周零6个月

20180811~0812

第一次带依依去海边,唐山乐亭。
依依很害怕海浪声,爸爸抱着她走近海浪,她就像猴子一样往上爬,抱紧紧的。沙滩都不敢下去。
海边碰到个比依依小几天的小朋友,跟爸爸一起做在浅水里玩,一点都不害怕,因为更小的时候就带过去游泳。
第二天早上,又带依依去了海边,依依愿意下来,牵着爸爸的手,在退潮的沙滩上走了。

20180820

淘宝买的百香果上午到货了,依依看见快递都要拆开看看。
拆开了泡沫箱,发现是百香果。依依和爸妈依依爱吃酸的,看见是百香果就一直说“要!要!要!”。
奶奶不知道是什么东西,跟依依说不知道怎么吃。
依依拉着奶奶去厨房,到放勺筷的地方,重复着“勺子,勺子。”
奶奶终于反应过来了,百香果要切开用勺子吃。奶奶说依依这么小就这么懂事了。

20180822

晚上吃完饭,带依依去水龙头洗脚,依依看见洗漱台上的一排东西。
指着洗面奶,说“妈妈”。然后用双手做轻拍脸颊的洗脸动作,萌萌的。
指着牙刷,说“姐姐”。然后做上下刷牙动作。
她是在告诉爸爸,这些东西都是谁的,用来做什么。
依依对周围的事物都很感兴趣,看见什么都会有样学样。

用Google的Jib构建springboot项目docker镜像

Jib

Jib 是google开源的用于对java项目进行容器化打包的工具。主要特点:

Whereas traditionally a Java application is built as a single image layer with the application JAR, Jib’s build strategy separates the Java application into multiple layers for more granular incremental builds. When you change your code, only your changes are rebuilt, not your entire application. These layers, by default, are layered on top of a distroless base image. For more information, check out the official blog post or watch this talk (slides).

传统的java项目打包方式,是将整个java应用相关的资源打包到一个层(layer)。Jib的构建策略是,将java应用的相关资源拆分成多个层(比如:依赖的jar和构建生成的class分层),这样rebuild的时候可以更快,因为可能只需要重新生成部分层的内容。

配置

Jib提供了maven和gradle插件,本文主要介绍 jib-maven-plugin 的使用方法。
将以下内容复制到maven项目的pom.xml中:

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>0.9.8</version>
<configuration>
<from>
<image>openjdk:8-jre-alpine</image>
</from>
<to>
<image>lf/${project.artifactId}:${project.version}</image>
</to>
</configuration>
</plugin>

说明:

  • from.image 指定使用的带java环境的基础镜像
    • 如上的配置是到registry.hub.docker.com下载,这里选择openjdk8的jre-alpine作为基础镜像
    • 未指定时默认值 gcr.io/distroless/java,这个是在google的服务器上,一般人连不上
    • 如果有内部的registry服务或mirror,可以这样指定:{registry-host}:5000/library/openjdk:8-jre-alpine
  • to.image 指定你要生成的镜像tag,镜像名称是 lf/${project.artifactId}
    • 可以去除”${project.version}”,这样版本默认就是latest

如果from.image使用的registry服务不支持https,需要修改配置如下(使用内部registry mirror服务):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>0.9.8</version>
<configuration>
<!-- 允许使用http与registry连接 -->
<allowInsecureRegistries>true</allowInsecureRegistries>
<from>
<image>172.16.14.73:5000/library/openjdk:8-jre-alpine</image>
</from>
<to>
<image>lf/${project.artifactId}</image>
</to>
</configuration>
</plugin>

构建

生成镜像tar

配置好之后,打开shell窗口,执行如下命令即可自动构建生成镜像的tar文件

1
mvn compile jib:buildTar

镜像tar默认生成路径:target\jib-image.tar

自动构建镜像到本地docker

如果你本地装有docker环境,且daemon已启动,那么执行如下命令,可自动将镜像构建到本地的docker daemon

1
mvn compile jib:dockerBuild

注意:docker命令路径需要配置到系统的path目录,否则Jib会找不到

构建镜像并上传registry

如果想构建镜像后自动上传到registry,可以执行如下命令:

1
mvn compile jib:build

由于to.image未指定registry服务器地址,默认将上传到registry.hub.docker.com。

为了上传到内部的registry,需要在to.image上指定registry服务地址,如果服务开启了权限验证,还需要配置上有push权限的账号密码。以下以使用docker官方的registry镜像搭建的服务为例,配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<allowInsecureRegistries>true</allowInsecureRegistries>
<from>
<image>172.16.14.73:5000/library/openjdk:8-jre-alpine</image>
</from>
<!-- 修改的配置 -->
<to>
<image>{registry.mydomain.com}:5000/lf/${project.artifactId}</image>
<auth>
<username>{my_username}</username>
<password>{my_password}</password>
</auth>
</to>
</configuration>
</plugin>

在maven package时自动构建镜像

增加配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<!-- 增加的配置 -->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>dockerBuild</goal>
</goals>
</execution>
</executions>
<!-- 之前的配置 -->
<configuration>
......
</configuration>
</plugin>

配置好之后,执行如下命令就会自动构建镜像到本地docker

1
mvn package

配置容器参数

jvm参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<jvmFlags>
<jvmFlag>-Xms512m</jvmFlag>
<jvmFlag>-Xmx1024m</jvmFlag>
<jvmFlag>-XX:+UseParNewGC</jvmFlag>
<jvmFlag>-XX:+UseConcMarkSweepGC</jvmFlag>
<jvmFlag>-XX:+DisableExplicitGC</jvmFlag>
<jvmFlag>-Xdebug</jvmFlag>
</jvmFlags>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

java程序入口mainClass

Jib默认会自动扫描寻找main class,如果你的项目中有多个main class,就需要显示声明:

1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<mainClass>mypackage.MyApp</mainClass>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

容器端口 EXPOSE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<ports>
<port>6565</port>
<port>8080</port>
</ports>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

镜像创建时间

Jib默认不设置镜像创建时间,这样就是1970-01-01。如果要镜像创建时间,则增加配置如下

1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<useCurrentTimestamp>true</useCurrentTimestamp>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

镜像格式

构建的镜像默认是Docker格式,还可以指定为OCI格式

1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<format>OCI</format>
</container>
<!-- 之前的配置 -->
......
</configuration>
</plugin>

依依成长日记201807

依依本月1周零5个月

20180708

下午带依依去长楹天街,和hh家的孩子一起玩。
4点半出发去大运河森林公园,在公园里依依第一次坐了儿童过山小火车,和妈妈一起坐的,没有哭,很淡定,下来了还想玩。
游乐园里有家长在吹泡泡,依依追着泡泡,爸爸教她:“泡泡,泡泡。抱住”。
依依追着到处飞的泡泡,叫着:“泡泡。泡泡。”
妈妈也买了一个肥皂泡玩具,爸爸一会吹大泡泡,一会大量的小泡泡,依依甩着小腿,追着泡泡跑来跑去,想要抓住,却一碰就破了。然后又去追逐下一个泡泡。
第一次玩泡泡,玩的好开心。

20180714

依依现在睡醒后,就会开始崩词练说话。
今天周六,早上依依醒了后就跟着妈妈说:
爸爸、妈妈、奶奶、爷爷、肉肉(youyou)、饺子、甲壳虫(jiakeqiong)、当当(小猫当当)等等

20170715

今天带依依去了杜仲公园,地方太小,绕了一圈就回家了,闷热的天气,晒黑了我的宝。
下午妈妈肚子突然开始肚子疼,不知道是不是中午吃了什么坏肚子了。
爸爸跟依依说:“妈妈肚子疼,痛痛,快帮妈妈拍拍”
妈妈侧躺着,依依不知道肚子在哪里,就拍着妈妈的背、腰、屁股,哪能拍着拍哪。
然后爸爸教了下肚子在哪里,依依跟着拍了几下,自己趴妈妈肚子上了。

20180716

今天依依又不老实,对奶奶又抓又挠。
奶奶不高兴了,对依依说:“奶奶生气了,不理你了”。然后转过头去故意不看她。
依依观察了一会,发现奶奶真的不理她了,然后就大声的喊:“奶奶!奶奶!”
然后还对着奶奶玩躲猫猫(用双手蒙住眼睛,然后放开),玩了几次之后,奶奶忍不住笑了。
晚上妈妈回来时,奶奶跟妈妈描述这个事情,依依听了还在边上做躲猫猫的动作。

如何用ab对webservice进行性能测试

模拟发送ws(webservice)请求

ws协议是http上的xml,所以发送ws请求,http请求体内必须是ws格式的xml。

使用工具 wizdl - Web Service GUI Test Tool,可以比较方便的生成你的ws应用的请求xml。

红框标识出来的部分就是发送的ws请求xml,把这段xml保存到一个xml文件中(wstest.xml)。

用curl验证ws的请求xml

为了验证我们生成的ws请求xml是否有效正确,可以使用curl来测试。

curl --data @wstest.xml http://172.16.24.215:81/example/ws/demoService?wsdl | xmllint --format -

说明:

  • 把ws的xml作为HTTP POST的请求数据:–data DATA HTTP POST data (H)
  • xmllint 命令对curl返回的xml进行格式化

使用ab进行ws性能测试

ab的帮助


相关的ab参数已经用红框标出,我们需要把wstest.xml直接作为HTTP的数据:

ab -n 100000 -c 20 -k -p wstest.xml -T "application/x-www-form-urlencoded" -m POST http://172.16.24.215:81/example/ws/demoService?wsdl
参数说明:

  • ‘-n 100000’ 发送10万次请求
  • ‘-c 20’ 使用20个并发(20个用户,绝对并发)
  • ‘-k’ 启用keep-alive
  • ‘-p wstest.xml’ 把wstest.xml文件的内容作为HTTP POST的数据
  • ‘-T’ 设置POST数据的Content-type
  • ‘-m POST’ 使用POST方法

ab测试结果

PS:测试的demoService方法里边执行了sleep(5)。

git处理文件换行符

[TOC]

有时我们会遇到跨平台开发的情况,在windows上开发同时支持linux和windows部署的程序。
那么我们的程序中可能就会有平台相关的一些文件,比如shell脚本(bat、sh)。
如果没有正确处理好这些文件的换行符,将会导致脚本文件在对应的平台上不能正确执行。

对于使用Git管理源码的项目,git对text文件有自动转换换行符的机制,相关的配置有:

  • git config core.autocrlf
  • git config core.safecrlf
  • git config core eol
  • .gitattributes

windows和linux换行符的区别

  • 在linux系统中,行尾使用一个换行符(LF=line feed)表示
  • 在windows系统中,行尾使用回车(CR=carriage return)+换行(LF=line feed)2个字符表示

git config core.autocrlf

可选的配置值有:

  • true 提交文件时自动转换为LF,检出文件时自动转换为CRLF。在windows平台上,这个是git的默认设置。
  • input 提交的时候自动转换为LF,检出文件时不做转换。
  • false 提交和检出的时候都不对换行符进行自动转换。提交时文件时什么样,服务器上就是什么样。
    1
    2
    3
    4
    5
    6
    7
    core.autocrlf=true:    core.autocrlf=input:      core.autocrlf=false:

    repo repo repo
    ^ V ^ V ^ V
    / \ / \ / \
    crlf->lf lf->crlf crlf->lf \ / \
    / \ / \ / \

因为 core.autocrlf 在windows平台上默认是true,所以检出的时候sh文件将自动转换成CRLF换行符。
如果在windows平台上打包安装程序,那么安装后的程序sh文件将不能正常执行。

git config core.safecrlf

由于git有自动转换换行符的机制,如果设置了autocrlf,那么文件的换行符可能被统一处理。
例如: 对于混合了CRLF和LF的文件,都被统一成LF提交服务器了。

这种就是git处理转换后不可逆的情况:在同个机器上,提交后再检出,不能还原出一样的文件。
如果git错误的将binary文件判断为text文件,自动进行了CRLF转换,那么就会损坏文件数据。

通过开启 safecrlf 选项,可以防止出现上述错误:

  • true 如果git根据配置的CRLF转换自动处理文件,将导致文件不可逆,那么git将拒绝提交文件。
  • warn 如果git根据配置的CRLF转换自动处理文件,将导致文件不可逆,那么git将显示警告信息但继续处理文件。
  • false 关闭检查。

开启该选项不会改变git的CRLF转换处理,但通过该选项,可以保证提交的text文件里不会出现混合LF、CRLF的情况。

git config core.eol

当autocrlf=false时,通过.gitattributes配置了text属性的文件,其换行符将使用本配置值。
可选的值有:cr,crlf,native(使用本地操作系统匹配的换行符)

.gitattributes

在项目的git根路径下,添加.gitattributes文件并纳入git管理,然后打开编辑内容:

1
2
3
4
5
6
7
8
9
10
11
*.bat eol=crlf
*.sh eol=lf

*.jpg -text
*.png -text
*.pdf -text

*.exe -text
*.so -text

*.txt text=auto

说明:

  • bat 文件在检入检出时,使用CRLF换行符
  • sh 文件在检入检出时,使用LF换行符
  • ‘-text’ 的意思是,标记该类型的文件不是text。git对这类文件会跳“是否text文件”的检测,也不会自动转换换行符。
  • ‘text=auto’ 的意思是,标记该类型的文件是text,同时使用core.eol配置的换行符(如果有配置的话)。
  • 优先级: autocrlf > text=auto + core.eol

对于明确是二进制数据的文件,可以在本文件中显示的声明非text,防止git检测有误时错误的对文件进行处理而损坏数据。

总结

通过git config进行配置,只能在对所有的文件进行统一处理,不能分文件类型处理。
而且仅对各客户端有效,不能保证在不同开发人员那保持一致。
所以最好在项目根路径下添加.gitatttibutes文件,对关键的文件类型分别统一配置CRLF转换,也可避免不同客户端环境不同的影响。

参考

TProfiler使用总结

TProfiler是阿里开源的一个java性能分析工具,实现原理和部署配置可看wiki

关于TProfiler中的以下几个关键配置,官方wiki描述的不是很清楚:

  • startProfTime = 9:00:00 开始profile的时间点
  • endProfTime = 11:00:00 结束profile的时间点
  • eachProfUseTime = 5 profile时间长度(单位秒)
  • eachProfIntervalTime = 50 两次profile的时间间隔(单位秒)

TProfiler对函数调用情况的采样调度是在类 com.taobao.profile.thread.DataDumpThread 中实现的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void run() {
try {
while (true) {
if (Manager.instance().canDump()) {
Manager.instance().setProfileFlag(true); // 疯炎疯语#1: 打开采样开关
TimeUnit.SECONDS.sleep(eachProfUseTime); // 疯炎疯炎#2: 采样期间,记录函数调用情况
Manager.instance().setProfileFlag(false);
// 等待已开始的End方法执行完成
TimeUnit.MILLISECONDS.sleep(500L); // 疯炎疯语#3: 简单的等待已经Start的函数End返回

dumpProfileData();
}
TimeUnit.SECONDS.sleep(eachProfIntervalTime);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
Manager.instance().setProfileFlag(false);
if (fileWriter != null) {
fileWriter.closeFile();
}
// 等待已开始的End方法执行完成
try {
TimeUnit.MILLISECONDS.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
Profiler.clearData();
}
}

TProfiler从startProfTime开始第一次函数调用情况采样(打开采样开关),此时被关注的函数调用时就会被记录执行信息,
经过eachProfUseTime时间后,采样开关会被关闭(采样停止)。
在采样停止后,线程会等待500毫秒的时间,然后再将采样到的数据输出到文件中,并重置程序中的相关状态。

函数调用情况的采样由类 com.taobao.profile.Profiler 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
com.taobao.profile.Profiler

/**
* 方法开始时调用,采集开始时间
*
* @param methodId
*/
public static void Start(int methodId) {
if (!Manager.instance().canProfile()) {
return;
}
... // 记录采样数据
}

/**
* 方法退出时调用,采集结束时间
*
* @param methodId
*/
public static void End(int methodId) {
if (!Manager.instance().canProfile()) {
return;
}
... // 记录采样数据
}

只有函数执行完之后触发了上边的End调用后,采样的数据才有可能会被输出。
如果一个函数时间执行过长,以致于在采样停止后500毫秒内还没有返回,那么这个函数的调用将无法被记录。
例如:函数执行的时间超过 “eachProfUseTime+500”。

所以,如果你设置的eachProfUseTime时间过短,那么你将无法通过TProfiler来发现执行时间超过这个时间的慢函数,
也就是无法通过TProfiler来发现这样存在严重性能问题的函数。

因此,设置eachProfUseTime时需要估计你的程序中函数可能执行的最慢时间是多少,然后设置一个比这个数稍大的时间。
但是,因为每次eachProfUseTime期间记录的采样信息是在本次采样结束时才输出到文件中的,
如果设置的eachProUseTime过长的话,那么TProfiler对内存的使用会上升,这还取决于采样函数执行的频率高低。

虽然TProfiler存在这样的问题,不过在系统访问压力的不大的情况下(例如在功能测试而非性能测试的时候),
也可以用来分析程序中哪些函数调用的频率比较高,或者平均调用时间比较长,从而做出针对性的调优。

至于 eachProfIntervalTime 则控制了2次采样之间的时间间隔,把这个数调大可以降低对应用程序的性能影响,
但是过大的话则采样数据可能不准。

招商银行个人信用贷2013

听闻招行有无抵押个人信用贷款政策,想到几个关键问题:

  1. 贷款方式:一次性放款?还是授信?
  2. 借贷期限
  3. 还款方式:分期还款?还是到期连本带息一次性还款?
  4. 是否可提前还款?提前还款利息如何计算?
  5. 若逾期有何后果?是否会催贷?
  6. 资金用途是否有限制?

通过电话咨询招行的个人信贷部,得到以下答复:

  • 授信方式:根据个人的信用评估结果确定授信额度,授信期限2年。
  • 最长1年的还款期,还款方式根据对个人的评估结果决定。
  • 逾期还款会影响个人信用记录。
  • 借贷利率:年化10%(北京,2013年11月)。
  • 个人信用贷属于 消费类贷款,只能用于个人消费用途
    (包括用于购车、装修、教育学资、大宗消费购物、旅游等,不能用于购房)。
    所以每次使用贷款时仍需要带上用途证明。
  • 若要用于投资或经商则必须有公司(应是 小企业信用贷)。

贷款逾期的处理应该跟其他贷款一样:催贷、起诉、走法律程序查封债务人资产。

招商银行官网:信用贷款

  • 信用方式 无须提供抵押、无须担保。
  • 放款快速 材料简单,手续便捷,随时申请,随时使用。
  • 免担保、免抵押!为高端人士专属定制,根据良好的信用记录和稳定的经济收入,为您提供充裕贷款,各种消费用途,随心选择!
  • 金额:最高300万元
  • 期限:最长2年

您需要准备的贷款申请资料:

  1. 身份证、婚姻证明
  2. 房产证
  3. 住址证明【至少任选其一】:水、电、气、电话或物管等费用账单
  4. 收入证明【至少任选其一】:工资证明/银行流水/所得税税单/社保记录/其他收入证明
  5. 用途证明:提供相应的交易证明材料

新海诚

新海诚电影台词记录而已

1、电影《言语之庭》

片中有2句台词很美:

  • 片首,女主角:”隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。”
  • 片尾,男主角:“隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。”

这两句出自《万叶集》雷神短歌。

第一句是女生的角度,第二句是男生的角度。就是希望对方留下来,对方也有这样的心意的意思。

2、电影《秒速5厘米》

即使我们交换了上千条短信,我们的心也只有可能仅接近1厘米左右而已。

读书笔记:Practices of an Agile Developer - Working in the Real World

《高效程序员的45个习惯 – 敏捷开发修炼之道》

英文原书名 《Practices of an Agile Developer : Working in the Real World》

“选定了要走的路,就是选定了它通往的目的地。”

Harry Emerson Fosdick (美国基督教现代主义神学家)

“即使你已经在正确的轨道上,但如果只是停止不前,也仍然会被淘汰出局。”

Will Rogers (美国著名演员)

“百言不如一行,千虑不如一动”

1、态度决定一切

将注意力集中在处理做事上。
处理问题时要对事不对人:否定他人无助于事;尊重他人,提出疑虑并进行讨论。

2、唯一不变的就是变化

“唯有变化是永恒的”

赫拉克利特

3、把握开发节奏

随意安排的工作计划,没有任何规律,让人根本不知道明天会发生什么。

控制时间,保持开发节奏,是为了避免问题堆积,防止所有事情同时发生。

4、让设计指导而不是操纵开发

当前阶段的设计只是基于你目前对需求的理解,一旦开始编码,一切都会改变。

设计可以分2个层面:战略与战术。
前期的设计属于战略,通常只有在没有深入理解需求的时候需要这样的设计。
它应该只描述总体的战略,不应该深入到具体的细节。

“如果你自己都不清楚所谈论的东西,就根本不可能精确的描述它。”

约翰.冯.诺依曼

一个故事
在1804年,Lewis和Clark进行了横穿美国的壮举,他们的“设计”就是穿越蛮荒。
但是,他们不知道在穿越殖民地时会遇到什么样的问题。他们只知道自己的目标和约束条件,但是不知道旅途的细节。
软件项目的设计也与此类似。在没有穿越殖民地的时候,你不可能知道会出现什么情况。
所以,不要事先浪费时间规划如何徒步穿越河流,只有当你走到河岸边的时候,才能真正评估和规划如何穿越。
只有到那时,你才开始真正的战术设计。

“好的设计应该是正确的,而不是精确的。”

“计划是没有价值的,但计划的过程是必不可少的。”

艾森豪威尔(美国总统)

5、使用短迭代,增量发布

软件开发不是精细的制造业,而是创新活动。规划几年之后客户才能真正使用的项目,注定是行不通的。

软件在被开发出来之前是不确定的,在开发过程总是存在着变化,
短迭代可以防止在错误的道路上走的太远,这样可以及时发现错误并进行纠正。

短迭代让人感觉非常专注且具效率。你能看到一个实际并且确切的目标。
严格的最终期限迫使你做出一些艰难的决策,没有遗留下长期悬而未决的问题。

如果每个迭代的时间不够用,要么是任务太大,要么是迭代的时间太短。

6、敏捷协作:定期安排会面时间

也许你个人很讨厌开会,但是沟通是项目成功的关键

立会:站着开的会议。这可以保证会议快速进行,大部分人不喜欢站着进行长时间的谈话。

定期例会的好处:

  • 让团队成员知道项目其他部分的进展。
  • 帮助团队识别是否在某些事情上进行了重复劳动。
  • 鼓励向前的动力:看到比尔报告的进度都在前进,会对彼此形成激励。

7、敏捷协作:架构师必须写代码

一个设计要解决的是眼前面临的特定问题,随着设计的实现,对问题的理解也会发生改变。

设计会随着时间而演进

8、敏捷协作:及时通报进展与问题

接受一个任务,也就意味着做出了要准时交付的承诺。
不过,遇到各种问题而导致延迟,这种情况并不少见。
如果等到截止时间才发布坏消息,这就等于是为经理和技术主管提供了对你进行微观管理的机会。
他们会担心你再次让他们失望,并开始每天多次检查你的工作进度。

及时通报进展与问题,有情况发生时,就不会让别人感到突然,并且他们也很愿意了解目前的进展状况。
他们会知道何时应提供帮助,而且你也获得了他们的信任。

读书笔记:《杀戮的艰难》

《杀戮的艰难》

作者: [中国台湾] 张娟芬

主要讲述了作者在参与台湾民间的“废除死刑”的社会运动中关于的一些感悟与见解。
文中提出废除死刑的论据主要有以下几点:

  1. 死刑对于死刑犯自身没有教育意义,一了百了的刑罚不能让罪犯认识到自己的罪过。
    作者寄望通过刑罚让罪犯悔悟,这样的做法有点宗教意味。
    如果罪犯能够悔悟当然好,不过这不应该作为刑罚的目的。
  2. 台湾存在司法不公,有罪推定的盛行容易导致司法误判,无辜者受刑。
  3. 台湾司法亦有不完善之处,刑事被告人的辩护权利没有得到完全的保障。
  4. 检察官和法官也是人,也会犯错。而死刑没有纠错的机会。
  5. 废除死刑不是要为死刑犯逃脱惩罚。死罪可免,活罪难逃。
    废除死刑可以倒逼司法改革,例如当前徒刑最高刑期过短(同大陆,有期最高二十年),
    罪犯出狱后仍有可能对社会造成危害的问题。

全书通过许多故事试图向读者说明,许多死刑犯并不是十恶不赦之人,大多数悲剧之后都有着各种不幸的故事。
有些人罪不致死,只是因为死刑之下的刑罚相对罪犯的罪过来说又太轻,达不到罪刑相适的效果,所以法官选择了判处死刑。
刑罚设计的不合理,部分是由于政府为了节约社会的刑罚成本(延长刑期会增加社会的刑罚成本),导致刑罚出现了断档。

一提到死刑,普罗大众脑海中浮现的都是一个个冷血无情、毫无人性、杀人不眨眼恶魔,废除死刑就是给这些人减轻刑罚。
事实上却是,有些刑法上规定的死刑情形并不完全是罪无可恕的。
比如有社会底层的民众,辛苦打工却被黑心老板欠薪不给,还被暴力殴打,以致绝望杀人(请Google:夏俊峰案)。

废除死刑的最终目的是为了推动司法改革,使得刑罚更加的人性化。
司法的人性化,只是让罪犯能够像一个人一样被对待,而不是说让罪犯能够得到优待。

纵观全书,能够感受到作者作为社会运动一分子的狂热,不过对于死刑问题的思考还是偏于感性,理性的思辨不足。

书中讲述 死刑犯邓武功的故事(第1章:思考/第二节:绕着死刑走一圈/第六小节:等死人–邓武功)
给了我一些别样的感悟:

  • 男人可以为女人牺牲时间,牺牲金钱,但绝不能牺牲事业。没有了事业的男人终将不幸。
  • 全职太太容易胡思乱想。聪明的女人不应该当全职太太,应保留自己的相对独立性。成为职业女性才能保持自信。

文中有句话说的很有意思:“节妇失足,半生坚真(应为:贞)无助;妓女从良,一生烟花无碍”。
这句话的矛盾之处,在于将理性和感性两种做法比较。
有人犯了错,惩罚TA以警戒后人勿要向恶,这是理性做法;宽容感化TA,以劝世人迷途知返,这是感性做法。
理性与感性本就是矛盾的存在,想在二者之间求得平衡是很难的。

另外,一个人对你的好与坏在天枰上该怎么进行称量?
这真的很难,相信每个人心里的那杆秤都是不同的。