拉巴力的纸皮箱

技术博客 | 记录学习笔记和思考


  • 首页

  • Notes

  • 标签

  • 归档

  • 关于

  • 搜索

单元测试使用总结

发表于 2020-11-11

mockito使用

mock实例

  • Test test = mock(Test.class);
  • Test test = spy(new Test());

在Spring中使用

  • @Mock Test test;
  • @Spy Test test = new Test();
  • @MockBean Test test; (起spring容器时)
  • @InjectMocks Test test; (起mockito容器时的测试对象)
  • Spring boot使用@MockBean和@SpyBean来定义Mockito的mock和spy。
  • 使用@mockBean,未mock的方法可能会导致返回默认值,从而导致异常的逻辑造成脏数据(可能是代码本来不完善);可以注意尽量@SpyBean

mock使用

  • when().thenReturn()模式 和 doReturn().when()模式
    两种模式都用于模拟对象方法,在mock实例下使用时,基本上是没有差别的。但是,在spy实例下使用时,when().thenReturn()模式会执行原方法,而doReturn().when()模式不会执行原方法。

  • when(test.do(anyString())).thenReturn(true);

  • 返回值为void: doAnswer((Answer<Void>)invocation -> null).when(test).do(anyString(),anyLong(),anyString());

  • 抛异常:doThrow(new RuntimeException("error")).when(test).do(anyLong(), anyString());

  • doReturn(expected).when(spyList).get(100); (使用spy时)
    - org.mockito.Mockito.doReturn; 注意不要导入powermock的包
    - doReturn().when()模式: 用于模拟对象方法,直接返回期望的值、异常、应答,或调用真实的方法,无需执行原始方法

  • 直接调用真实方法:Mockito.doCallRealMethod().when(userService).getUser(userId);, Mockito.when(userService.getUser(userId)).thenCallRealMethod();

  • 模拟可空参数方法: Mockito.doReturn(user).when(userDAO).queryCompany(Mockito.anyLong(), Mockito.nullable(Long.class));

  • 匹配null对象,可以使用isNull方法,或使用eq(null):Mockito.doReturn(user).when(userDAO).queryCompany(Mockito.anyLong(), Mockito.isNull());, Mockito.when(userDAO.queryCompany(Mockito.anyLong(), Mockito.eq(null))).thenReturn(user);

  • 模拟final方法: PowerMock提供对final方法的模拟,方法跟模拟普通方法一样。但是,需要把对应的模拟类添加到@PrepareForTest注解中。

  • 模拟私有方法: PowerMock提供提对私有方法的模拟,但是需要把私有方法所在的类放在@PrepareForTest注解中。

    1
    2
    3
    4
    5
    PowerMockito.when(userService, "isSuperUser", userId).thenReturn(!expected);
    //通过模拟方法stub(存根),也可以实现模拟私有方法。但是,只能模拟整个方法的返回值,而不能模拟指定参数的返回值。
    PowerMockito.stub(PowerMockito.method(UserService.class, "isSuperUser", Long.class)).toReturn(!expected);
    Method method = PowerMockito.method(UserService.class, "isSuperUser", Long.class);
    Object actual = method.invoke(userService, userId);
  • 模拟构造方法: PowerMock提供PowerMockito.whenNew方法来模拟构造方法,但是需要把使用构造方法的类放在@PrepareForTest注解中。

    1
    2
    PowerMockito.whenNew(MockClass.class).withNoArguments().thenReturn(expectedObject);
    PowerMockito.whenNew(MockClass.class).withArguments(someArgs).thenReturn(expectedObject);
  • 调用无访问权限的构造方法: 调用无访问权限的构造方法,可以使用PowerMock提供的Whitebox.invokeConstructor方法。

  • 调用无权限访问的普通方法: 调用无访问权限的普通方法,可以使用PowerMock提供的Whitebox.invokeMethod方法。

  • 附加匹配器
    Mockito的AdditionalMatchers类提供了一些很少使用的参数匹配器,我们可以进行参数大于(gt)、小于(lt)、大于等于(geq)、小于等于(leq)等比较操作,也可以进行参数与(and)、或(or)、非(not)等逻辑计算等。
    PowerMockito.when(mockList.get(AdditionalMatchers.geq(0))).thenReturn(expected);

  • Whitebox.setInternalState方法
    现在使用PowerMock进行单元测试时,可以采用Whitebox.setInternalState方法设置私有属性值: Whitebox.setInternalState(Foo.class, "FIELD_NAME", "value");

mock静态方法

  • 返回值为void: PowerMockito.doNothing().when(FileUtils.class, "writeStringToFile", any(File.class), anyString());
  • BDDMockito.given(FileUtils.readFileToString(eq(new File(file)))).willReturn(IOUtils.toString(getClass().getClassLoader().getResourceAsStream("test.json")));
  • 前置初始化:
    1
    2
    3
    4
    5
    6
    7
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({FileUtils.class})
    @Before
    {
    MockitoAnnotations.initMocks(this)
    PowerMockito.mockStatic(FileUtils.class);
    }

设置静态常量字段值

  • 有时候,我们需要对静态常量对象进行模拟,然后去验证是否执行了对应分支下的方法。比如:需要模拟Lombok的@Slf4j生成的log静态常量。但是,Whitebox.setInternalState方法和@InjectMocks注解并不支持设置静态常量,需要自己实现一个设置静态常量的方法:
1
2
3
4
5
6
7
public final class FieldHelper {
public static void setStaticFinalField(Class clazz, String fieldName, Object fieldValue) throws NoSuchFieldException, IllegalAccessException {
Field field = clazz.getDeclaredField(fieldName);
FieldUtils.removeFinalModifier(field);
FieldUtils.writeStaticField(field, fieldValue, true);
}
}

使用Answer来生成期望的返回

1
2
3
4
5
6
7
8
9
10
11
12
13
when(test.do(anyList())).thenAnswer(
(Answer)invocation -> {
Object[] args = invocation.getArguments();
//Object mock = invocation.getMock();
return list.stream().filter(v -> ((List<Integer>)args[0]).contains(v.getAid())).collect(
Collectors.toList());
});
doReturn(resp).when(test).do(argThat(new ArgumentMatcher<List<Long>>() {
@Override
public boolean matches(Object argument) {
return ((List<Long>)argument).size() == 1;
}
}));

verify使用

  • 校验执行次数:Mockito提供vertify关键字来实现校验方法是否被调用,从未被调用never(),调用次数times(1), verify(test).do(any());
  • 验证私有方法
    PowerMockito.verifyPrivate(userService).invoke("isSuperUser", userId);
  • 验证方法调用并捕获参数值: Mockito提供ArgumentCaptor类来捕获参数值,通过调用forClass(Class clazz)方法来构建一个ArgumentCaptor对象,然后在验证方法调用时来捕获参数,最后获取到捕获的参数值并验证。如果一个方法有多个参数都要捕获并验证,那就需要创建多个ArgumentCaptor对象。
  • verify语句, 除times外,Mockito还支持atLeastOnce、atLeast、only、atMostOnce、atMost等次数验证器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

public class ListTest {
@Test
public void testAdd() {
List<Integer> mockedList = PowerMockito.mock(List.class);
PowerMockito.doReturn(true).when(mockedList).add(Mockito.anyInt());
mockedList.add(1);
mockedList.add(2);
mockedList.add(3);
InOrder inOrder = Mockito.inOrder(mockedList);
inOrder.verify(mockedList).add(1);
inOrder.verify(mockedList).add(2);
inOrder.verify(mockedList).add(3);
}
}
  • 验证调用参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

public class ListTest {
@Test
public void testArgumentCaptor() {
Integer[] expecteds = new Integer[] {1, 2, 3};
List<Integer> mockedList = PowerMockito.mock(List.class);
PowerMockito.doReturn(true).when(mockedList).add(Mockito.anyInt());
for (Integer expected : expecteds) {
mockedList.add(expected);
}
ArgumentCaptor<Integer> argumentCaptor = ArgumentCaptor.forClass(Integer.class);
Mockito.verify(mockedList, Mockito.times(3)).add(argumentCaptor.capture());
Integer[] actuals = argumentCaptor.getAllValues().toArray(new Integer[0]);
Assert.assertArrayEquals("返回值不相等", expecteds, actuals);
}
}
  • 确保验证完毕.
    Mockito提供Mockito.verifyNoMoreInteractions方法,在所有验证方法之后可以使用此方法,以确保所有调用都得到验证。如果模拟对象上存在任何未验证的调用
  • 验证静态方法。Mockito没有静态方法的验证方法,但是PowerMock提供这方面的支持。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RunWith(PowerMockRunner.class)
@PrepareForTest({StringUtils.class})
public class StringUtilsTest {
@Test
public void testVerifyStatic() {
PowerMockito.mockStatic(StringUtils.class);
String expected = "abc";
StringUtils.isEmpty(expected);
PowerMockito.verifyStatic(StringUtils.class);
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
StringUtils.isEmpty(argumentCaptor.capture());
Assert.assertEquals("参数不相等", argumentCaptor.getValue(), expected);
}
}

其他

  • ReflectionTestUtils.setField(config, "id", id);
  • Mockito.reset(test);
  • @VisibleForTesting
  • Mocking a method in the same test class using - Mockito:https://towardsdatascience.com/mocking-a-method-in-the-same-test-class-using-mockito-b8f997916109
1
2
3
4
5
6
7
8
9
10
11
12
13
public class PersonTest{

@Test
public void playTest() {
Person person = new Person("name", 15, "23435678V");

Person person1 = Mockito.spy(person);

Mockito.doReturn(true).when(person1).runInGround("ground");

Assert.assertEquals(true, person1.isPlay());
}
}

一般不建议在同个类mock自己的方法,如果一定要,可以使用spy

  • @Captor注解在字段级别创建参数捕获器。但是,在测试方法启动前,必须调用MockitoAnnotations.openMocks(this)进行初始化。
  • @PowerMockIgnore注解
    为了解决使用PowerMock后,提示ClassLoader错误。

异常测试

1
2
3
4
5
6
7
8
   @Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void test() {
thrown.expect(new BizExceptionCodeMatches(ExceptionCodeEnum.FAIL_CODE.code()));
//do
}
1
@Test(expected = IndexOutOfBoundsException.class)

异步测试

  • 异步系统的两种测试方法:https://mp.weixin.qq.com/s/ft7LDsLmJByxunPuqGUOuQ
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
31
32
33
34
public class ExampleTest {

private final Object lock = new Object();

@Before
public void init() {
new Thread(new Runnable() {
public void run() {
synchronized
(lock) {
//获得锁
monitorEvent();
//监听异步事件的到来
lock.notifyAll();
//事件到达,释放锁
}
}
}).start();
}

@Test
public void testAsynchronousMethod() {
callAsynchronousMethod();
//调用异步方法,需要较长一段时间才能执行完,并触发事件通知
/**
* 事件未到达时由于init已经获得了锁而阻塞,事件到达后因init中的锁释放而获得锁,
* 此时异步任务已执行完成,可以放心的执行断言验证结果了
*/
synchronized
(lock) {
assertTestResult();
}
}
}

基于Spock的数据驱动测试

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
class SpockTest  extends Specification{

// 初始化
def setupSpec() {
println ">>>>>> setupSpec"
}
def setup() {
println ">>>>>> setup"
}
def cleanup() {
println ">>>>>> cleanup"
}
def cleanupSpec() {
println ">>>>>> cleanupSpec"
}

def void testAdd(int a, int b, int expect) {

expect:
assert expect == a + b

where:
a | b | expect
1 | 1 | 2
2 | 2 | 4
}

}

使用rest-assured进行接口层测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class RestAssuredMockMvcTest {

@Before
public void before(){
RestAssured.registerParser("text/plain", Parser.JSON);
}

///https://github.com/rest-assured/rest-assured/wiki/Usage#spring-mock-mvc-module
@Test
public void test(){

given().
standaloneSetup(new GreetingController()).
param("name", "Johan").
when().
get("/greeting").
then().
statusCode(200).
body("code", equalTo(0));
//body("data", equalTo("Hello, Johan!"));
}
}

事务测试

  • TODO

其他

  • 单元测试的运行速度重要吗?
    违背这个原则的典型反例,就是在单测中启动 Spring。
  • 数据驱动测试(Data Driven Test)
  • mockito只能用于纯逻辑的验证,涉及事务那些还是没办法。单个类的单元测试逻辑正确不代表逻辑就覆盖全了,所以针对重要的接口需要单独集成测试用例
  • ContiPerf:: 更为优雅和方便的单元压力测试工具。

扩展

  • [JDK11下Mock框架进化:从PowerMockito到Mockito Only]https://mp.weixin.qq.com/s/OsySrzocrMmJdk6C0_h60A

Reference

  • https://www.baeldung.com/mockito-void-methods
  • https://stackoverflow.com/questions/2276271/how-to-make-mock-to-void-methods-with-mockito
  • https://github.com/eugenp/tutorials/tree/master/testing-modules/mockito
  • </https://stackoverflow.com/questions/9585323/how-do-i-mock-a-static-method-that-returns-void-with-powermock>
  • https://www.cnblogs.com/Ming8006/p/6297333.html#c2.9
  • https://www.baeldung.com/mockito-annotations
  • https://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/
  • https://github.com/eugenp/tutorials/tree/master/testing-modules/mockito
  • https://github.com/rest-assured/rest-assured/wiki/Usage#spring-mock-mvc-module
  • 单元测试,只是测试吗?
  • 单元测试难?来试试这些套路
  • Spock单元测试框架以及在美团优选的实践
  • [阿里开源的 Mock 工具:TestableMock]
  • 收藏!Java编程技巧之单元测试用例编写流程 – 这个很全了。。。
  • https://stackoverflow.com/questions/30890011/whats-the-difference-between-mockito-matchers-isa-any-eq-and-same
  • https://stackoverflow.com/questions/24295197/is-there-mockito-eq-matcher-for-varargs-array
  • https://stackoverflow.com/questions/5385161/powermock-testing-set-static-field-of-class
  • Java单元测试技巧之PowerMock:

  • 转:分享一个观点:区分集成测试和单元测试的最本质差别在于,单元测试没有不可控外部依赖,也就是不会因为外部的原因导致测试失败。其它差别都不是能有效区分单元测试和集成测试的。

《我的第一本金融入门书》-笔记

发表于 2020-11-03

银行的生财之道——存款与贷款

  • 银行的存款不可能全部贷放出去,按照法律规定,银行必须要留存一定比例的存款作为应对储户提款的准备金,并且贷款在很多时候存在不能及时收回的情况,甚至会出现坏账,这会对银行造成损失,此外,这笔钱还没有扣除税收等因素

货币创造的秘密——商业银行的派生存款

  • 我们时常听到财经新闻报道说,中央银行上调法定存款准备金率0.5个百分点,冻结了约3000万元的银行存款货币。在我国,这是当市场流动性泛滥、通货膨胀严重的时候政府所采用的紧缩货币供给的手段。银行存款也是货币,并且银行账户上的存款数量远远大于现金,那么这些多出来的没有现金支撑的存款货币是怎么创造出来的呢?为什么法定存款准备金率的上调就能冻结那么多的存款货币呢?
  • 我们知道,现在人们使用的货币都是信用货币,而信用货币最早的形式是商业银行的银行券。后来,银行券的发行逐渐集中到了一国的中央银行。也就是说,现在人们手中的所有现金货币都是由中央银行发出来的,而商业银行能够创造的只是存款货币。存款货币的创造与银行以支票存款为依据组织的转账结算有直接的联系。一般来说,人们把现金存入银行之后,并不一定再把现金全数提出;从银行取得贷款的客户通常也并不要求银行支付现金,而是要求把贷款记在自己的存款账户中。当客户的存款账户上存有款项时,既可以在必要的时候提取现金,又可以开出支票履行支付义务;当一位客户取得支票时,他往往也不是到付款银行提取现金,而是委托自己开有存款账户的往来银行代收并把收来的款项记入存款账户。对银行来说,客户开出支票,因此有应该付出的款项,同时客户交来支票委托收款,因此有应该收入的款项
  • 银行对现金货币的需要归结为两类:一是客户从存款中提取现金用于发放工资、小额零星支付等;二是结清支票结算中应收应付的差额。在长期经营中,银行发现,相对于存款,现金只是一小部分,而且两者的比例关系相对稳定。也就是说,只要按存款的一定百分比保持现金库存即可应对客户对于现金的需要。
  • 在这样的现代银行支付体系下,存款货币就产生出来,或者说是派生出来了。
  • 假如有一位客户甲,他持有10000元的现金,并将其存入开立了活期存款账户的A银行。从而,A银行负债业务中的存款一项就多了10000元。根据经验,保存相当于90%的现金就足以应对客户日常提取现金的需要,那么A银行可以把9000元贷出。假如这时候正好有一位客户乙要从A银行贷款9000元,那么此时A银行的资产账户上就多出来9000元的贷款,以及剩余的1000元用于应对取现的准备金,实际上,这1000元的准备金是按照法律要求要存到中央银行的账户上的。
  • 如果客户乙将这9000元的贷款用签发支票的方式支付给与自己有业务往来的客户丙,客户丙在B银行开立了账户,于是这9000元则由A银行转到了B银行,B银行的存款就多了9000元。同样的道理,B银行将这9000元中的10%留作准备金,将其余的90%(8100元)贷放出去。如果这时正好有客户丁要从B银行贷款8100元,那么B银行的资产账户就多出来8100元的贷款,同时B银行将900元的准备金上缴中央银行。
  • 以此类推,B银行的客户丁向C银行的客户戊用支票支付8100元的应付款,于是C银行就又多了8100元的存款,在这8100元中,90%用于C银行的贷款,10%用作准备金,无限地循环下去,最终我们可以得到一个总的存款数量和准备金数量。
  • 将A、B、C……银行的存款数量相加,得到10000+9000+8100+7290+…=100000(元),准备金数量为1000+900+810+729+…=10000(元),从中我们可以看出最初的10000元原始存款最终变成了100000元派生存款,扩大了10倍。经过简单归纳,我们发现这个倍数正好是准备金率的倒数,也就是1/10%=10。
  • 至此,我们就明白了商业银行派生货币的秘密,在银行之间的非现金转账制度和不完全准备金制度下,这样的存款货币派生机制就是有效的。在这一制度下,某单位的现金经过多次存款转账支付,可以创造出(1/准备金率)倍的存款。我们也能够回答中央银行调整存款准备金率对存款货币数量影响巨大的原因了。假如存款准备金率由10%调整到20%,那么存款的最终创造数量就变为1/20%,扩大了5倍,即10000元的现金只能创造出50000元的存款,这个影响相当巨大。
  • 在非现金转账制度和不完全准备金制度的条件下,商业银行可以创造出数倍于现金数量的存款,而这个倍数就是存款准备金率的倒数。

利率是怎样调整的——固定利率与浮动利率

  • 根据在借贷期内利率是否会发生变化,我们又可以将利率分为固定利率和浮动利率。
  • 浮动利率是一种在借贷期内可定期调整的利率。
  • 浮动利率尽管可以为债权人减少损失,但也因手续复杂、计算依据多样而增加费用开支。因此,浮动利率多用于3年以上的国际金融市场的借贷。
  • 固定利率和浮动利率是利率的两种设置方式。采用固定利率可以使计算简单方便,而采用浮动利率可以使长期借贷行为更加公平。

为什么会有负利率——名义利率与实际利率

  • 实际利率是指物价水平不变,从而货币购买力保持不变条件下得到的利息率。
  • 为了避免通货膨胀的损失,假设仍然要取得3%的利息,那么粗略地计算,乙必须把贷款利率提高到8%,这样才能保证收回的本金和利息之和与以前的物价水平相当,并且保证购买力不变。其中,这个8%就是名义利率。从这个例子我们可以看出,名义利率是包括物价水平变化情况的利率,实际利率和名义利率之间的关系可以大致表示为:名义利率=实际利率+通货膨胀率。市场上各种利率都是名义利率,实际利率却不容易观察到。而利用上述公式,就可以根据已知的名义利率和通货膨胀率推出实际利率。例如考察我国现在的银行存款,1年期定期储蓄存款的利率是3.25%,这是名义利率。而2011年3月的消费物价指数为4.9%,这可以代替通货膨胀率,这样我们可以算出1年期储蓄存款的实际利率为-1.65%,也就是说,我们年初把钱存进银行,年末取出后按购买力计算还亏了1.65%。所以,有些人不愿意把钱存进银行,而是去炒股或者买房,因为一般认为股市和房市是可以实现保值的市场。
  • 实际利率是物价水平不变条件下的利率,而名义利率是包括了物价变化水平的利率,两者的关系为:名义利率=实际利率+通货膨胀率

没有风险的利率——基准利率

  • 生活中,我们经常听到所谓基准利率的说法,比如,在国内,老百姓习惯上把银行的1年期定期储蓄存款的利率作为基准利率;而银行从业人员则把银行间隔夜拆借利率作为基准利率;在国外,基准利率又成了中央银行的再贴现率。那么,到底什么是基准利率呢?顾名思义,基准利率是指在多种利率并存的条件下起决定作用的利率,也就是说这种利率发生了变动,其他利率也会相应变动。因此,了解了这种关键性的利率水平的变化趋势,也就可以了解全部利率体系的变化趋势

什么是有价证券的价值——票面价值、内在价值、市场价格

  • 票面价值也称面值,是在有价证券票面上标明的金额数值
  • 内在价值就是一种有价证券未来收益的现值,它是对有价证券进行价值评估的核心。
  • 对于债券,其本身并没有对应的实物资产。股票,有其对应的实物资产,但具有同样估值金额的实物资产绝不等于对应的股票有同等的内在价值。
  • 市场价格也称市值,它的形成是以其内在价值为准的
  • 票面价值、内在价值、市场价格是三个不同的概念。票面价值是标明在有价证券票面上的金额数量,内在价值是有价证券未来收益的现值,而市场价格是围绕有价证券内在价值上下波动而形成的。

怎样评估有价证券的价值——净现值

  • 现值发行的债券票面价格为1000元,每年按8%付息,即利息为80元,每年付息一次,10年还本。如果市场利率达到9%,那么这张债券的现值,或者说内在价值实际只有935元,如果这张债券的定价超过935元,则将不具有投资价值,如果定价低于935元,则可以买入。
  • 净现值是将有价证券未来可预期到的收益折现到当前所得到的金额再减去投资的成本。

一个简单的股票价值评价指标——市盈率

  • 所谓市盈率,就是股票的市场价格与每股盈利的比值。
  • 市盈率=每股市场价格/每股盈利
  • 如果市盈率太高,则可能意味着股票的价格高于价值,在这种情况下,投资者需要卖出手中的股票或不购买这种股票。如果市盈率太低,则可能意味着股票的价值被低估,此时正是投资的好时机
  • 从理论上来说,股票的市盈率愈低,愈值得投资
  • 只有比较同类股票的市盈率才会有实用价值
  • 市盈率的高低也不能作为投资选择的绝对标准。因为高市盈率还可能意味着股票的收益有很大的增长潜力,投资者对股票特别看好;低市盈率可能是因为股票未来的收益前景不好,投资人对股票不那么看好导致的。
  • 证券业监管部门也十分关注市盈率的高低。如果市场的平均市盈率太高,那么,政府可能得出市场泡沫过大的判断,然后采取一定的措施帮助消除泡沫。
  • 市盈率是判断股票价值的一种十分简便的方法,它的数值等于股票的市场价格与每股盈利的比值,含义是,每得到1元的收益需要付出多少元的投资。

实际收益的损失——通货膨胀风险

  • 通货膨胀风险也称为购买力风险。它是由于通货膨胀、货币贬值给投资者带来的实际收益下降的风险
  • 因为通货膨胀的增长,居民的收入或工资可能会出现上涨。大部分民众对通货膨胀不敏感,但是对自己的工资上涨很敏感。人们的收入增加,大多数的人会选择增加消费,这种现象就是货币幻觉
  • 股票的通货膨胀风险相对较小。
  • 当一国的股票市场完全瘫痪,不可以保证人们财富的安全时,人们就会放弃股票和本国货币,大量持有有信用的外币和黄金等贵金属。

购买金融资产就是投资吗——投资与投机

  • 交易者根据交易手段、交易结果、交易目的的不同应该被分成两类:投资者与投机者。
  • 拥有安全性、盈利性、研究性特征的是投资者,反之则是投机者。
  • 投资者深入分析金融资产的价值,他们寻找价值被低估的金融产品并长期持有以获得稳定的收入。投机者关注行情指标,他们购买金融资产的目的就是为了在短期内获得暴利。

行为金融学典型现象——羊群效应

  • 羊群效应是行为金融学的经典内容。羊群是一种比较散乱的动物组织,如果有一只羊躁动起来,那么其余的羊会跟随着这只羊一起躁动起来。羊群效应说的是一种从众心理。
  • 羊群效应的教训告诫我们,做任何事都要有自己的判断。总是跟着别人投资,也不会得到多大的收益
  • 投资者应该相信自己的判断,千万不要盲目跟风投资。

股票的生财之道——分红与价差

  • 股票的获利方式有两种,一种是通过股价的变动获利,另一种是通过股票的分红获利。
  • 在长期中获得合理的收益,而不是短期内的一夜暴富,这是我们股票的一个重要原则。
  • 只有坚定这一个原则,我们在投资股票时,才能够以一个平和的心态去面对股市带来的波动与股价的涨涨落落。

未来标准化的商品买卖——期货合约

  • 之前讲到远期合约的优势是规避未来的风险,其实远期合约也存在一些不足,那就是远期合约往往是买卖双方商议好就可以达成的一种合约,而如果第三方甚至其他各方想要介入这份合约或者买卖双方想要将合约中的金融产品卖给其他人的话,则会比较麻烦。比如双方规定好要交的货是一等大豆1000吨,但是第三方只想要200吨,或者第三方只想要二等大豆等,这样就不能转卖这个远期合约。为了避免这种麻烦,使交易更为顺畅地进行,人们又发明了标准化的远期合约,即期货合约。
  • 期货是现在进行买卖,但是在将来进行交收或交割的标的物,这个标的物可以是某种商品(如黄金、原油、农产品),也可以是金融工具,还可以是金融指标。
  • 期货实际上是一种可以反复转让、反复买卖的标准化合同。
  • 交易这些“将运到”合约比交易谷物本身要更为有用
  • 期货市场的两类关键参与人就是套期保值者与投机者。期货市场建立的目的是出于对保值的需要。
  • 所谓套期保值,就是以现在的价格卖出未来生产的产品,或是以现在的价格买入未来所需要的原料。
  • 套期保值者一般是产品的生产商或者是需要原料的加工商。他们进入期货市场购买或卖出期货合约的目的是为了避免未来的损失。举例来说,棉花生产商为了避免在棉花收获时因棉花丰收而引起的价格下跌中受到损失,在收获期前三个月就在期货市场卖出期货合约,或者做空该种类的期货。而到了棉花收获期,他们再买入期货合约,也就是进行平仓。由于期货合约越到履约期越接近现货价格,如果三个月后棉花价格下跌,那么棉花生产商便在期货市场盈利,从而弥补在现货市场的亏损;如果三个月后棉花价格上涨,那么棉花生产商便在现货市场盈利,从而弥补在期货市场的亏损,即将利润在三个月前就锁定。
  • 而投机者在期货交易中则是扮演着“价格发现者”的角色。投机者进入期货市场购买或卖出期货合约的目的只有一个——就是获利。因此,在期货市场中时刻关注价格的波动与走向,如果发现期货市场价格与现货市场价格出现偏离,那么就会毫不犹豫地利用价差进行套利交易。但是同时,他们的不断套利也使得期货市场与现货市场的价格不会出现扭曲。
  • 期货采用保证金制度,即只需要付部分货款就可以订购全部的商品
  • 期货市场更适合专业的投资者进行投资。
  • 中国有上海期货交易所、郑州商品交易所、大连商品交易所、中国金融期货交易所四大交易所
  • 期货合约是将要买卖的东西的单位、品质、样式等在合约中事先规定好,在规定的日期进行交割的一种远期合约。期货的出现有助于保障原材料供应商与需求商的利益不会因原材料价格波动而受损。期货交易中使用保证金制度,属于杠杆交易,风险较大。

金融政策的神奇魔力

  • 政府调节经济的目的是为了预防由于单纯依靠市场力量所出现的种种市场失灵的情况。无论是由于人们的盲目乐观而产生的经济泡沫,还是由于人们信心不足而出现的经济衰退,政府都可以通过运用金融政策使经济重回正轨

市场失灵的历史表现——1929年美国经济危机回顾

  • 经济学家凯恩斯认为经济危机的根源在于有效需求不足。
  • 劳动者工资率的上升却慢于劳动生产率的增长。其结果是,生产商品的能力大大超过了购买力,“消费不足”带来了“生产过剩”的必然后果。

金融政策魔力的源泉——货币、利率与汇率

  • 一个国家的宏观金融政策应主要包括三大政策:货币政策、利率政策和汇率政策。
  • 政府的目标是确保三个市场的均衡,即保证国内的商品市场的均衡、货币市场的均衡以及国际收支的均衡。
  • 对于商品市场的均衡,从总体上说,就是国内商品的总供给与总需求的均衡,让所供给的商品满足所产生的需求,这样一方面可以不出现供过于求的局面,不至于产生商品积压,引起通货紧缩,使得经济发展陷入停滞的局面;另一方面可以防范供不应求的局面,不至于出现需求旺盛而供给不足,产生物价上涨,人民的需求难以得到有效保障的困境。政府可以运用财政政策对市场加以调整。在货币市场的均衡方面,就是要使一国对于货币的需求等于货币的供给。就货币的需求而言,根据凯恩斯的理论,人们有三种倾向去持有货币,即预防动机、交易动机与投机动机。这三方面的因素使得人们对货币有相应的需求。而中央银行作为货币的发行机构,可以通过控制货币的供给引导货币市场的均衡。在国际收支方面,如果一国的出口大于进口,则会出现顺差局面,会对本国的货币产生升值压力,进而影响本国的出口行业,并同时容易造成输入型通货膨胀,对国内经济产生影响;而如果进口大于出口,则会产生贸易赤字,使得本国货币不断走弱,进而影响本国的国际购买力水平与经济发展前景。因此,政府应该通过有效的汇率政策等调控方式引导国际收支平衡。

是痛苦的根源还是繁荣的表象——通货膨胀

  • 如果通货膨胀保持在一个比较低的水平,那么就说明市场上对于各种产品的需求比较旺盛,至少是供不应求。这样的话,整个经济的流转就会比较顺畅,企业生产的产品不会因为卖不出去而滞销;企业可以继续生产,生产过程中也会雇佣一定的劳动者,因此也不会有人失业。劳动者有了工作,也就有了收入,有了收入,也就有了消费的基础。
  • 一般而言,国际上通常认为通货膨胀率(一般用消费者物价指数CPI进行衡量)在2%以下是可以接受的范围,而在3%以上就认为已存在问题。如果通货膨胀率高于5%,则认为存在着比较严重的问题。而通货膨胀率如果达到20%,就认为这个国家面临着经济崩溃的风险。
  • 通货膨胀是指一个经济体在一段时间内货币数量增速大于实物数量增速,普遍物价水平上涨,单位货币的购买力下降的状况。较低水平的通货膨胀反映经济的蓬勃发展,但较高水平的通货膨胀就是经济痛苦的根源

一个艰难的抉择——失业与通货膨胀的跷跷板

  • 失业率的存在是让人苦恼的,通货膨胀的爆发是让人忧愁的,西方一些学者甚至将两者的数值进行加总,创造出一个“痛苦指数”来反映人们对于现行经济状况的担忧。而更让一国政府与中央银行郁闷的是,往往他们通过相应的金融政策调整,在解决其中一个问题的时候,会引发另一个问题的产生。就如同跷跷板一样,压下了这一头,那一头又升了起来。
  • 事实正是如此,当中央银行通过宽松的货币政策甚至是降息对不景气的经济进行刺激以消除失业压力的同时,会引发投资的加速,使得原材料的成本大幅度提高,进而引发一般商品价格上涨,并促使工资上涨,形成成本推动的通货膨胀。相反,当中央银行通过提高利率或收紧货币为一个过热的经济体降温时,常常会让投资者犹豫不决,导致投资不足,进而使企业不能进行有效的扩大再生产,并开始裁员,导致失业人数增加。
  • 上述这种情况正好反映了金融政策制定者所处的两难境地。金融政策的调整既要保证老百姓不会因为物价的快速上涨而怨声载道,又要避免老百姓因找不到工作或失业而痛苦不堪。所以说,对一国政府与中央银行而言,如何让通货膨胀与失业的跷跷板在一个能够接受的范围内达到平衡,是一个十分艰难的抉择。小贴士根据经济学家的研究,一国的失业率与通货膨胀率常常存在着此消彼长的替代关系。这种现象使得政府在制定相应的宏观经济政策时常常面临着两难的抉择,往往只能就重避轻,而难以全部满足。

来自全球化的挑战——输入型通货膨胀与汇率变动的压力

  • 当今世界市场的发展使得各国的联系更为紧密,因此单单考虑本国的情况显然难以完全把握经济的命脉。因此,政府在进行相应的金融政策调整时,还要考虑外部因素,也就是考虑国际市场带来的压力。而这种压力也来自两个相对应的方面,或者说,来自汇率的两种调整方式的压力。一种方式是实行固定汇率制,也就是保持汇率稳定。保持汇率稳定可以预防经济的波动,但是相应地,由于本国货币的升值或贬值压力,一国的中央银行必须动用其外汇储备进行汇率干预以保持汇率的稳定,这就对一国的外汇储备状况提出了很高的要求。如果一个国家的货币有贬值压力,那么中央银行就需要不断地用本国的外汇储备换回本国货币以保持市场上对本国货币的需求,从而稳定本国汇率。这样做对本国的外汇储备是极大的消耗。而另一方面,如果本国货币有升值压力,那么中央银行必须不断地在国际市场中供给本国货币以换回外汇储备,这样做的话会使本国的外汇储备不断膨胀,而当外汇储备贬值时,就会造成本国外汇储备的巨大损失。另一种方式是实行浮动汇率制,是指政府允许市场作为调节汇率的手段,允许汇率进行波动。这样,政府就可以不动用外汇储备对汇率市场进行干预,使汇率可以较为自由地变动。然而,在这种方式下,汇率的波动会对经济产生很大的影响。如果本国货币升值,那么会使本国的相关出口行业面临着巨大的汇率压力,因为出口企业在国内用本国货币购买原材料、雇佣劳动力,而出口到国外的产品却是用外币进行结算,本国货币升值会造成产品的成本上升,对利润产生冲击。如果本国货币贬值,那么会引发进口产品的价格上升,进而形成输入型通货膨胀。也就是说,我们购买同样的国外原材料或产品时,需要付出更多的本国货币,就如同通货膨胀一样,同样的产品需要更多的钱才能买到,表现为进口原材料与商品的价格普遍提高,对于对外依赖度很高的国家,这将会严重干扰该国的经济生产过程。因此,无论采用哪种汇率制度,汇率的波动或者汇率的变化压力都会对经济造成一定的冲击。而对汇率的调节机构来说,制定相应的汇率政策是一个取舍的过程。汇率政策对一国汇率的影响可以分为三种,即有计划的升值、保持汇率不变以及有计划的贬值。有计划的升值可以防止输入型通货膨胀,使本国的进口商品、原材料价格趋于稳定,进而使一般商品价格不至于出现较大的波动,但是,这是以牺牲出口行业的利益为代价的。而有计划的贬值则恰恰相反,一国政府为了推动出口企业的快速发展,通过实施一定程度的货币贬值手段对外贸行业进行刺激,使外贸企业由于能够更为便宜的使用国内资源而获得一定的成本优势。但是,贬值手段所带来的可能后果是输入型通货膨胀的压力,会对本国的一般性生产行业造成一定的冲击,同时也会影响本国的一般商品价格。保持汇率稳定不变则如前文所述,会促使中央银行动用大量的外汇储备进行干预,这样会对一国的外汇储备造成一定的压力。

对魔法的质疑——金融政策是否是万能的

  • 金融政策在实行中往往存在着滞后性与信息不完全的问题。
  • 金融政策的调整不是立竿见影的,而是有一定的滞后性。这就对金融政策的制定者提出了较高的要求,需要他们对未来的趋势有明确的判断,不能为了解决短期的问题而影响长期的发展。
  • 经济的波动往往呈现出复苏—繁荣—衰退—萧条—再复苏的周期性特征,这是因为,在繁荣阶段,企业往往增加投资并且成本较高,形成泡沫,在随后的衰退期中很可能会遭受损失。如果金融政策的制定者能够把握这种经济周期规律,合理运用金融政策,那么就可以获得良好的效果
  • 逆周期政策就是一种金融调控的合理手段。简单地说,逆周期政策就如同开车一般,在经济向着繁荣方向发展时就踩下经济的刹车,而在经济向着衰退方向发展时就踩下经济的油门。具体而言,当经济进入复苏阶段,企业重新开始走上扩张道路时,政府不应继续通过宽松的金融政策对其进行刺激,而是应该适当紧缩货币与信贷。这样,由于金融政策有滞后性,当经济走向高涨时期时,货币与信贷政策正好可以发挥作用,避免经济过热。而当经济增长比较平缓但并未出现下滑趋势时,政府就应对其进行刺激。逆周期政策可以避免由于滞后性造成的调控不当的问题,是金融政策制定中一个比较好的调控思路。

扩展

美国国债

  • 中国为什么要购买美国国债?https://www.zhihu.com/question/23117022
  • 根本原因是中国是实行外汇管制和人民币汇率控制。也就是说钞票进出中国都要经过一个机构,更换对应的货币,这个机构叫央行。
  • 中国是世界工厂,生产很多东西卖到全世界;同时中国的经济发展和巨大的市场规模,很多外国公司到中国投资。所以中国现在每年的贸易都是顺差(进来的钱多,出去的钱少),这样一年一年累计,中国银行就聚集了一大笔美元。

买美国国债

  1. 钱太多,花不掉。
    中国的外汇也不全是买美国国债,也有部分是做其他的,比如买黄金,投资等。但是这么一笔巨额的资金,只做这些是消化不了的。
  2. 选来选去,只有买美国国债比较合适:1,有保障(美国后台,安全),2,用的掉(美国国债发行量大),3,回报率尚可。
  3. 购买美国国债是稳赚不赔的吗?
    不是,比如美元贬值可能导致缩水
  4. 那么大笔的重要的资金,安全是第一位的;回报率是第二位的

中国的外汇储备并不都是中国人赚的

  • 中国的外汇储备并不全部都是中国人自己赚的,里面有一部分,而且是很大一部分,是外国投资引来的外汇,这笔美元只是暂存在央行,其所有权并不归属于中国。中国每年的巨额出口顺差,赚的钱也并不全是中国的,相当大一部分,都是属于外国资方的,但是我们不能因此排斥外国资方,相反还要拼命引资,没有这些外国投资,中国不可能发展到今天这个高度。
  • 所以,为了在外汇储备激增的前提下尽可能的保护中国的利益,买美国国债,是保护中国外汇储备最佳的选择。

《半小时漫画经济学》-笔记

发表于 2020-11-02

一、开篇:我们为什么要读经济学

  • 历史上没有一场仗是因为爱和正义打起来的,所有的流血背后,深层次的原因都是经济
  • 如果我们想搞明白人类是怎么活成这样的、世界是怎么运转起来的,就要先搞明白这个问题:经济是怎么来的?一、经济起源首先,经济是什么?简单地讲,就是资源最优化配置。比如一瓶水,只有到口渴的人手里,价值才能发挥到最大。
  • 这些余粮,就是大家的财产,我们也可以将之理解成经济学里的资源。
  • 农业是骨架,工业填充了血肉,其他行业是各种器官,它们一起组成了经济这副躯体。

二、货币的起源:钱打哪儿来的

  • 用金银当货币,就叫——金银本位。用羊当货币就是羊本位,用贝壳当货币就是贝本位,以此类推。
  • 经济越来越好,商品就越来越多,这就需要更多的钱去买。于是有了比金银更方便带、更方便造的纸币。到后来,人们觉得纸币也麻烦,于是有了方便付款的电子货币。
  • 货币随着经济增长一直在变多!
  • 钱源于债务!因为人类学家发现了很多证据,研究了半天,得出个结论:这种物物交换的社会是不存在的!
  • 二狗子拿着鸡要换三胖子的铁锤,三胖子虽然不想要鸡,但他还是把铁锤给了二狗子,大家都熟,打个欠条就行。比如欠条到了老四手里,就相当于二狗子欠老四债。后来,大家也都这么做,用着用着顺手了,欠条就在村里流通了起来,谁还在乎它原先是谁的?为什么大家相信这张欠条呢?原来,二狗子人品好,财产多,不管谁拿着欠条来换铁锤,他都给换。这种有借有还的品质,就是传说中的——信用。人们交换、欠债什么的,其实玩的都是信用,只要有人相信,贝壳、石头、金银,甚至纸,都能当钱花。这就是信用货币理论的一部分。

三、那些年缴过的“五险一金”到底是什么

  • 政府、工厂、工人各拿出点钱来存在一起,哪个工人出意外了,就拿钱出来,让他能维持生活,大概是这样:工人们没后顾之忧了,干起活儿来更带劲,德国经济一路雄起。现代社保制度从此诞生了!
  • 如果社保不够年限,那恐怕享受不到福利了。你自己缴的会退给你,不过公司帮你缴的钱,只能和它们说再见了。

四、养老金能养老吗

  • 计算养老金时,是以当时的社会平均工资为基础的,所以不用担心钱贬值的问题。
  • 真实情况是,人口正在老龄化,上班族越来越少,退休的大爷大妈越来越多。[插图]这样下去,总有一天,社保基金入不敷出,到时候嘛。。

五、医保到底保了个啥

六、一口气搞懂到底要缴哪些税

  • 从收入里拿出来的这部分钱就叫个人所得税。正确叫法应该是免征额
  • 在商品流通过程中缴的税,就叫流转税。
  • 无论占有哪种财富,都有可能要缴税,这叫财产和资源税。
  • 税很多事和特定行为有关,把它们打包一下收的税,就叫行为税

七、买房前必须知道的二三事

  • 宅基地所有权归集体,使用权归农民,不存在什么年限,住到宇宙爆炸都没问题。但宅基地的房子有个问题,没房产证,没产权,没土地使用证,俗称小产权房。这种房子自己住没问题,但要想卖给外村人或者城里人,就难喽!
  • 一般买这些地的,都是房地产公司,交的钱就叫土地出让金,但使用权是有期限的,比如70年,相当于租地。房地产公司怎么赚钱呢?很简单,盖楼卖给消费者,这就是我们熟悉的商品房。产权时间是从开发商拿地开始算的,以70年产权为例,实际你买的房子的产权到期时间可能要比70年短。
  • 国家收回土地土地产权到期了,如果国家想收回来用,那你的房子就要拆迁了,你的人生可能就不一样了。

九、借钱那些事儿:如何避开借贷中的那些坑

  • 个人、公司和政府,三者之间的不同组合,就对应了我们身边不同的金融产品。
  • 按传统经济学家的说法,人是理性的,大家都只会把钱借给靠谱的人,也只会借自己有能力还的钱。次贷危机首先得弄清楚什么叫次贷:[插图]一边美国银行敢给,另一边矮矬穷真敢借,也不想想自己能不能还上
  • 法律就说了,民间借贷的利率高过36%属于高利贷,是非法的。

十、消费心理学:消费者防剁手指南

  • 大家购物时,会先找差不多的货比一比,一般不会选高价和低价,而是选中间价。这就是托奥斯基的“价格锚点”理论。
  • 特沃斯基和卡尼曼的“损失规避”理论。简单来说就是比起得到,大家更怕失去。所以就算是一件好东西,一旦发现会给自己带来损失,很多人就宁愿不要。

十一、传销大起底:珍爱生命,远离传销

  • 整个过程都没有真正的产品,赚钱全靠拆东墙补西墙。这个简单的骗术,就是金融界大名鼎鼎的庞氏骗局。这个骗局的死穴就在于:需要不断有新钱注入,一旦没有蠢萌新人进来,大家全都要玩儿完。四个字形容它的特点,那就是:一旦停药,骗子就会赶紧拿钱跑路,大家的投资款就打水漂了。
  • 如果有一天,再也发展不到下线了,整个系统就崩溃了。也就是说,传销的本质就是:不要产品,只要人。

一、开篇:我们为什么要了解金融危机

  • 经济有个定义:价值的创造、转化和实现。简单地说,经济就是资源配置,但是人类总是在这条路上跑偏。
  • 博大精深的中华文化告诉我们,把“危机”拆开来看,就是:“危险”和“机会。
  • 二战之所以能打起来,部分原因是美国的国内危机,演变成了全球危机。
  • 金融危机不是绝对的坏事,也可能是社会的崩溃疗法

二、金融危机就要来了:明斯基时刻

  • 人类社会的经济是有规律的,每次繁荣后面,都跟着一波波衰退。人们把这种周期性经济衰退的现象叫:经济危机。而经济的衰退常常是由于金融危机导致的。
  • 经济是有周期的,金融危机经常发生,原因可能是金融不稳定。经济周期有大有小,很多小周期构成了一个大周期,明斯基时刻说的是大周期的转折点。
  • 借的这部分钱,就叫杠杆。借钱用来扩充资产,就是加杠杆。杠杆让你赚得多,但赔起来也多。
  • 杠杆越来越高,最后还不起了,可能就会引发危机。所以该咋做知道了吧?去杠杆啊!简单说就是还钱,一般政府都会做这些事:方法1:债务违约重组钱暂时还不上是吧?银行为了把钱要回来,只好想点别的办法,比如少还点,延长还款期限。方法2:财富再分配给土豪加税,把收来的钱用来发福利、创造就业岗位,这样失业的人就慢慢有了钱,就能把欠的还上。方法3:货币调节为了解决问题,政府会和中央银行商量,让中央银行多印一些钱,然后花到了大家身上。

三、一朵花酿成的惨案:郁金香泡沫(上)

  • 郁金香泡沫,堪称金融危机鼻祖。
  • 赚了钱就按比例分红,赔了钱就只承担有限责任,这就是世界上第一家股份有限公司

四、一朵花酿成的惨案:郁金香泡沫(下)

  • 合同到期了,就能拿到郁金香,反正不会亏,大家都乐意。这种玩法就是期货的雏形。荷兰人全国总动员炒郁金香,船不造了,生意黄了,钱投进去连个响都没有,经济急剧下滑。
  • 郁金香泡沫过去了,后来又有南海泡沫、密西西比泡沫,甚至次贷危机。人们好像从来不会吸取教训,直到现在咱们身边也还在发生这种事:所以看完这个故事,对咱们还是很有用的,起码你再看到有些东西很贵,但明显不值那个价,人们却一直往里砸钱投资时,就应该知道那很可能就是金融泡沫,要保持冷静。价格虚高的东西别碰,要投就投有价值的,这叫理性。

五、连牛顿也算不出的疯狂:南海泡沫

  • 对南海公司来说,“韭菜”就是一茬茬的钱,问题是怎么收割呢?南海贸易特许权本来就是个金字招牌,再加上政府的担保,就能让不明真相的老百姓信得不要不要的。“韭菜们”都看好南海公司,纷纷买入他们的股票。
  • 上到国王,下到家庭主妇,全在炒股,却不管不问公司经营啥情况,这就很容易——出大事啊!

六、股票连涨13个月会怎么样:密西西比泡沫

  • 他首先要做的不是跑业务,而是开始发股票,而且能用国债来换股票。大家都很看好公司,因此股票老值钱了。现在能用国债换,简直是睡觉都能笑醒!这样一换,国债被抵销,国家就不用还老百姓钱啦!法国经济繁荣靠股市,但股市其实很虚,因此所谓的经济繁荣就是个泡沫啊!最后路易十六被送上断头台,这就是著名的法国大革命。

七、房价是怎么被炒起来的:1837年美国大恐慌

  • 1837年美国大恐慌从本质上说就是一个美国人瞎炒房的故事。简单来说,贷款变难了,这叫信贷紧缩,缩得太紧,导致市场上没钱,美国经济就容易不景气。总结一下,美国跟英国房东打了两架,欠了外债,为了还钱开银行,薅了老百姓的黄金,最后把自己的经济搞坏了。
  • 很快国内经济一落千丈,纸币没人信,黄金又没有,股票暴跌,很多行业破产,大家都找不到工作。这就是美国第一次萧条,史称美国大恐慌。
  • 1848年,恐慌了11年的美国在加州的一个地方,发现了大金矿。本来缺黄金,一下子却变成了矿主,美国突然不慌了,这就是历史上著名的淘金热。
  • 简单来说,美国大恐慌其实就是一个炒房的故事,房子是用来住的,不是用来炒的,可惜美国人并不懂这个道理。

八、美联储的诞生:1907年美国银行危机

  • 南方要搞农业,北方要搞工业,一言不合就开撕,这就是咱们熟悉的南北战争。
  • 他来自传说中的摩根家族,据说当时身家达13亿美元。于是摩根撸起袖子,着手拯救美国:他先找了几家银行,成立了一个由富翁们组成,专门给发愁的信托和银行送钱的联盟——摩根干的其实是中央银行的活,所以美国觉得需要一家中央银行来统一管钱。成立新机构要取个新名字,叫啥好呢?美国老百姓已经听到银行就害怕了,所以不能有银行两个字。那就叫美国联邦储备局吧

九、实现美国梦的三大法宝:泰罗制、福特制和猪

十、1929—1933年美国大萧条

  • 自由放任主义。结果小公司一个个倒下,而强势的公司却越做越大,逐渐成了江湖的不败神话:垄断的意思大家都知道吧:一家公司赶走竞争者,占领市场一家独大。但垄断常常会产生不好的结果,少数人资源独占,而多数人吃糠咽菜,贫富差距很快就被拉大了。
  • 当时的资本家一心想赚钱,玩命搞生产,可问题是:多数人穷得连饭都吃不起,他们能买得起啥?所以当时的社会背景就是:资本家们一瞅,一个个的都不消费,多影响自己赚钱国家经济啊!
  • 消费力虚了,农业也跟着倒了血霉,农产品卖不出去,只能销毁。很多农民宁可把牛奶倒进河里,也不降价或者送给穷人。为什么呢?因为一旦牛奶降价,其他货为了卖出去,只能被迫降价,这样会导致卖家利润更低。另外,想卖货得先砸钱,比如投入运费,货倒了反而损失小。
  • 经济危机最严重的问题就是失业。
  • 由生产过剩引发的经济危机。

十一、拯救美国的两位“救市主”:胡佛和罗斯福

  • 胡佛是一个坚定的自由放任主义者,这种说法其实不太对,因为他在经济危机之后一直在积极干预经济。

  • 新上任的总统就是罗斯福。罗大爷觉得,政府应该对市场插手,不能只当看大门的保安,想解决危机,就要做连你家垃圾都要管的——这套想法其实就是凯恩斯主义,当然里面的内容还有很多,这里简单理解一下就好。既然胡佛搞砸了,那这一套还好使吗?咱看看罗斯福怎么做的就知道了。
    罗斯福放了个大招——废除金本位。金本位制度规定美元和黄金挂钩,两者价值要对等,不能瞎印美元。现在脱钩了,政府就能多印点美元给银行,而且美元一多就贬值。对其他国家来讲,美国商品便宜了,秒变抢手货。

  • 政府搞基建招工,然后给工人们发工资。

  • 胡佛和罗斯福的很多政策其实差不多,都整顿了银行,都不让降工资,但为啥一个失败而另一个却成功了呢?这里就要说一下经济周期了。啥叫经济周期?简单说就是:下滑期,再厉害也没用;上升期,躺赢不是梦。

重构-改善既有代码的设计-摘要

发表于 2020-11-01







《重新定义团队:谷歌如何工作》-笔记

发表于 2020-10-24

自序

  • 韦尔奇和康纳迪采用了20-70-10的绩效排名体系,在这种体系下,他们将通用电气的员工分为三类:最优秀的20%,中间层的70%,末尾的10%。最优秀的员工得到赞扬,作为奖励可以选择工作任务,参加领导力培训项目和享有优先认股权。末尾的10%会遭到解雇。

  • 清晰明了的“前20%”“中间70%”和“末尾10%”被更加委婉的描述方式取代:“顶尖人才”“极具价值”和“需要改进”。

  • 因为自由的状态是以自由表达为基础的,而自由表达又依靠对信息和真实情况的了解。

  • 在这里有时会精疲力竭,有时会倍感沮丧,但永远奋发进取,创造有目的性的、自由的和充满创造力的环境。

前言 为什么谷歌的原则也对你适用

  • 当员工信任领导层的时候,他们就会成为品牌的代言人,从而为其家庭、所处的群体和环境带来积极的改变。员工生产效率变高,企业发展增速,顾客购买热情高涨,商业投资回报也就自然而然地实现了。
  • 从管理的核心角度来讲,权力的动态方向恰与自由背道而驰。员工要依靠管理者,希望取悦他们。然而,注重取悦管理者意味着与其进行开诚布公的探讨是有风险的。如果你不取悦他,内心就可能惶恐不安或焦躁愤恨。同时他还要保证你实现某些工作成果。
  • 谷歌应对此类问题的方法是割开这个结。我们刻意剥夺了管理者对员工的控制权。下面一些例子是谷歌的管理者不能单方面做出的一些决定:•雇用谁•解雇谁•如何评估一个人的表现•给某个人加薪多少,给多少分红或分配多少股权•选谁来拿最佳管理奖•给谁升职•代码何时才算合格,可以纳入到公司的软件代码库中•一种产品的最终设计以及何时投放市场。
    上述决定都是由一组同事、一个委员会或一个特别任命的独立团队做出。
  • 升职的问题又摆到了眼前,这时他们又会惊愕地发现自己没有权力独自决定给他们认为团队里最优秀的员工升职。问题在于,你和我对“最优秀的员工”的认识有所不同。也有可能你的团队中最差的成员比我的团队最优秀的员工还要好,这种情况下,你的整个团队都应该升职,而我的团队成员都不应该升职。
  • 一名管理者到底该做些什么呢?只有一件事情可以做。按照我们的执行总裁埃里克·施密特的话说就是“管理者服务于团队”。和其他企业一样,我们当然也遭遇过意外和失败,但是在谷歌这种不干预的领导方式下,管理者的关注重点不是惩罚或奖励,而是清除路障,鼓励团队。
  • 只有公司采用了给员工充分授权的经营方式(比如,剥夺管理者的决定权,并将该权力分配给一些个体或团队),为员工提供工作之外的学习机会,提高团队信任度(给团队足够的自主权,允许员工自行组队),或是组合利用上述方法,这样业绩才能得到提升。
    简而言之,只有当企业着手给员工更多的自由时,业绩才能提升。
  • 我们所做的绝大多数事情的费用都极低。即便是只拿死工资的时候,也能把工作做得更好,使员工更有幸福感。其实,越是在经济状况不好的时候,善待员工越是重要。
  • 我们只需要坚信员工都是好的,再就是要有足够的勇气,把员工看成是企业的主人翁,而不是把他们当成机器。机器会完成工作;主人翁会竭尽所能帮助企业和团队获得成功。人的一生大部分时间都在工作,但是对多数人而言,工作是一件痛苦的事情,只是一种谋生的手段。可以不必如此的。
  • 如何更好地探寻和发展自由、富有创造力和宽松的环境,使员工在这种环境下工作。

第一章 成为一名创始人

  • 他们都希望创造出这样一家公司:工作有意义,员工可以尽情发挥自己的激情,他们和他们的家人都得到关怀。

  • 建立杰出的团队或机构的起点是有一位创始人。但是成为一名创始人并不意味着要建立一家新的公司。任何人都有能力成为一名创始人,也可以成为所在团队的文化创造者,不管你是一家公司的第一名雇员还是一家数十年历史的公司中的一员。

  • 我写作本书的愿望之一就是,希望阅读本书的人都能站在创始人的角度看待自己。或许不是一家公司的创始人,但是也可以成为一个团队、一个家庭或一种文化的创始人。谷歌的经历带来的最根本的一点经验就是你必须先决定自己想要成为一名创始人还是一名雇员。这个问题关乎的不是实际的所有权而是做事的态度。

  • 谷歌工作法则:成为一名创始人□把自己看成是一名创始人□像创始人一样行动

第二章 “文化可以把战略当早餐一样吃掉”

  • 如果你给员工以自由,他们将还你以惊喜

  • 公司文化的三个根本元素:使命、透明和发声的权利。

  • 我们的使命是“整合全球信息,使人人都能访问并从中受益”

  • 谷歌的使命与众不同,既在于其简洁明了,也在于其未曾言及的方面。没有言及利润或市场。没有言及顾客、股东或用户。没有言及为何选此作为公司使命,也未曾言及如何实现这些目标。相反,谷歌的使命整合全球信息,使人人都能访问并从中受益是一件不言自明的好事。这样的使命使个人的工作有了意义,因为它不是一种商业目标而是一种道德目标。史上最有影响力的运动都要有道德动机,或是追求独立,或是追求平等权利。

  • 归根结底,我们永远也无法达成我们的使命,因为总有更多的信息需要集成,总有更多的方式可以使人们从中受益。这样就给我们创造了动机,促使我们不断创新,探索新的领域。要成为“市场领导者”这种公司使命,一旦实现,就难以再带来更多的激励。

  • 我们在践行公司使命时,也带来了令人惊喜的实用价值。

  • 每一类职业的人里面都大约有三分之一将自己的工作看作一种使命。这样做的人不仅更快乐,而且也更健康。

  • 如果你相信员工,就不必害怕与他们分享信息透明是我们公司文化的第二块基石。“默认开放”(Default to open)是在开源社区中时常会听到的一个短语。

  • 如果你能给员工以自由,他们就会为你创造惊喜。他们有时也会令你失望,但是我们也都知道人无完人。这并非宣扬自由的檄文,只不过是权衡利弊后的选择。

  • 谷歌工作法则:打造了不起的文化□将工作看作是一种命运的召唤,而且工作要有富于意义的使命。□给人以稍多于你的舒适区的信任、自由和自主权。如果你没有感到紧张,那是因为你给的还不够。

第三章 只聘用比你更优秀的人

  • 如果我们前期选人的时候能做到更好,也就意味着聘用他们之后在这些人身上投入的精力就会减少。聘用水平超过90%应聘者的员工,最糟的情况他们也能有平均水平的表现。这些员工几乎不可能成为公司里表现最差的

  • 你如何能够判断自己到底有没有找到一名非凡的人才?我所遵循的首要原则——也是你在招聘时需要做出的第二个改变——是:“只聘用比你更优秀的人。”我所聘用的人都在某些特定的方面比我更优秀的。

  • 从《人才的谬见》一文中得到的教训不是“不要聘用聪明人”。而是“不要只聘用聪明人”。至理名言。出色的招聘工作不仅在于聘请到名头很大的人、顶尖的销售人员或最聪明的工程师,而且在于搜寻到在你所处组织的环境下能够成功的最优人才,在于找到能使周围每个人都更加成功的人才。

  • 谷歌工作法则:关于招聘□资源有限的情况下,将人力资源费用首先投入到招聘上。□慢慢来,聘用最优秀的人才,只聘用在某些特定的方面比你更优秀的人,不要让经理独自做团队人员聘用决策。

第四章 搜寻最优人才

  • 最优秀的人并不在寻找工作。表现极为优秀的人在现在的工作岗位上很开心,满足感很强。他们不会进入人们的推荐人名单中,因为人们会想为什么要推荐一些在现在岗位上很开心的人呢?而且他们肯定也不会考虑新的工作。

  • 谷歌工作法则:搜寻非凡的应聘者?□要详细说明寻找人才的标准,依此找到最优秀的被推荐人□使招聘成为每个人的工作□不要害怕尝试疯狂的事情,以此引起最优秀人才的注意

第五章 不要相信你的直觉

  • 根据头10秒钟的印象做出的预测是没有任何意义的。这头10秒钟的预测使我们在整个面试过程中都在试图证明我们对某个人的印象,而不是真正地去评估他们。心理学家将这种现象称作证实偏见(Confirmation Bias),“倾向于寻找、解释或优先考虑那些能够支持我们观点或假设的信息”。

  • 多数的面试都是在浪费时间,因为99.4%的时间都用在证实面试官最初10秒钟的印象,不论印象好坏。“请做一下自我介绍。”“你最大的缺点是什么?”“你最大的优势是什么?”毫无价值。

  • 你不仅要评估应聘者,还需要让他们喜欢上你。真的。你得让他们有一次非常棒的体验,处理好他们关心的问题,使他们感觉刚刚经历过一生中最快乐的一天。

  • 谷歌工作法则:筛选新雇员?□设定高质量标准□寻找自己的应聘者□客观评估应聘者□给应聘者一个加入的理由

第六章 打造最幸福的公司

  • 权力导致腐败,绝对的权力导致绝对的腐败

  • 如果要做假设,也应该认为掌握权力的人是恶的,权力越大,恶念越深……伟人多数是恶人,即便他们不滥用权力,而只是施加影响力;如果你再考虑到权力带来腐败的可能性或必然性,他们的恶会更甚。

  • 回想一下你参加过的会议。我敢打赌,级别最高的那个人总是坐在会议桌的上首。是因为他们匆匆地从一间办公室冲到另一间办公室,抢先来到会议室,才占到这个最好的位置吗?下次仔细观察一下。随着参会者陆续到场,他们会刻意将上首的座位空着。此种现象证明了我们一些不自觉的微妙举动都创造了等级制度。没有指示,没有讨论,甚至没有有意识的思考,我们就会为“上级”留出位置。

  • 我们最高层的一些领导对这种现象也非常熟悉,并尝试打破这种状态,选择坐到会议桌某一侧的中间。

  • 经理都倾向于累积和运用权力。员工都倾向于服从命令。

  • 不可否认的是,我们很多人都同时扮演着经理和员工两个角色。我们都遇到过控制欲很强的经理,也都遇到过不服从管理的员工,这样的挫败感我们每个人都曾有过。

  • 授权于群众的第一步就是要保证人们能够安全地发表意见。俗话说“枪打出头鸟”,就是警示人不要随便发表评论。正是因为这个原因我们才尽可能削弱经理的权力。他们拥有的正式授权越少,就越难利用萝卜加大棒的政策辖制团队,这个团队的创新范围便会越广。

  • 为了减轻人类内在寻求等级划分的倾向,我们尝试除去显示权力和地位的象征符号。

  • 谷歌坚持的核心准则中一直都有一条“不要耍政治手腕。用数据说话”

  • 经理们忽略的是,每次他们放弃一些控制权,就可以为团队创造一次提升的好机会,也给自己节省出更多时间应对新的挑战。找出某个令你的团队感到沮丧的领域,让他们改变现状。如果有限制,比如时间或资金有限制,就告诉他们。要对员工透明,在塑造团队或公司的过程中给他们发言权。你会惊讶于他们的成就。

  • 谷歌工作法则:授权于员工□消除地位象征□依靠数据而不是根据经理的想法做决定□探寻方法,让员工塑造自己的工作和公司□高期待

第七章 为什么每个人都讨厌绩效管理

  • 关注个人成长而不是评分和奖励,以此改善绩效

  • OKRs(Objectives and Key results,目标和主要结果)。目标必须具体、可度量、可检验;如果你达成所有结果,就能完成目标。

  • 正如普拉萨德·塞迪解释的:“传统的绩效管理体系犯了一个大错。他们将两件应该彻底分开的事情合到了一起:绩效评估和人员发展。评估有其必要性,可确定加薪或奖金等有限资源的分配。发展也同样很有必要性,可以促进员工的成长与提高。”如果你希望员工成长,不要同时进行这两项谈话。确保发展成为你与团队成员之间不断往返的一个过程,而不是年底的一次惊喜。

  • 为了确保员工与经理的交谈更有效,我们整理出一份一页的讲义,分发给他们,在绩效交谈的时候使用。做这一份讲义的目的还是为了使对话更具体,更切合实际。我们给员工分发这些讲义只是为了稳妥;我们希望经理能够覆盖恰当的话题,但是让员工准备好引导讨论也没有什么坏处。

  • 把奖励分配谈话与员工发展谈话分开。两项谈话混为一谈会扼杀学习的动力。不管公司规模多大,这一点都适用。

  • 谷歌工作法则:绩效管理□正确地设定目标□收集同事的反馈意见□通过校准流程确定考评结果□把奖励分配谈话与员工发展谈话分开

第八章 管理团队的两端——最优员工和最差员工

  • 从统计学上讲,这些现象更适合用“幂律分布”(power law distribution)解释。

  • 大多数公司在管理员工时都采用正态分布,大多数员工被列为平均水平,两端为表现差和表现优秀的员工。两端并不像身高分布那样对称,因为失败的员工都被解雇了,最差的应聘者根本就进不了公司,因此左侧的一段很短。但是很多公司认为员工的表现还会符合同样的正态分布。这样的认识是一个错误。事实上,组织中大多数的个人表现符合幂律分布。

  • 并非大批平均水平的员工通过数量优势做出主要贡献,而是由少数精英员工通过强大的表现做出主要贡献。

  • 采用一种不同的方式:我们的目标在于告诉底端5%的每一位员工,他们处于这样一个群体。这种对话不会是幽默风趣的。但是我们向这些员工传递出的信息使这项工作简单了一些:“你在整个谷歌处于底端的5%。我知道这样的感觉不好。我之所以要告诉你是因为我想要帮助你成长,变得更好。”换言之,这不是一次“要么好好干,要么走人”的谈话;这是一次感性的谈话,目的是帮助一个人发展。有一位同事曾经将其形容为“富有同情心的实用主义”。绩效表现糟糕极少是因为某人的能力不足或品性不佳。更多的是由于技能的缺陷(或许可以改进,或许不能)或意愿不足(员工没有做工作的动力)。在后一种情况下,可能是由于个人问题,也可能预示着团队中出现了某个更大的问题需要修正。

  • 通常,调岗之后这个人的绩效能够提升到平均水平。这听起来或许不算什么,但是反过来这样想想:100个人的团队中,吉姆是表现最差的5个人之一。经过这次干预之后,吉姆的绩效表现进入了前50位。

  • 余下的一些员工,有的选择主动离职,有的就只能解雇了。听起来很残酷,但是最后他们通常会更开心一些,因为我们表现出对他们状况的理解,并与他们一道投入了改进过程,而且我们给他们时间寻找一家能够发挥专长的公司。

  • 在分布底端投入时间精力的这个循环意味着你们的团队能够提升很多。员工或是得到大幅的提升,或是离职去别的地方寻找成功。

  • 对员工直接一些实际上是仁慈的表现

  • 我要强调一点,谷歌识别底端5%的员工并非“员工大排名”,不是要按照固定的分布将员工的绩效表现分类。那种考评方式下,员工为了不落在底端会激烈竞争,最终搅乱了公司文化。
    我采访过的每一位现在和过去的微软员工——每一位——都认为员工大排名是微软内部最有害的政策,在这种政策下,无数的员工被迫离职……“如果你的团队中有10个人,你开始工作的第一天就了解到,不管每一位员工多么优秀,都将有两个人获得好评,7个人获得中评,另外有一个人获得差评,”一位前微软软件开发工程师说,“这使员工的注意力都放在内部互相竞争上,而不是与其他公司竞争。”

  • 如果你相信员工本质都是好的,认为他们值得信任,那就必须对他们坦诚相待,保持透明度。这就包括让他们知道自己的绩效拖了后腿。但是在一家使命导向性、有目标的公司,处理人力问题时要有敏感性。多数表现不佳的员工能够认识自己的表现,想要变得更好。给他们改进的机会非常重要。

  • 顶端的员工生活在高产出、良好的反馈意见、更高的产出和更好的反馈意见这样一个良性循环中。他们每天都沐浴在爱的环境中,给他安排的额外工作也使他更加开心。更重要的是要从最优秀的员工身上学习。

  • 最优秀经理手下工作的谷歌人在十几项Googlegeist评估维度上要比最差经理手下工作的谷歌人高5%至18%。除此之外,他们在以下几方面的认可度明显更高:•职业决策更加公正。绩效评估公正,得到升职的都是实至名归的人选。•个人的职业目标能够达成,他们的经理是非常有帮助的支持者和引导者。•工作高效,决策迅速,资源分配合理,从多种视角考虑问题。•团队成员之间没有等级制度,互相尊重,决策依据数据做出而不是靠耍手段,团队内部各人的工作和信念都保持透明。•他们适当地参与到决策制定过程中,并且得到一定的授权去完成工作。•他们可以自由地平衡工作和私人生活。

  • 最优秀经理领导的团队绩效表现也更好,人员流动率更低。

  • 调查显示高分经理具备八种低分经理所不具备的共性:8个氧气项目特性1. 做一名好的导师。2. 给团队授权,不随便插手下属工作。3. 表达出对团队成员的成功和个人幸福的兴趣和关心。4. 高效/结果导向型。5. 善于沟通——聆听和分享信息。6. 在职业发展方面助力团队。7. 对团队有清晰的愿景和战略。8. 具备重要的技术技能,可为团队提供建议。

  • 我们发现在伟大的经理中间,技术专业性是8种特性里重要性最低的一项。不要误会,技术专业性非常关键。一名不会编代码的经理不可能在谷歌领导一个团队。但是在区分最优秀的经理行为时,技术能力在不同团队中是差异最小的。

  • 这是对经理–员工关系的一次华丽反转。想要提高,最好的方法是与那些提供反馈意见的员工进行交谈,询问他们希望自己做出哪些改变。

  • 让处于绩效分布底端的人了解真相,但是不要将绩效与薪酬或职业成果直接挂钩,尽可能用一种积极的方式警示并激励他们。数百名经理需要面对自己并非好经理的现实。

  • 谷歌工作法则:管理团队的两端—最优员工和最差员工?□助力有难处的员工□将最优秀的人放在显微镜下观察□利用调查和检查清单寻找真相,推动员工学习□与人分享员工对你的反馈意见,以身作则采取行动解决问题,身先示范

第九章 打造学习型组织

  • 在某一领域精熟的人,不管是小提琴家、外科医生、运动员[插图]还是拼字比赛冠军[插图],学习的方法都有异于常人。他们将活动分解成细小的动作,比如连续数小时在雨中练习同一种击球动作,不断重复。每一次,他们都会观察效果,做微小的——几乎难以觉察的——调整,逐步改进。埃里克森将这种方式称作刻意练习:有意重复类似的小任务,即时反馈、修正和实验。

  • 不过或许你不想要手下最优秀的销售人员去教学。毕竟,不应该让她全心全意做销售吗?我认为这是一种短视的想法,因为个人的绩效表现的提升是线性的,而培训授课则会带来几何级数的增长。

  • 学习型组织发端于一种认识,即我们所有人都渴望成长,也都希望帮助他人成长。然而,在很多组织中却是员工受教,专业人士负责教学。为什么不让员工同时做两件事情?

  • 谷歌工作法则:打造学习型组织□进行刻意练习:将课程分成易于消化的小块,给出明晰的反馈意见,并不断重复这个过程□请最优秀的员工教学□只在已经证明能够改变员工行为的课程上进行投入

培训的效果衡量四个层次,一是反应,课后调查反馈课堂效果及氛围。二是学习,调查学员学到了那些知识,学习效果如何。三是形行为,接受学员学以致用的反馈,是否有提升,同时调查团队周边或客户的客观评价。四是结果,最终是否导致了效率提升,绩效比变好等等

第十章 不公平薪酬

  • 总结下来共4条原则:1. 不公平薪酬。2. 以成就为荣,不以报酬为荣。3. 创造易于传播爱的环境。4. 精心筹划却遭受失败的要奖励。

  • 如何庆祝成功的同时不滋生嫉妒

  • 这样做带来了不良的后果,假如你是非常优秀的员工,将会得到几次大幅加薪,之后加薪的速度会越来越慢,直到最后你接近容许的薪酬范围上限,加薪也会随之停止。最优秀的队员除了需要高报酬之外,也能持续创造优异的成果。

  • 对于那些快速学习成长和表现最顶尖的人来说,确保你的薪水与所创造的价值相适应有一种方法,就是离开这种垄断的内部市场,进入自由市场。即寻找一份新工作,以你的真正价值为基础,协商薪酬,然后离开现在的公司。这也是你在人才市场上看到的真实情况。

  • 为什么公司不设计一种体系,避免最优秀和潜力最大的员工辞职呢?因为他们对公平有一种错误认识,没有勇气坦诚面对自己的员工。薪酬的公平并不是说所有在同级别岗位上的人都要拿同样的薪水或是上下差不到20%。薪酬与贡献相匹配才能算得上公平。因此,个人的薪酬应该有巨大的差异

  • 正态分布(又称高斯分布)与幂律分布最大的区别在于,某些现象中,正态分布严重低估了极端事件发生的概率。

  • 个人的表现符合幂律分布。事实上,大多数员工都在平均水平以下:•66%的研究员发表论文的数量低于平均水平。•84%艾美奖提名演员获得提名数低于总提名平均数。•68%的美国参议院议员的任职届数要低于平均数。•71%的NBA球员得分低于平均分。低于平均数并非坏事。这只不过是一种数学统计而已。数据显示,非凡贡献者的表现水平要远高于大多数人,他们可以拉动平均数远高于中位数。

  • “10%的产出来自最顶尖1%的员工,26%的产出来自最顶尖5%的员工。”换言之,他们发现最顶尖1%员工的产出是平均产出的10倍,最顶尖5%的员工的产出是平均产出的4倍多。当然,这种算法并非在所有地方都适用。恰如奥博伊尔和阿吉斯所指出的:“工业和以体力劳动工作为主的组织,技术能力有限,对最低和最高产量有严格的标准。”在这些地方的员工表现更接近于正态分布。在这种环境下,极少有机会能做出非凡的成就。但除此种情况之外,幂律分布都占据主导。

  • 那些拿到100万美元奖励的人一定、一定是狂喜的吧?他们确实很开心。我的意思是说,拿到这样的奖励非常激动人心。人生就此改变。之后,我们最优秀的、最有创造力的、又有洞察力的技术人员中有一些(虽然不是全部)——他们曾创造出谷歌历史上最具有影响力的一些产品——意识到自己不太可能通过同样的产品两次获得创始人奖,因此立刻会想要转移到新的产品领域。虽然并非本意,但是我们创造出的这种激励体系,使公司里几乎所有人都不如以前开心,即使有少数人开心了,但也动了念头,不愿继续从事为他们赢得奖励的关键的创新性工作!

  • 我们公开地进行体验奖励,私下里进行差异化奖金和股权奖励。这样的结果使谷歌人变得比以前更开心。

  • 在奖励员工的时候,一定不能只用现金奖励,还要考虑体验奖励。很少有人回顾人生时会只看到一张张薪水单。他们会记住一些谈话、一些午餐,与同事和朋友共度的一些事件。不要用金钱庆祝,要用行动庆祝。

  • 谷歌工作法则:不公平薪酬□控制情感,做到不公平薪酬。薪酬差异化要明显,应符合绩效表现的幂律分布□以成就为荣,不以报酬为荣□创造易于传播爱的环境□精心筹划却遭受失败的要奖励

来源微信读书
分章读书总结:
1、在绩效方面,更多要参考幂律分布而不是传统的正态分布,平均数不等于中位数,实际上组织内大部分员工处于平均值之下,组织10%绩效产出来自1%的员工,出于人才保留和激励,不公平薪酬完全是合理且必要的;
2、人对于公正性的感知非常强,会极大影响他对于自身价值的认识、工作满意度、上级信任度和组织忠诚度,所以极端奖励体系要同时满足分配公正和程序公正;
3、在奖励员工时,不能只考虑现金奖励,还要考虑体验奖励;金钱激励是即时性的,所以在金钱激励时要辅以绩效谈话或颁奖等仪式性行为,以加深记忆,拉长激励的保质期,但总体来讲,用行动庆祝比用金钱庆祝更有持续记忆力;
4、要在组织内创造易于传播爱的环境,公开的赞许是最有效的一种管理工具,相信员工能做正确的事,结果通常他们会去做正确的事;
5、奖励成功也要奖励失败,否则员工会失去创造方面的冒险性;

第十一章 世上最好的东西是免费的

  • 我们做的几乎所有事情都是免费或费用很低的。所有这些项目都是为了提升效率,创造社区意识或创新精神。

  • 我不能给出数据证明有多少经济价值是因为免费洗衣机创造的,因为我根本就不在乎这些。我还记得职业生涯早期的麻烦经历,从我公寓到地下室的公用洗衣机要经过堆满杂物的楼道和摆满清洁用品的楼梯,而后要困在家里好几个小时,生怕别人来偷走我的衬衫。超级烦人。我们为什么不在园区找一间空房间,放上几台洗衣机和一些清洁剂,让生活稍微愉悦一些呢?我们为什么不请一些演讲者来园区给我们做演讲呢?

  • 我们进行过离职调查,从来没有任何人说这些服务能够使他们留下,也没有人因为这些服务才加入谷歌。这其中并没有什么大秘密:我们所做的这些事情(大多数)仅是举手之劳,但却收获巨大,而且我们感觉这样做是应该的。

  • 微小的关怀和资源投入也能带来巨大的成果。

  • 谷歌工作法则:效率、社区意识和创新精神?□使员工的生活容易一些□想办法说可以□生命中的不幸罕有发生……一旦员工遭遇不幸,要伸出援手

第十二章 助推

  • 诺贝奖获得者、普林斯顿大学荣誉退休教授丹尼尔·卡尼曼在他的《思考,快与慢》(Thinking, Fast and Slow)一书中描述人类有两套思维系统。其中一套慢、有深度、有思索、以数据为导向,而另外一套快、依靠本能、属于直觉思维系统。多数时候我们会依赖第二套思维系统,因此即便我们认为自己理性的时候,其实恐怕也并非如此。

  • 在面对对自我观念和自我认同的威胁时,防御是一种自然的反应。

  • 只需简单地提供信息,然后依靠人的本性——好胜的本性和利他主义的本性——就能改变一个机能失调的团队,看到这种现象真是既有趣,又令人振奋。

  • 谷歌工作法则:助推走向健康、富有和快乐□区分“实是”和“应是”的不同□进行许多小的实验□助推,不要硬推

第十三章 谷歌的教训

  • 任何想法走了极端都会变得愚蠢可笑。

  • 因此外界批评从原则上来讲是对的,但在实践中却并非如此。每年我们都要遭受一次重大的信息泄露。每一次都要进行一次调查,而且每一次信息泄露不管是刻意而为还是意外事故,不管是出于善意还是恶意,当事人都会被解雇。我们不会宣布泄露信息的人是谁,但是我们会让公司里的所有人都知道泄露的信息是什么,以及后果怎样。很多人了解到很多信息,总不可避免地有几个人会搞砸。但这样是值得的,因为泄露信息造成的损失相比我们享受的开放性而言并不算重大。

  • 一次失败的绩效管理变革。每一次我们对谷歌的绩效管理体系做出改变的时候,都会遭遇两个不证自明的真理:1. 没人喜欢当下的体系。2. 没人喜欢改变当下体系的提议。

  • 谷歌工作法则:搞砸的时候□承认错误。坦诚面对错误□吸取各个方面的意见□不管什么坏掉了,修好□找出错误中的寓意,加以传播

第十四章 从明天起你可以做些什么

  • 问题并非管理体系需要如何改变人性,而是如何改变工作的性质。

  • 一家组织的经营方式可以遵循两种极端的模型。本书的核心在于我的信念,相信你可以选择出期望打造何种类型的组织,而我所做的只是展示一些实现目标的工具。“低自由度”的一端是指挥控制型组织,对员工的管理很严格,工作强度大,公司对员工弃之如敝屣。“高自由度”的一端以自由为基础,员工受到尊重,对公司如何发展有一定的话语权。

  • 如果你希望建立高度自由的环境,下面有10个步骤可以帮助你的团队和组织实现转型。1. 赋予工作意义2. 相信员工3. 只聘用比你更优秀的人4. 不要将职业发展与管理绩效混为一谈5. 关注团队的两端—最优员工和最差员工6. 既要节俭又要慷慨7. 不公平薪酬8. 助推9. 管理日益提升的期望10. 享受!然后回到第1条,再来一遍

  1. 赋予工作意义工作至少占据了我们生活三分之一的时间和清醒时的一半时间。工作可以——也应该——不仅仅是一种达成结果的手段。非营利组织从很久以前就已将工作的意义作为吸引和激励员工的方法。比如,帮助难民的非营利组织避难通道(Asylum Access)的创始人艾米丽·阿诺德–费尔南德斯建立起一个世界一流的全球团队,这个团队的建立完全基于成员的共同愿景,即帮助难民找到工作,送他们的孩子上学,帮助他们在新的国家中建立起新的家园。在很多环境下,工作仅仅是为了得到薪水,但是亚当·格兰特的研究成果证明,只需与那些因你的工作而受益的人建立起微小的联系,便能大幅提升生产效率,而且还能使人更开心。所有的人都希望自己的工作有一定的目的。将工作与一种超越日常但却能真实反映所做事情的理念或价值观联系在一起。谷歌立志整合全球信息,使人人都能访问并从中受益。任何在这里工作的人都要践行这项使命,不管职位多么低微。这种使命吸引来了人才,激励他们留下来,去冒险,以最高水平的表现去工作。如果你是一名鲑鱼切片工,你就是在养育他人;如果你是一名管道工,你就是在改善人们的生活质量,保持他们家园的清洁和健康;如果你在生产线上工作,不管生产的产品是什么都将为人所用,帮助到他们。不管你在做什么,都会对某人有重要的意义。而你所做的这项工作对你也应有重要的意义。作为一名经理,你的工作就是帮助员工发现这种意义。
  2. 相信员工如果你相信人本善,就应如此行动。要对员工保持透明和真诚,给他们话语权,决定如何行事。从小事做起也可以。真的,你之前表现出的信任越少,小的举动就会令人感到越重大的意义。对于一家传统上一直进行不透明管理的公司而言,一个意见箱,员工知道其中的意见真正地有人读过且有人处理,会令人有革命性的感觉。请团队成员问你是什么促使你做出最近的一些决定的。如果你拥有的是一家小商店,要经常询问员工他们认为做出哪些改变能使商店更好,或者问他们如果这是他们的公司,他们会怎么做。因为你希望他们能这样做。就好似这是他们的公司一样。要实现这种状态唯一的方法就是你放弃一小部分权力,给他们朝这个方向发展的空间。这听起来或许有些令人望而却步,但其实并不需要冒太大的风险。管理层随时都可以拿走意见箱,或告诉员工不再需要他们的意见,或者甚至可以解雇一些人。如果你担心这样做会有损你的权威,那么就告诉员工每一种改变都只是试行几个月。如果可行,就继续。如果不可行,就停下来。即便仅仅是尝试,你的员工也会心怀感激的。如果你是团队的成员,就向你的老板提出这样的请求:给我一个机会。帮助我理解你的目标是什么,让我理清如何达成这些目标。这样的小举动将创造通往主人翁文化的途径。
  3. 只聘用比你更优秀的人企业总会认为尽快填补一个空缺岗位比耐心寻找最适合一个岗位的人更重要。有销售人员对我说过:“宁滥毋缺”,意思是说他们宁愿由一名领域内中等水平的人完成70%的限定销售额,也不愿让一个岗位空缺。但是在招聘质量要求上的妥协就已经是一个错误了。聘用糟糕的员工就好似在锅里扔进了一颗老鼠屎,不仅自身的表现不佳,还会拖累周围人的表现、士气和精力。如果拒绝一个人意味着其他每个人在短期内都需要更努力地工作,只需要提醒他们回想一下与上一个浑蛋同事共事时的遭遇就好了。成立委员会完成招聘工作,预先设定客观的标准,永远不要妥协,定期查看新聘用的员工是否优于以往聘用的员工。能够证明你的招聘工作做得很好的是新聘用的员工中十有八九都比你更优秀。如果他们不及你优秀,暂时不要聘用,直到找到一个更优秀的人。短期内你们的工作会放缓,但最终你将建立一个更加强大的团队。
  4. 不要将职业发展与管理绩效混为一谈克里斯·阿基里斯向我们展示了,即便最成功的人也有学不会的时候。如果他们都无法学习,那么余下的我们又能有什么希望呢?面对自己的缺点时总是难以令人愉悦。如果你将后果与批评结合在一起,如果员工感觉犯了一个错误就意味着在职业或经济上受损,那么他们就会争辩而不是保持开放的态度去学习和成长。发展谈话要随时进行,确保平稳且富有成效,恰如我以前的经理在每次会后进行的谈话一样。开启一次发展谈话的时候永远要保持这样的态度:“我能做些什么帮你取得更大成功?”否则,员工的防御心理就会增强,学习将中断。在实现目标的道路上,要确保发展谈话的平稳进行。不管目标有没有实现,两种谈话都应在空间和时间上分开。一个绩效考评阶段结束之后,立刻直入主题就设定的目标进行讨论,探讨哪些目标已经实现,以及奖励如何与绩效挂钩。但是这一次交谈应该只针对成果,而不是过程。可能没有达成目标,可能完成了目标,也可能超额完成了目标,每一种结果都应该对应不同的奖励或鼓励。如果处理好这方面的工作,绩效讨论就不再会是突然袭击,因为在整个过程中你们都在进行沟通,员工也能感觉到你在每一步工作上对他们的支持。不管在什么情况下,都不要完全依赖经理确定员工表现的确切情况。为了团队的发展,恳请同事贡献意见,即使是简单地问询一些问题或发布一些简单问卷也可以。至于绩效考评,要求经理们坐在一起组成团队,共同校准考评结果,确保公正。
  5. 关注团队的两端——最优员工和最差员工将最优秀的人放在显微镜下观察。他们结合了环境和技能,精心打磨才理清了如何成就超常表现。不仅要识别出最佳全能员工,还要识别出特定方面最突出的员工。不要寻找最优秀的销售人员;寻找面向特定规模的新用户销售量最大的人。找到能在夜雨中练习高尔夫球那样的优秀人才。在专业方面分得越精细,就越利于研究你的明星员工,发现他们比其他人更成功的原因。然后不仅要让他们成为其他人的榜样,围绕他们所做之事制定检查清单,还要请他们做老师。教授一项技能是掌握它的最好方法之一。请明星员工做教员,即使是半小时的咖啡交谈时间,也要促使他们清楚地讲述自己是如何开展工作的,而这个过程也有助于他们的成长。如果你身边有这样的同事,要仔细观察他们,多向他们提问题,利用这个机会从他们身上获取知识。与此同时,对表现最糟糕的员工也要心怀怜悯。如果你的招聘工作没有犯错,那么大多数陷入困境的员工都是因为没有找到合适的岗位,而不是因为自身笨拙。帮助他们学习或找到新的角色。但是如果上述努力失败,立刻辞退他们。让他们留在公司里并非仁慈,在一个自己并非最差员工的环境中,他们会更加快乐。
  6. 既要节俭又要慷慨我们为员工做的大多数事情都不需要任何花费。请供应商来公司为员工服务或与当地三明治店协商为公司送午餐。TGIF和嘉宾演讲者需要的仅仅是一个房间和一支麦克风。然而却带来了无比丰富的财富:启发谷歌人开发出一种新的服务或引发讨论。省下钱来,在员工最需要的时候,在他们遇到灾难或大喜之时使用。当某人需要急诊医疗护理或迎接家庭新成员之时,你的慷慨会带来最大的影响力。关注人类最重大的一些时刻能够突出你们的组织关心每一个员工。了解到自己在人生低谷和顶峰之时背后都有整个机构的力量做后盾,每个人都会感到宽慰。这一点对很小的公司也同样适用。我的父亲成立过一家工程公司,他亲自领导了30年。他深切关怀每一位员工,不仅付给他们薪水,而且善意赞扬,为他们提建议,做引导。团队中任何一个人任职5年之后,他都会拉他们出来私聊一番。他告诉他们公司有一项退休金计划,5年时间的投入已经满额。除了员工自己存下来的积蓄,他还为他们每个人额外存了一笔钱。有些人欢呼雀跃,有些人感动流涕,有些人只是简单地谢过了他。他没有提早告诉员工这项计划,因为他不希望人们为了钱才留下来工作。他希望员工留下来是因为喜欢创造东西,是因为喜爱这个团队。关键时刻他很慷慨,因此也使结果大不相同。
  7. 不公平薪酬不管你们的人力资源部门是怎么对你说的,要记住大多数工作中的绩效表现都是符合幂律分布的。你们的团队中90%甚至更高的价值都是由顶尖的10%的人创造的。因此,最优秀的员工远比平均水平的员工更有价值。他们的价值或许比平均水平的员工高50%,或许高50倍,但是不管高多少肯定值得你为他们付出更多。一定要让他们感觉到这些。即使你没有足够的资金为他们提供超高额的薪水,但是更高一些的薪水也算一种心意表达。另外一位员工对这种奖励或许会有些不高兴,但是你可以坦诚相对,解决这个问题:向他们解释薪酬差异化的原因,以及他们怎么做才能改变现状。与此同时,在公众认可方面要慷慨投入。团队的成就要庆贺,虽然失败但却学到重要经验教训的时候也要鼓励。
  8. 助推本书中提到的各种想法中对你未来的人生能够带来最大切实改善的一种就是改变每笔收入中存下来的金额。如果比较30年里赚到的钱同样多的一些人,他们累积的财富却可能有3000%的差异,而这一切几乎完全取决于你存下了多少钱。存钱从来都不是一件简单的事情。除非你比克罗伊斯[插图]还要富有,节省下来的每一个美元都像是一种利弊权衡。我是要买品牌货还是一般产品?是买3美元的花生酱还是吃甜点?换一辆新车还是再凑合一年?我毕业后的第一年,当演员的同时还做服务生,经常光顾小镇附近的女主人廉价商店(Hostess Thrift shop),店里售卖一些马上就要过期的面包和点心。我有了零食蛋糕(有节制的!),而且还能每周多省下几美元。要记住,督促谷歌人提升不到3%的存钱比例,每位谷歌人的退休基金将增加262000美元。很多人听到下面的事情或许会觉得很疯狂。我认识一些人,将度假胜地汉普顿斯的10万美元夏日出租房看成生活必需品;我的一些银行家朋友虽然在2008年丢掉了工作,但还是能躲到海滨别墅里度假。我一直反复强调这一点,但人们还是不愿意改变存款比例。计算出当前你存下来的钱占收入的比例,从现在起再多存一些。不论何时这都不是一件容易的事情。但这样做肯定是值得的。上面是对你个人而言。现在环顾四周,看看你所处的环境是如何助推你与周围的人的。你能很容易地看到其他人,与他们建立联系吗?你们冰箱里最不健康的零食放在与人的视线平齐的位置上吗?你给同事和朋友发邮件或短信的时候是分享好消息还是抱怨发火?我们都时刻受到环境的助推,也时刻助推着周围的人。利用这一点,使你自己和你的团队更快乐、更高效。工作场所的空间布置要鼓励你所期望的行为:如果你需要员工协作,但却受困于工位是小隔间,那么就推倒隔断。向员工传递讯息的时候要深思熟虑。分享一些积极的数据,比如参加当地慈善活动志愿者的人数,鼓励其他人参与。你将惊异于同一个工作场所给人带来的感觉会有如此大的不同。
  9. 管理日益提升的期望有时你会犯错误,这时就需要倒退几步。要准备好吃下你们自己的枸杞派。明白了这一点之后,在开始实验之前,告诉周围的人你打算实验本书中的一些想法。这样做有助于促使他们从批判者转变为支持者,实验走上了弯路的时候,他们的质疑将给你带来更多的益处。
  10. 享受!然后回到第1条,再来一遍拉里和谢尔盖立志创立一个他们都希望为之工作的地方。你也可以做同样的事情。即使你刚毕业加入一家公司,还只是一名初级职员,或者是第1000006号职员,你也可以像一位创始人一样选择与周围人的沟通方式,选择如何设计自己的工作场所,选择如何领导。你这样做可以帮助创造一个能够吸引地球上最优秀人才的场所。
  • 这并非一劳永逸的努力。想要打造了不起的公司文化和环境要求我们不断地学习和革新。不要担心立刻尝试所有事情。实验本书中介绍的一种或多种想法,从实验中学习经验,对项目进行调整,然后再次尝试。这种方式的美妙之处在于,良好的环境可以自我强化:所有这些努力可以互相支持,共同创造出一个有创造力、有趣、努力且效率极高的组织。如果你相信人本善,那么就应在工作中践行自己的信念。谷歌已经30多次被卓越职场研究所评为最佳雇主,另外还获得数百种支持女性、非裔美国人、老兵等人群的组织和政府、社会机构颁发的荣誉。但是我们并非第一个“最佳雇主”,也不会是最后一个,甚至在今日也不是唯一一个。谷歌真正擅长的是大规模运营,建立起的体系服务20亿人也如服务10人一样周到可靠。员工的创新得益于一批有先见之明的创始人、狂热的企业文化捍卫者、周密的学术研究,以及具有创造力的公司和政府。数千名谷歌人共同塑造了我们运营的方式,推动我们找到最具有创造力和最公平的方式解决与人相关的问题,使我们肩负起了责任。我有幸与见解深刻、勇于担当、富于创造力的同事和人力运营团队共事,竭尽全力才跟得上他们的步伐。我每天都能从他们身上获得启发。每年有成千上万的人参观我们的园区,问我们:“为什么这里的人这么开心?”“谷歌的秘密是什么?”“我在我的组织里做些什么才能使其更具创新性?”答案就在你的手中。谷歌工作法则1. 赋予工作意义2. 相信员工3. 只聘用比你更优秀的人4. 不要将职业发展与管理绩效混为一谈5. 关注团队的两端——最优员工和最差员工6. 既要节俭又要慷慨7. 不公平薪酬8. 助推9. 管理日益提升的期望10. 享受!然后回到第1条,再来一遍

后记

  • 我们一直围绕着4条基本原则构建谷歌人力运营部:1. 为实现极乐天堂而奋斗。2. 利用数据预测和塑造未来。3. 不遗余力地提高生产力。4. 创建非传统型团队。
  • 我选择血细胞来图示“人力资源正在做的工作”旨在强调我们的项目就如人体的循环系统一样无处不在且同样可靠。
  • 大多数公司,包括几年前的谷歌都会向升职的人道贺,但却毫不关注那些没有得到升职机会的人。这是非常愚蠢的行为。只需要一两个小时的时间找出你认为可能会因此沮丧的人,告诉他们如何才能得到持续发展。人们都希望受到这样的待遇。这样做从程序上讲更公正,有助于员工认同流程的开放性和可靠性。这样远比导致某人辞职,失去他们带来的产值,再寻找新人替代,聘用新人,引领新人走上高速通道这个过程对公司更有利。而且,在某人职业生涯非常脆弱的时刻,你这样做是帮助他们理解了发生的事情,利用一个消极事件激发他的动力。要构建这种能力需要花费一些时间,但是不管你所在组织的规模大小,开始这项工作都不是难事。
  • 她完全不知道电子数据表有一项功能可以做计算。我们需要留心所属专业的两端,并针对他们采取相应的行动。她的例子解释了为什么越来越多的公司将非人力资源从业人员安排为人力资源部的主管。
  • 情商高的人通常有更明晰的自我认知,因此也不会那么傲慢。这也使他们更容易转移到新的领域。
  • 教会整个团队一些传统人力资源团队不会学到的技巧,比如使用sQL或r等编程语言,或将员工面试中搜集的定性数据进行编码的方法。
  • 通过三分招聘模型的使用,我们招聘到具备各种能力的人:人力资源专业人员教会我们如何对员工和组织施加影响,识别不同的形态模式;咨询师可以提升我们对商业的理解力以及我们解决问题的水平;分析人员能提高我们所做各项工作的质量。
  • 在人力运营部中将我们所有人团结在一起的最重要因素在于我们共同的愿景,认为工作不必令人痛苦。工作可以令人更高雅、更有活力、更兴奋。这是推动我们努力的原因。

总结

  • 自由的状态是以自由表达为基础的,而自由表达又依靠对信息和真实情况的了解。(自由需要控制在一定的合理范围内?)
  • 从管理的核心角度来讲,权力的动态方向恰与自由背道而驰。
  • 剥夺管理者对员工的控制权。由一组同事、一个委员会或一个特别任命的独立团队做出。
  • 管理者服务于团队。管理者的关注重点不是惩罚或奖励,而是清除路障,鼓励团队。
  • 只有当企业着手给员工更多的自由时,业绩才能提升。
  • 坚信员工都是好的,再就是要有足够的勇气,把员工看成是企业的主人翁,而不是把他们当成机器。
  • 让处于绩效分布底端的人了解真相,但是不要将绩效与薪酬或职业成果直接挂钩,尽可能用一种积极的方式警示并激励他们。数百名经理需要面对自己并非好经理的现实。
  • 有效的管理不是简单粗暴地不允许你犯错,而是预见到可能发生的错误,提供一个合理的标准和方法,在错误发生之前就避免它。
  • 情商高的人通常有更明晰的自我认知,因此也不会那么傲慢。这也使他们更容易转移到新的领域。

管理借鉴

  1. 尽量创造自由的环境;(高自由度)
  2. 不能把员工当作机器;
  3. 会议时不坐在上首座位,避免潜在的等级关系;(除去显示权力和地位的象征符号)
  4. 尽量保持透明;
  5. 放弃一些控制权,就可以为团队创造一次提升的好机会,也给自己节省出更多时间应对新的挑战;
  6. 关注个人成长而不是评分和奖励,以此改善绩效;
  7. 把奖励分配谈话与员工发展谈话分开;
  8. 绩效交谈前发讲义,覆盖恰当的话题,引导讨论;
  9. 打造学习型组织;
最优秀经理手下工作的谷歌人在十几项Googlegeist评估维度上要比最差经理手下工作的谷歌人高5%至18%。除此之外,他们在以下几方面的认可度明显更高:
•职业决策更加公正。绩效评估公正,得到升职的都是实至名归的人选。
•个人的职业目标能够达成,他们的经理是非常有帮助的支持者和引导者。
•工作高效,决策迅速,资源分配合理,从多种视角考虑问题。
•团队成员之间没有等级制度,互相尊重,决策依据数据做出而不是靠耍手段,团队内部各人的工作和信念都保持透明。
•他们适当地参与到决策制定过程中,并且得到一定的授权去完成工作。
•他们可以自由地平衡工作和私人生活。

调查显示高分经理具备八种低分经理所不具备的共性:8个氧气项目特性
1.  做一名好的导师。
2.  给团队授权,不随便插手下属工作。
3.  表达出对团队成员的成功和个人幸福的兴趣和关心。
4.   高效/结果导向型。
5.   善于沟通——聆听和分享信息。
6.   在职业发展方面助力团队。
7.   对团队有清晰的愿景和战略。
8.   具备重要的技术技能,可为团队提供建议。

招聘借鉴

  1. 只聘用比你更优秀的人(至少某些特定的方面比你更优秀的。)
  2. 最优秀的人通常并不在寻找工作;
  3. 让面试者开心;
  4. 谷歌工作法则:筛选新雇员?□设定高质量标准□寻找自己的应聘者□客观评估应聘者□给应聘者一个加入的理由

【计算机科学速成课】笔记

发表于 2020-10-18
  • 【计算机科学速成课】[40集全/精校] - Crash Course Computer Science

Redis笔记

发表于 2020-10-11

脑图

命令

  • info memory 可查看Redis使用了jemalloc
  • Redis Config Get 命令 - 获取指定配置参数的值:https://www.redis.net.cn/order/3667.html
  • cluster nodes

Redis 客户端

  • https://redis.io/clients#java
  • Jedis
  • lettuce
  • Redisson

Jedis

连接方式

  1. Jedis直连
    1
    Jedis jedis = new Jedis("127.0.0.1",6379);
  2. Jedis连接池
    1
    2
    GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
    JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
  • Jedis是redis的java客户端,JedisCluster则是Jedis根据Redis集群的特性提供的集群客户端。

Jedis客户端如何定位到对应的主节点

  • 你不知道的Redis:RedisCluster与JedisCluster
  • JedisClusterInfoCache:关于缓存数据的获取及更新实际是由JedisClusterInfoCache的discoverClusterNodesAndSlots方法实现, 主要是通过cluster slots 命令获取集群内的槽位分布数据,然后解析该命令的返回结果,为每个主节点初始化一个连接池,然后将节点与连接池、节点负责的所有槽位与连接池的映射关系缓存
  • 初始化主要分为一下几部分:
    1. 连接一个节点执行cluster slots命令,获取槽位分布以及集群节点信息;
    2. 为每一个节点都初始化一个连接池,并跟节点建立映射关系缓存;
    3. 将每个主节点负责的槽位一一与主节点连接池建立映射缓存。
    4. 初始化工作中缓存的映射信息,在JedisCluster的使用过程中起到了至关重要的作用。但也正是因为JedisCluster在本地内存中缓存节点数据并且为每个节点维护一个连接池,在使用节点特别多的庞大集群时,客户端也会消耗更多内存。

Redis基本数据类型原理

  1. 字符串:redis没有直接使用C语言传统的字符串表示,而是自己实现的叫做简单动态字符串SDS的抽象类型。C语言的字符串不记录自身的长度信息,而SDS则保存了长度信息,这样将获取字符串长度的时间由O(N)降低到了O(1),同时可以避免缓冲区溢出和减少修改字符串长度时所需的内存重分配次数。
  2. 链表linkedlist:redis链表是一个双向无环链表结构,很多发布订阅、慢查询、监视器功能都是使用到了链表来实现,每个链表的节点由一个listNode结构来表示,每个节点都有指向前置节点和后置节点的指针,同时表头节点的前置和后置节点都指向NULL。
  3. 字典hashtable:用于保存键值对的抽象数据结构。redis使用hash表作为底层实现,每个字典带有两个hash表,供平时使用和rehash时使用,hash表使用链地址法来解决键冲突,被分配到同一个索引位置的多个键值对会形成一个单向链表,在对hash表进行扩容或者缩容的时候,为了服务的可用性,rehash的过程不是一次性完成的,而是渐进式的。
  4. 跳跃表skiplist:跳跃表是有序集合的底层实现之一,redis中在实现有序集合键和集群节点的内部结构中都是用到了跳跃表。redis跳跃表由zskiplist和zskiplistNode组成,zskiplist用于保存跳跃表信息(表头、表尾节点、长度等),zskiplistNode用于表示表跳跃节点,每个跳跃表的层高都是1-32的随机数,在同一个跳跃表中,多个节点可以包含相同的分值,但是每个节点的成员对象必须是唯一的,节点按照分值大小排序,如果分值相同,则按照成员对象的大小排序。
  5. 整数集合intset:用于保存整数值的集合抽象数据结构,不会出现重复元素,底层实现为数组。
  6. 压缩列表ziplist:压缩列表是为节约内存而开发的顺序性数据结构,他可以包含多个节点,每个节点可以保存一个字节数组或者整数值。

基于这些基础的数据结构,redis封装了自己的对象系统,包含字符串对象string、列表对象list、哈希对象hash、集合对象set、有序集合对象zset,每种对象都用到了至少一种基础的数据结构。

redis通过encoding属性设置对象的编码形式来提升灵活性和效率,基于不同的场景redis会自动做出优化。不同对象的编码如下:

  1. 字符串对象string:int整数、embstr编码的简单动态字符串、raw简单动态字符串
  2. 列表对象list:ziplist、linkedlist
  3. 哈希对象hash:ziplist、hashtable
  4. 集合对象set:intset、hashtable
  5. 有序集合对象zset:ziplist、skiplist

Redis为什么快

redis的速度非常的快,单机的redis就可以支撑每秒10几万的并发,相对于mysql来说,性能是mysql的几十倍。速度快的原因主要有几点:

  1. 完全基于内存操作
  2. C语言实现,优化过的数据结构,基于几种基础的数据结构,redis做了大量的优化,性能极高
  3. 使用单线程,无上下文的切换成本
  4. 基于非阻塞的IO多路复用机制

Redis6.0之后改用多线程

  • redis使用多线程并非是完全摒弃单线程,redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。
  • 这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高redis的性能。

主从同步的原理

  1. slave发送sync命令到master
  2. master收到sync之后,执行bgsave,生成RDB全量文件
  3. master把slave的写命令记录到缓存
  4. bgsave执行完毕之后,发送RDB文件到slave,slave执行
  5. master发送缓存中的写命令到slave,slave执行

配置参数

cluster-require-full-coverage

cluster-require-full-coverage= yes

  1. 任一master宕机 集群可用
  2. 同一组master和slave宕机 集群不可用
  3. 半数及以上master宕机 集群不可用

cluster-require-full-coverage= no

  1. 同一组master和slave宕机 集群可用
  2. 半数及以上master宕机 集群不可用

源码系列

  • 全面阐释Redis常见对象类型的底层数据结构

字符串SDS

  • 扩容策略:长度小于1M时每次扩容加倍;长度大于1M后每次扩容加1M

字典

  • 由两个hashtable组成,通常情况下只有一个有值。扩容时搬迁过程中两个都有值;
  • hashtable第一维是数组,第二维是链表;
  • 渐进式rehash:在后续的hset,hdel等指令逐步搬迁,同时有定时任务进行搬迁(单线程,一次性搬迁太耗时)

压缩列表(ziplist)

  • zset和hash在元素较少时使用ziplist存储
  • ziplist是连续的内存空间,元素紧凑存储,支持双向遍历

快速列表(quicklist)

跳跃列表(skiplist)

紧凑列表(listpack)

  • Redis 5.0

基数树(rax)

LFU

  • Least Frequently Used, 按最近的访问频率进行淘汰,比LRU更精准表示一个key的访问热度

工具

  • Redis Memory Analyzer:https://scalegrid.io/blog/the-top-6-free-redis-memory-analysis-tools/, https://stackoverflow.com/questions/49388547/get-the-redis-key-value-size-in-memory

Reference

  • [redis深度历险:核心原理与应用实践]
  • 关于Redis,你扛得住这夺命连环11问吗?

MySQL笔记

发表于 2020-10-03

思维导图

InnoDB 事务隔离级别

隔离级别 脏读 不可重复读 幻读
未提交读(RUC) NO NO NO
已提交读(RC) YES NO NO
可重复读(RR) YES YES NO
可串行化 YES YES YES

InnoDB 锁类型

共享/排它锁(Shared and Exclusive Locks)

在InnoDb中实现了两个标准的行级锁,可以简单的看为两个读写锁:

  1. S-共享锁:又叫读锁,其他事务可以继续加共享锁,但是不能继续加排他锁。
  2. X-排他锁: 又叫写锁,一旦加了写锁之后,其他事务就不能加锁了。
  • 兼容性:是指事务A获得一个某行某种锁之后,事务B同样的在这个行上尝试获取某种锁,如果能立即获取,则称锁兼容,反之叫冲突。

  • 纵轴是代表已有的锁,横轴是代表尝试获取的锁。

    . X(行级) S(行级)
    X(行级) 冲突 冲突
    S(行级) 冲突 兼容

意向锁(Intention Locks)

  • InnoDB为了支持多粒度锁机制(multiple granularity locking),即允许行级锁与表级锁共存,而引入了意向锁(intention locks)。意向锁是指,未来的某个时刻,事务可能要加共享/排它锁了,先提前声明一个意向。
  1. 意向共享锁:表达一个事务想要获取一张表中某几行的共享锁。
  2. 意向排他锁:表达一个事务想要获取一张表中某几行的排他锁。
  • 事务要获得某些行的S/X锁,必须先获得表对应的IS/IX锁,意向锁仅仅表明意向,意向锁之间相互兼容;虽然意向锁之间互相兼容,但是它与共享锁/排它锁互斥
  • 如果请求事务与当前存在的锁兼容,则授予锁。如果冲突则不会授予,事务会进行等待,直到冲突的锁被释放。永远不会在冲突情况下授予锁,因为会导致数据库的死锁
  • 意向共享锁/意向排他锁属于表锁,且取得意向共享锁/意向排他锁是取得共享锁/排他锁的前置条件。
. IX IS X(表级) S(表级)
IX 兼容 兼容 冲突 冲突
IS 兼容 兼容 冲突 兼容
X(表级) 冲突 冲突 冲突 冲突
S(表级) 冲突 兼容 冲突 兼容

意向锁的意义在哪里?

  1. IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突
  2. 意向锁是在添加行锁之前添加。
  3. 如果没有意向锁,当向一个表添加表级X锁时,就需要遍历整张表来判断是否存行锁,以免发生冲突
  4. 如果有了意向锁,只需要判断该意向锁与表级锁是否兼容即可。

MVCC

  • MVCC,多版本并发控制技术。在InnoDB中,在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号。通过版本号和行锁,从而提高数据库系统并发性能。

InnoDB 索引

  • InnoDB的主键索引与行记录是存储在一起的,故叫做聚集索引(Clustered Index):

InnoDB的表必须要有聚集索引

  1. 如果表定义了PK,则PK就是聚集索引;
  2. 如果表没有定义PK,则第一个非空unique列是聚集索引;
  3. 否则,InnoDB会创建一个隐藏的row-id作为聚集索引;
  • 聚集索引,也只能够有一个,因为数据行在物理磁盘上只能有一份聚集存储。

  • InnoDB的普通索引可以有多个,它与聚集索引是不同的:普通索引的叶子节点,存储主键(也不是指针)

索引使用

  • where条件中的and前后的顺序,不会影响索引的命中
  • 负向查询肯定不可以命中索引

InnoDB log

  • binlog 可以给备库使用,也可以保存起来用于恢复数据库历史数据。它是实现在 server 层的,所有引擎可以共用。redo log 是 InnoDB 特有的日志,用来支持 crash-safe 能力。

MySQL EXPLAIN

Extra

该列包含MySQL解决查询的详细信息,有以下几种情况:

  1. Using where:列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
  2. Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
  3. Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”
  4. Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
  5. Impossible where:这个值强调了where语句会导致没有符合条件的行。
  6. Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行

type

找到所需行的方式

  1. ALL: 扫描全表
  2. index: 扫描全部索引树
  3. range: 索引范围扫描
  4. ref: 非唯一性索引扫描
  5. eq_ref:唯一性索引扫描
  6. const:常量扫描,比如主键。

总结

  • Using filesort:当Query 中包含order by 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。
  • Using temporary:在某些操作中必须使用临时表时,在 Extra 信息中就会出现Using temporary ,主要常见于 GROUP BY 和 ORDER BY 等操作中

主要命令

  1. SHOW ENGINES; 命令查看 MySQL 支持的存储引擎。
  2. SHOW TABLE STATUS; 命令查看当前库中的表使用的是什么存储引擎。
  3. select * from information_schema.INNODB_LOCKS TODO
  4. show variables like '%tx_isolation%';查看事务隔离级别
  5. show engine innodb status 输出innodb监控可以查看到意向锁的信息
  6. show status like 'innodb_row_lock%';查看锁情况

其他

  1. 在 MySQL 数据库中,Database 和 Schema 是一对一的,所以 Database 和 Schema 是一个概念。
  2. 唯一索引会降级记录锁,这么做的理由是:非唯一索引加next-key锁由于不能确定明确的行数有可能其他事务在你查询的过程中,再次添加这个索引的数据,导致隔离性遭到破坏,也就是幻读。唯一索引由于明确了唯一的数据行,所以不需要添加间隙锁解决幻读。
  3. 间隙锁之间是兼容的。插入意向锁(IX)和间隙锁冲突。间隙锁 属于S锁???这样才符合表格的描述。
  4. 删除记录时,先查询出需要删除的记录主键,通过主键索引进行删除,可以避免产生间隙锁(唯一索引会降级记录锁)。
  5. 间隙锁(gap lock)与临键锁(next-key lock) 只在RR以上的级别生效,RC下会失效

注意事项

  1. 以固定的顺序访问表和行。交叉访问更容易造成事务等待回路。
  2. 尽量避免大事务,占有的资源锁越多,越容易出现死锁。建议拆成小事务。
  3. 降低隔离级别。如果业务允许(上面4.3也分析了,某些业务并不能允许),将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。
  4. 为表添加合理的索引。防止没有索引出现表锁,出现的死锁的概率会突增。
  5. 在删除之前,可以通过快照查询(不加锁),如果查询没有结果,则直接插入,如果有通过主键进行删除。如果查询的索引不含有唯一属性,不会降级成记录锁,而是间隙锁,插入时容易死锁。

Q&A

InnoDB选择什么列作为主键

  1. 不能为空的列;
  2. 不能重复的列;
  3. 很少改变的列;(行是按照聚集索引物理排序的,如果主键频繁改变,物理顺序会改变,性能会急剧降低。)
  4. 经常被检索(where key=XXX)的列; (被检索的列上要建立索引,如果该索引是聚集索引,能够避免回表,性能提升几乎一倍。)
  5. 不是太长的列;(普通索引叶子节点会存储主键值,如果主键值太长,会增加普通索引的大小。)

为什么 MySQL 索引选择了 B+树而不是 B 树?

  1. B+树更适合外部存储(一般指磁盘存储),由于内节点(非叶子节点)不存储 data,所以一个节点可以存储更多的内节点,每个节点能索引的范围更大更精确。也就是说使用 B+树单次磁盘 I/O 的信息量相比较 B 树更大,I/O 效率更高。
  2. MySQL 是关系型数据库,经常会按照区间来访问某个索引列,B+树的叶子节点间按顺序建立了链指针,加强了区间访问性,所以 B+树对索引列上的区间范围查询很友好。而 B 树每个节点的 key 和 data 在一起,无法进行区间查找。

扩展

InnoDB一棵B+树可以存放多少行数据?

  • https://www.cnblogs.com/leefreeman/p/8315844.html
  • 约2千万。(高度为3的B+树);一个高度为 3 的 B+ 树大概可以存放 1170 × 1170 × 16 = 21902400 行数据,已经是千万级别的数据量了。
  • InnoDB存储引擎最小储存单元——页(Page),一个页的大小默认是16K。
    • show variables like 'innodb_page_size';
    • innodb的所有数据文件(后缀为ibd的文件),他的大小始终都是16384(16k)的整数倍
  • 假设一行记录的数据大小为1k,实际上现在很多互联网业务数据记录大小通常就是1K左右
  • 非叶子节点能存放多少指针:假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,我们一个页中能存放多少这样的单元,其实就代表有多少指针,即16384/14=1170。那么可以算出一棵高度为2的B+树,能存放1170 × 16=18720条这样的数据记录。
  • 根据同样的原理我们可以算出一个高度为3的B+树可以存放:1170117016=21902400条这样的记录。所以在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次IO操作即可查找到数据。
  • 在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次IO操作即可查找到数据。
  • 怎么得到InnoDB主键索引B+树的高度?
    • 在实际操作之前,你可以通过InnoDB元数据表确认主键索引根页的page number为3,你也可以从《InnoDB存储引擎》这本书中得到确认。
    • SELECT b.name, a.name, index_id, type, a.space, a.PAGE_NO FROM information_schema.INNODB_SYS_INDEXES a, information_schema.INNODB_SYS_TABLES b WHERE a.table_id = b.table_id AND a.space <> 0;
  • 基于现有表的总大小和总行数,算出每一行占用的大概大小
    • 每行大概大小 ≈ total_size / total_rows
    • 对于InnoDB存储引擎,可以通过执行以下SQL查询来获取表的大小
        SELECT
        table_name AS `Table`,
        ROUND(((data_length + index_length) / 1024 / 1024), 2) AS `Size (MB)`
        FROM
        information_schema.tables
        WHERE
        table_schema = 'your_database_name' -- 替换为实际的数据库名
        AND table_name = 'your_table_name'; -- 替换为实际的表名        
        
    • 通过查看InnoDB存储引擎的.ibd文件来获取表的大小。每个InnoDB表都有一个对应的.ibd文件,其中包含了该表的数据和索引。
    • 3层B+树,每行大小1k(1个页16k,则可以存16条数据):可以记录的总大小大概为1170117016

MySQL InnoDB 引擎 RR 隔离级别是否解决了幻读?

  • https://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247489575&idx=2&sn=410aa5a43cb2cdc265dcd39e31128f17&chksm=eb539d11dc24140743b6b6f1369e958417cbe86b9f53809afe2744872f86675e753d9884f9e3&xtrack=1&scene=90&subscene=93&sessionid=1559142508&clicktime=1559142541&ascene=56&devicetype=android-26&version=2700043b&nettype=WIFI&abtest_cookie=BQABAAoACwASABMAFQAHACOXHgBWmR4AyJkeANyZHgDzmR4AA5oeAAyaHgAAAA%3D%3D&lang=zh_CN&pass_ticket=W5ig5maP6tmaLevaqwsMcnXl28LHoqSmvBuqMPbg7dOQBytHnUWtVKFBwtS2hFz6&wx_header=1

  • Mysql官方给出的幻读解释是:只要在一个事务中,第二次select多出了row就算幻读。

  • a事务先select,b事务insert确实会加一个gap锁,但是如果b事务commit,这个gap锁就会释放(释放后a事务可以随意dml操作),a事务再select出来的结果在MVCC下还和第一次select一样,接着a事务不加条件地update,这个update会作用在所有行上(包括b事务新加的),a事务再次select就会出现b事务中的新行,并且这个新行已经被update修改了,实测在RR级别下确实如此。
    如果这样理解的话,Mysql的RR级别确实防不住幻读。

  • 在快照读读情况下,mysql通过mvcc来避免幻读。
    在当前读读情况下,mysql通过next-key来避免幻读。
    select * from t where a=1;属于快照读
    select * from t where a=1 lock in share mode;属于当前读

不能把快照读和当前读得到的结果不一样这种情况认为是幻读,这是两种不同的使用。所以MySQL 存储引擎 InnoDB 隔离级别 RR 解决了幻读问题。

结论

  1. MySQL 存储引擎 InnoDB 隔离级别 RR 解决了幻读问题。
  2. 不能把快照读和当前读得到的结果不一样这种情况认为是幻读,这是两种不同的使用。
  3. 如果要update,不能出现幻读的情况,之前应该加上for update查询;不需要update,只是读,快照读已经使用mvcc解决幻读问题。

Reference

  • MySQL 体系结构-概述
  • MySQL 体系结构-主要文件
  • MySQL 参数- Innodb_File_Per_Table(独立表空间)
  • 为什么开发人员必须要了解数据库锁?
  • 主键,不少人以为自己懂了,却不透彻…
  • 如何避免回表查询?什么是索引覆盖?
  • InnoDB架构,一幅图秒懂!
  • 事务已提交,数据却丢了,赶紧检查下这个配置
  • 丁奇:MySQL 中 6 个常见的日志问题
  • 再深入一点|binlog 和 relay-log 到底长啥样?
  • MySQL InnoDB 引擎中的 7 种锁类型,你都知道吗?
  • 锁机制与 InnoDB 锁算法
  • MySQL常见的七种锁详细介绍 !!
  • MySQL中InnoDB的锁分类
  • 浅谈MySQL的七种锁
  • 别废话,各种SQL到底加了什么锁?
  • MySQL Explain详解
  • 记一次 MySQL 性能优化过程
  • MySQL索引前世今生

关于CLOSE_WAIT和HttpClient的使用

发表于 2020-09-26


ESTABLISHED 表示正在进行网络连接的数量
TIME_WAIT 表示表示等待系统主动关闭网络连接的数量
CLOSE_WAIT 表示被动等待程序关闭的网络连接数量

  1. 查看系统TCP状态的命令:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
  2. CLOSE_WAIT 是被动关闭产生的一种状态,当用户程序正常close之后将变成LAST_ACK状态。
  3. TIME_WAIT状态可以通过优化服务器参数得到解决(当然也有可能是程序处理不当产生太多连接)。而CLOSE_WAIT数目过大一般是由于程序被动关闭连接处理不当导致的。
  4. 以HttpClient为例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    try {
    String resp = "";
    HttpResponse response = client.execute(get);
    if (response.getStatusLine().getStatusCode() != 200) {
    get.abort();
    return "";
    }
    HttpEntity entity = response.getEntity();
    if (entity != null) {
    in = entity.getContent();
    resp = in.xxx;
    //xxx
    }
    return resp;
    } catch (Exception e) {
    get.abort();
    return "";
    } finally {
    if (in != null) {
    in.close();
    }
    }
    在异常时显示调用abort,直接中止本次连接,避免in未赋值导致连接未关闭的问题。
  5. HttpClient连接关闭。一种是主动,一种是被动。在代码API的使用上没进行区分。主动关闭时当调用Close(),发出FIN包由ESTABLISHED进入FIN_WAIT_1 状态;被动关闭时当调用Close(),发出FIN包由CLOSE_WAIT进入LAST_ACK状态。
  6. 使用PoolingClientConnectionManager?

扩展

httpclient 的timeout参数

  • httpclient SocketTimeout ConnectTimeout ConnectionRequestTimeout
  • ConnectionRequestTimeout
    • httpclient使用连接池来管理连接,这个时间就是从连接池获取连接的超时时间,可以想象下数据库连接池;
  • ConnectTimeout
    • 连接建立时间,三次握手完成时间;
  • SocketTimeout
    • 关于readimeout的含义: Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.
    • 数据传输过程中数据包之间间隔的最大时间;
    • SocketTimeout的值表示的是“a”、”b”、”c”这三个报文,每两个相邻的报文的间隔时间不能超过SocketTimeout
    • 虽然报文(“abc”)返回总共用了6秒,如果SocketTimeout设置成4秒,实际程序执行的时候是不会抛出java.net.SocketTimeoutException: Read timed out异常的

Reference

  • 服务器TIME_WAIT和CLOSE_WAIT详解和解决办法
  • HttpClient连接池抛出大量ConnectionPoolTimeoutException: Timeout waiting for connection异常排查

分布式一致性协议概览

发表于 2020-09-12
  • 本文内容基本来源:网上资料总结

共识(Consensus) 和 一致性(Consistency)

  • 分布式一致性(共识)协议 (consensus protocol)
  • Consensus != Consistency
  • CAP 定理中的 C 和数据库 ACID 的 C 才是真正的“一致性”—— consistency 问题
  • 在早些的文献中,共识(consensus)也叫做协商(agreement)
  • 共识(Consensus),很多时候会见到与一致性(Consistency)术语放在一起讨论。严谨地讲,两者的含义并不完全相同。
  • 一致性的含义比共识宽泛,在不同场景(基于事务的数据库、分布式系统等)下意义不同。具体到分布式系统场景下,一致性指的是多个副本对外呈现的状态。如前面提到的顺序一致性、线性一致性,描述了多节点对数据状态的共同维护能力。而共识,则特指在分布式系统中多个节点之间对某个事情(例如多个事务请求,先执行谁?)达成一致意见的过程。因此,达成某种共识并不意味着就保障了一致性。
  • 实践中,要保证系统满足不同程度的一致性,往往需要通过共识算法来达成。
  • 分布式之系统底层原理

共识问题

  • 在分布式系统中,共识就是系统中的多个节点对某个值达成一致。共识问题可以用数学语言来描述:一个分布式系统包含 n 个进程 {0, 1, 2,…, n-1},每个进程都有一个初值,进程之间互相通信,设计一种算法使得尽管出现故障,进程们仍协商出某个不可撤销的最终决定值,且每次执行都满足以下三个性质:
    • 终止性(Termination):所有正确的进程最终都会认同某一个值。
    • 协定性(Agreement):所有正确的进程认同的值都是同一个值。
    • 完整性(Integrity),也称作有效性(Validity):如果正确的进程都提议同一个值,那么所有处于认同状态的正确进程都选择该值。
  • 完整性可以有一些变化,例如,一种较弱的完整性是认定值等于某些正确经常提议的值,而不必是所有进程提议的值。完整性也隐含了,最终被认同的值必定是某个节点提出过的。
  • 算法共识/一致性算法有两个最核心的约束:1) 安全性(Safety),2) 存活性(Liveness):
    • Safety:保证决议(Value)结果是对的,无歧义的,不会出现错误情况。
      • 只有是被提案者提出的提案才可能被最终批准;
      • 在一次执行中,只批准(chosen)一个最终决议。被多数接受(accept)的结果成为决议;
    • Liveness:保证决议过程能在有限时间内完成。
      • 决议总会产生,并且学习者最终能获得被批准的决议。
  • 根据解决的场景是否允许拜占庭(Byzantine)错误,共识算法可以分为 Crash Fault Tolerance (CFT) 和 Byzantine Fault Tolerance(BFT)两类。
    • 对于非拜占庭错误的情况,已经存在不少经典的算法,包括 Paxos(1990 年)、Raft(2014 年)及其变种等。这类容错算法往往性能比较好,处理较快,容忍不超过一半的故障节点。
    • 对于要能容忍拜占庭错误的情况,包括 PBFT(Practical Byzantine Fault Tolerance,1999 年)为代表的确定性系列算法、PoW(1997 年)为代表的概率算法等。确定性算法一旦达成共识就不可逆转,即共识是最终结果;而概率类算法的共识结果则是临时的,随着时间推移或某种强化,共识结果被推翻的概率越来越小,最终成为事实上结果。拜占庭类容错算法往往性能较差,容忍不超过 1/3 的故障节点。
  • 副本控制协议可以分为两大类:“中心化(centralized)副本控制协议”和“去中心化(decentralized)副本控制协议”。

分布式系统的几个主要难题

  1. 网络问题
  2. 时钟问题
  3. 节点故障问题

达成共识还可以解决分布式系统中的以下经典问题

  1. 互斥(Mutual exclusion):哪个进程进入临界区访问资源?
  2. 选主(Leader election):在单主复制的数据库,需要所有节点就哪个节点是领导者达成共识。如果一些由于网络故障而无法与其他节点通信,可能会产生两个领导者,它们都会接受写入,数据就可能会产生分歧,从而导致数据不一致或丢失。
  3. 原子提交(Atomic commit):跨多节点或跨多分区事务的数据库中,一个事务可能在某些节点上失败,但在其他节点上成功。如果我们想要维护这种事务的原子性,必须让所有节点对事务的结果达成共识:要么全部提交,要么全部中止/回滚。
  • 总而言之,在共识的帮助下,分布式系统就可以像单一节点一样工作——所以共识问题是分布式系统最基本的问题。

FLP 不可能(FLP Impossibility)

  • 早在 1985 年,Fischer、Lynch 和 Paterson (FLP)在 “Impossibility of Distributed Consensus with One Faulty Process[5]” 证明了:在一个异步系统中,即使只有一个进程出现了故障,也没有算法能保证达成共识。
  • 简单来说,因为在一个异步系统中,进程可以随时发出响应,所以没有办法分辨一个进程是速度很慢还是已经崩溃,这不满足终止性(Termination)。
  • FLP给后来的人们提供了研究的思路——不再尝试寻找异步通信系统中共识问题完全正确的解法。FLP 不可能是指无法确保达成共识,并不是说如果有一个进程出错,就永远无法达成共识。

同步系统中的共识

  • Dolev 和 Strong 在论文 “Authenticated Algorithms for Byzantine Agreement[9]” 中证明了:同步系统中,如果 N 个进程中最多有 f 个会出现崩溃故障,那么经过 f + 1 轮消息传递后即可达成共识。
  • 在一个有 f 个拜占庭故障节点的系统中,必须总共至少有 3f + 1 个节点才能够达成共识。即 N >= 3f + 1。
  • 虽然同步系统下拜占庭将军问题的确存在解,但是代价很高,需要 O(N^f+1 ) 的信息交换量,只有在那些安全威胁很严重的地方使用(例如:航天工业)
  • PBFT(Practical Byzantine Fault Tolerance)[12] 算法顾名思义是一种实用的拜占庭容错算法,由 Miguel Castro 和 Barbara Liskov 发表于 1999 年。
  • 算法的主要细节不再展开。PBFT 也是通过使用同步假设保证活性来绕过 FLP 不可能。PBFT 算法容错数量同样也是 N >= 3f + 1,但只需要 O(n^2 ) 信息交换量,即每台计算机都需要与网络中其他所有计算机通讯。

一致性模型

  • 一致性(Consistency)是指多副本(Replications)问题中的数据一致性。
  1. 强一致性:数据更新成功后,任意时刻所有副本中的数据都是一致的,一般采用同步的方式实现。
  2. 弱一致性:数据更新成功后,系统不承诺立即可以读到最新写入的值,也不承诺具体多久之后可以读到。
  3. 最终一致性:弱一致性的一种形式,数据更新成功后,系统不承诺立即可以返回最新写入的值,但是保证最终会返回上一次更新操作的值。
  • 分布式中一致性是非常重要的,分为弱一致性和强一致性。现在主流的一致性协议一般都选择的是弱一致性的特殊版本:最终一致性。

CAP

  • CAP是指在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)这三个要素最多只能同时实现两点,不可能三者兼顾。
  • CAP理论提出就是针对分布式环境的,所以,P 这个属性是必须具备的。
  1. Consistency 一致性
    一致性指“all nodes see the same data at the same time”,即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致。等同于所有节点拥有数据的最新版本。
    CAP中的C指的是强一致性。
  2. Availability 可用性
    可用性指“Reads and writes always succeed”,即服务一直可用,而且是正常响应时间。
    对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。如果不考虑一致性,这个是很好实现的,立即返回本地节点的数据即可,而不需要等到数据一致才返回。
  3. Partition Tolerance 分区容忍性
    Tolerance也可以翻译为容错,分区容忍性具体指“the system continues to operate despite arbitrary message loss or failure of part of the system”,即系统容忍网络出现分区,分区之间网络不可达的情况,分区容忍性和扩展性紧密相关,Partition Tolerance特指在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
  • 传统数据库都是假设不保证P的,因为传统数据库都是单机或者很小的本地集群,假设网络不存在问题,出现问题手工修复。所以,损失分区容错(P)只保证CA相当于就是一个单体应用,根本不是分布式。

  • 分布式是要求单个节点故障(概率太高了)系统仍能完成运行。搭建分布式就是间接要求必须保证P,即P是现实,那C和A就无法同时做到,需要在这两者之间做平衡。

  • 像银行系统,是通过损失可用性(A)来保障CP,银行系统是内网,很少出现分区不可达故障状态,一旦出现,不可达的节点对应的ATM就没法使用,即变为不可用。同时如果数据在各分区未达到一致,ATM也是Loading状态即不可用。

  • 在互联网实践中,可用性又是极其重要的,因此大部分是通过损失一致性(C)来保障AP,当然也非完全牺牲一致性,使用弱一致性,即一定时间后一致的弱一致性,当数据还在同步时(WRITE之后),使用上一次的数据。

  • Google 2009年 在Transaction Across DataCenter 的分享中,对一致性协议在业内的实践做了一简单的总结,如下图所示,这是 CAP 理论在工业界应用的实践经验。

BASE 理论

  • Basically Available(基本可用)
  • Soft state(软状态)
  • Eventually consistent(最终一致性)
  • BASE 理论是对 CAP 中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
  • BASE理论是对大规模的互联网分布式系统实践的总结,用弱一致性来换取可用性,不同于ACID,属于AP系统。

ACID

  • ACID(Atomicity原子性,Consistency一致性,Isolation隔离性,Durability持久性)是事务的特点,具有强一致性,一般用于单机事务,分布式事务若采用这个原则会丧失一定的可用性,属于CP系统。

分类

按单主和多主进行分类

  1. 单主协议,即整个分布式集群中只存在一个主节点。主备复制、2PC、 Paxos、Raft、ZAB。
    • (不允许数据分歧):整个分布式系统就像一个单体系统,所有写操作都由主节点处理并且同步给其他副本。
  2. 多主协议,即整个集群中不只存在一个主节点。Pow、Gossip协议。
    • (允许数据分歧):所有写操作可以由不同节点发起,并且同步给其他副本。
  • 单主协议由一个主节点发出数据,传输给其余从节点,能保证数据传输的有序性。而多主协议则是从多个主节点出发传输数据,传输顺序具有随机性,因而数据的有序性无法得到保证,只保证最终数据的一致性。这是单主协议和多主协议之间最大的区别。
---单主--主备复制、2PC、 Paxos、Raft、ZAB
|
---多主--Pow、Gossip

按CAP中的P分类

  • 分区容忍的一致性协议跟所有的单主协议一样,它也是只有一个主节点负责写入(提供顺序一致性),但它跟 2PC 的区别在于它只需要保证大多数节点(一般是超过半数)达成一致就可以返回客户端结果,这样可以提高了性能,同时也能容忍网络分区(少数节点分区不会导致整个系统无法运行)。分区容忍的一致性算法保证大多数节点数据一致后才返回客户端,同样实现了顺序一致性。
---非P--主备复制、2PC
|
---P   --Paxos、Raft

算法简介

1、主备复制

  • 主备复制可以说是最常用的数据复制方法,也是最基础的方法,很多其他协议都是基于它的变种。 主备复制要求所有的写操作都在主节点上进行,然后将操作的日志发送给其他副本。可以发现由于主备复制是有延迟的,所以它实现的是最终一致性。
  • 主备复制的实现方式:主节点处理完写操作之后立即返回结果给客户端,写操作的日志异步同步给其他副本。这样的好处是性能高,客户端不需要等待数据同步,缺点是如果主节点同步数据给副本之前数据缺失了,那么这些数据就永久丢失了。MySQL 的主备同步就是典型的异步复制。

2、2PC

  • 2PC 是典型的 CA 系统,为了保证一致性和可用性,2PC 一旦出现网络分区或者节点不可用就会被拒绝写操作,把系统变成只读的。
  • 由于 2PC 容易出现节点宕机导致一直阻塞的情况,所以在数据复制的场景中不常用,一般多用于分布式事务中。
  • 如果网络环境较好,该协议一般还是能很好的工作的,2PC广泛应用于关系数据库的分布式事务处理,如mysql的内部与外部XA都是基于2PC的,一般想要把多个操作打包未原子操作也可以用2PC。
|---1. Prepare(Vote Request) 
|
|---2. Global Commit (1- return (Vote Commit)) (正常流程)
|
|---2. Global Rollback (1- return (Vote Abort)) (异常流程)
  • 缺点:
    1. 性能问题(两个阶段都涉及同步等待阻塞,极大降低了吞吐量)
    2. 协调者单点故障问题
    3. 丢失消息导致的数据不一致问题

3、3PC

  • 相对于2PC,3PC主要解决的单点故障问题,并减少阻塞。在2PC的基础上增加了CanCommit阶段,并引入了超时机制。一旦事务参与者迟迟没有收到协调者的Commit请求,就会自动进行本地commit,这样相对有效地解决了协调者单点故障的问题;但是性能问题和不一致问题仍然没有根本解决。

  • CanCommit阶段: 检查下自身状态的健康性,看有没有能力进行事务操作。

  • 和2PC区别:

    1. 相比较2PC而言,3PC对于协调者(Coordinator)和参与者(Partcipant)都设置了超时时间,而2PC只有协调者才拥有超时机制。这个优化点,主要是避免了参与者在长时间无法与协调者节点通讯(协调者挂掉了)的情况下,无法释放资源的问题,因为参与者自身拥有超时机制会在超时后,自动进行本地commit从而进行释放资源。而这种机制也侧面降低了整个事务的阻塞时间和范围。
    2. 通过CanCommit、PreCommit、DoCommit三个阶段的设计,相较于2PC而言,多设置了一个缓冲阶段保证了在最后提交阶段之前各参与节点的状态是一致的。
  • 无论是2PC还是3PC都无法彻底解决分布式的一致性问题。Google Chubby的作者Mike Burrows说过,“there is only one consensus protocol, and that’s Paxos”——all other approaches are just broken versions of Paxos。意即世上只有一种一致性算法,那就是Paxos,所有其他一致性算法都是Paxos算法的不完整版。

4、MVCC

  • MVCC(Multi-version Cocurrent Control,多版本并发控制)技术。MVCC 技术最初也是在数据库系统中被提出,但这种思想并不局限于单机的分布式系统,在分布式系统中同样有效。

5、Paxos协议

  • 2PC、3PC 两个协议的协调者都需要人为设置而无法自动生成,是不完整的分布式协议,而Paxos 就是一个真正的完整的分布式算法。系统一共有几个角色:Proposer(提出提案)、Acceptor(参与决策)、Learner(不参与提案,只负责接收已确定的提案,一般用于提高集群对外提供读服务的能力),实践中一个节点可以同时充当多个角色。
  • 作者在描述Paxos时,列举了希腊城邦选举的例子,所以该算法又被称为希腊城邦算法。
  • Paxos是非常经典的一致性协议,但是因为过于理论化,难以直接工程化,因此工业界出现了诸多基于Paxos思想出发的变种。虽然这些变种最终很多都和原始的Paxos有比较大的差距,甚至完全演变成了新的协议,但是作为奠基者的Paxos在分布式一致性协议中依然持有不可撼动的地位。
  • Paxos协议的容错性很好,只要有超过半数的节点可用,整个集群就可以自己进行Leader选举,也可以对外服务,通常用来保证一份数据的多个副本之间的一致性,适用于构建一个分布式的一致性状态机。
  • Google的分布式锁服务Chubby就是用了Paxos协议,而开源的ZooKeeper使用的是Paxos的变种ZAB协议。

6、Raft协议

  • Raft协议是斯坦福的Diego Ongaro、John Ousterhout两人于2013年提出,作者表示流行的Paxos算法难以理解,且其过于理论化致使直接应用于工程实现时出现很多困难,因此作者希望提出一个能被大众比较容易地理解接受,且易于工程实现的协议。Raft由此应运而生。不得不说,Raft作为一种易于理解,且工程上能够快速实现一个较完整的原型的算法,受到业界的广泛追捧。
  • Raft协议对标Paxos,容错性和性能都是一致的,但是Raft比Paxos更易理解和实施。系统分为几种角色:Leader(发出提案)、Follower(参与决策)、Candidate(Leader选举中的临时角色)。
  • 在Raft协议出来之前,Paxos是分布式领域的事实标准,但是Raft的出现打破了这一个现状(raft作者也是这么想的,请看论文),Raft协议把Leader选举、日志复制、安全性等功能分离并模块化,使其更易理解和工程实现,将来发展怎样我们拭目以待(挺看好)。
  • Raft协议目前被用于 cockrouchDB,TiKV等项目中
  • Raft 算法实际上是 Multi-Paxos 的一个变种,通过新增两个约束:
    • 追加日志约束:Raft 中追加节点的日志必须是串行连续的,而 Multi-Paxos 中则可以并发追加日志(实际上 Multi-Paxos 的并发也只是针对日志追加,最后应用到内部 State Machine 的时候还是必须保证顺序)。
    • 选主限制:Raft 中只有那些拥有最新、最全日志的节点才能当选 Leader 节点,而 Multi-Paxos 由于允许并发写日志,因此无法确定一个拥有最新、最全日志的节点,因此可以选择任意一个节点作为 Leader,但是选主之后必须要把 Leader 节点的日志补全。
    • 基于这两个限制,Raft 算法的实现比 Multi-Paxos 更加简单易懂,不过由于 Multi-Paxos 的并发度更高,因此从理论上来说 Multi-Paxos 的性能会更好一些,但是到现在为止业界也没有一份权威的测试报告来支撑这一观点。

Paxos和Raft的对比

  • Paxos算法和Raft算法有显而易见的相同点和不同点。二者的共同点在于,它们本质上都是单主的一致性算法,且都以不存在拜占庭将军问题作为前提条件。二者的不同点在于,Paxos算法相对于Raft,更加理论化,原理上理解比较抽象,仅仅提供了一套理论原型,这导致很多人在工业上实现Paxos时,不得已需要做很多针对性的优化和改进,但是改进完却发现算法整体和Paxos相去甚远,无法从原理上保证新算法的正确性,这一点是Paxos难以工程化的一个很大原因。相比之下Raft描述清晰,作者将算法原型的实现步骤完整地列在论文里,极大地方便了业界的工程师实现该算法,因而能够受到更广泛的应用。
  • 从根本上来看,Raft的核心思想和Paxos是非常一致的,甚至可以说,Raft是基于Paxos的一种具体化实现和改进,它让一致性算法更容易为人所接受,更容易得到实现。由此亦可见,Paxos在一致性算法中的奠基地位是不可撼动的。

7、Gossip算法

  • Gossip又被称为流行病算法,它与流行病毒在人群中传播的性质类似,由初始的几个节点向周围互相传播,到后期的大规模互相传播,最终达到一致性。
  • Gossip协议与上述所有协议最大的区别就是它是去中心化的,上面所有的协议都有一个类似于Leader的角色来统筹安排事务的响应、提交与中断,但是Gossip协议中就没有Leader,每个节点都是平等的。
  • Gossip协议被广泛应用于P2P网络,同时一些分布式的数据库,如Redis集群的消息同步使用的也是Gossip协议,另一个重大应用是被用于比特币的交易信息和区块信息的传播。
  • 去中心化的Gossip看起来很美好:没有单点故障,看似无上限的对外服务能力……本来随着Cassandra火了一把,但是现在Cassandra也被抛弃了,去中心化的架构貌似难以真正应用起来。归根到底我觉得还是因为去中心化本身管理太复杂,节点之间沟通成本高,最终一致等待时间较长……往更高处看,一个企业(甚至整个社会)不也是需要中心化的领导(或者制度)来管理吗,如果没有领导(或者制度)管理,大家就是一盘散沙,难成大事啊。
  • 事实上现代互联网架构只要把单点做得足够强大,再加上若干个强一致的热备,一般问题都不大。
  • 应用:数据同步;缺点:节点之间沟通成本高,最终一致等待时间较长

8、Pow(Proof of work)

  • Proof-of-work算法又被称为Pow算法。工作量证明算法。
  • Pow最为人所熟知的应用是比特币。代表者是比特币(BTC),区块链1.0
  • PoW(Proof of Work,工作量证明)的字面意思是谁干的活多,谁的话语权就大,在一定层面上类似于现实生活中“多劳多得”的概念。以比特币为例,比特币挖矿就是通过计算符合某一个比特币区块头的哈希散列值争夺记账权。这个过程需要通过大量的计算实现,简单理解就是挖矿者进行的计算量越大(工作量大),它尝试解答问题的次数也就变得越多,解出正确答案的概率自然越高,从而就有大概率获得记账权,即该矿工所挖出的区块被串接入主链。
  • 基于PoW节点网络的安全性令人堪忧。大于51%算力的攻击。
  • 51%算力攻击目前仅在“PoW”共识机制中存在,因为“PoW”共识机制依赖算力计算获胜,也就是谁算得快,谁的胜率就高。在使用了“PoW”共识机制的区块链网络中,我们称参与计算哈希的所有计算机资源为算力,那么全网络的算力就是100%,当超过51%的算力掌握在同一阵营中时,这个阵营的计算哈希胜出的概率将会大幅提高。为什么是51%?50.1%不行吗?当然也是可以的,之所以取51%是为了取一个最接近50%,且比50%大的整数百分比,这样当算力值达到51%后的效果将会比50.1%的计算效果更明显。举个例子,如果诚实节点的算力值是50.1%,那么坏节点的算力值就是49.9%。两者的差距不算太大,这样容易导致最终的区块竞争你来我往、长期不分上下。如果算力资源分散,不是高度集中的,那么整个区块链网络是可信的。然而,当算力资源集中于某一阵营的时候,算力的拥有者就能使用算力资源去逆转区块,导致区块链分叉严重,

9、PoS(Proof of Stake)

  • 代表者是以太坊(ETH),以太坊正在从PoW过渡到PoS,区块链2.0
  • PoS(Proof of Stake,股权证明)是由点点币(PPCoin)首先应用的。该算法没有挖矿过程,而是在创世区块内写明股权分配比例,之后通过转让、交易的方式,也就是我们说的IPO(Initial Public Offerings)公开募股方式,逐渐分散到用户钱包地址中去,并通过“利息”的方式新增货币,实现对节点地址的奖励。PoS的意思是股份制。也就是说,谁的股份多,谁的话语权就大,这和现实生活中股份制公司的股东差不多。但是,在区块链的应用中,我们不可能真实地给链中的节点分配股份,取而代之的是另外一些东西,例如代币,让这些东西来充当股份,再将这些东西分配给链中的各节点。
  • PoS共识算法具有下面的优缺点:(1)优点•缩短了共识达成的时间,链中共识块的速度更快。•不再需要大量消耗能源挖矿,节能。•作弊得不偿失。如果一名持有多于50%以上股权的人(节点)作弊,相当于他坑了自己,因为他是拥有股权最多的人,作弊导致的结果往往是拥有股权越多的人损失越多。(2)缺点•攻击成本低,只要节点有物品数量,例如代币数量,就能发起脏数据的区块攻击。•初始的代币分配是通过IPO方式发行的,这就导致“少数人”(通常是开发者)获得了大量成本极低的加密货币,在利益面前,很难保证这些人不会大量抛售。•拥有代币数量大的节点获得记账权的概率会更大,使得网络共识受少数富裕账户支配,从而失去公正性。
  • 区块链2.0仍存在性能上的缺陷,难以支持大规模的商业应用开发。与支付宝在“双十一”时26.5万笔交易/秒的性能相比,像以太坊这样的区块链系统只能做到几百笔交易/秒的水平。交易需由多个参与方确认,是影响区块链性能的主要原因。

10、DPoS

  • 代表者是柚子(EOS),区块链3.0

11、

  • PBFT拜占庭容错,联盟链中常用。

Gossip算法和Pow算法对比

  • 同为去中心化算法,Gossip算法和Pow算法都能实现超大集群的一致性,但是它们的特性可谓有天壤之别。Gossip算法往往应用于超大集群快速达成一致性的目的。它的特性是如流感一般超强的传播速度,以及自身能够管理的数量可观的节点数。但是对于流传的消息没有特别的管控,无法辨别其中的虚假信息,并且只关注与最终的一致性,不关心消息的顺序性。而Pow算法则完全专注于尽可能地解决“拜占庭将军”问题,防止消息的篡改。它可以不计代价地去要求各个节点参与竞选,以付出巨大算力为代价保证平台的安全性。

应用

  • 区块链:PoW、PoS、Gossip

总结

2PC和TCC什么关系

  1. 2PC在“分布式一致性协议”的范畴,属于CA层面的一个协议,一般作为和其他协议(PAXOS,Raft)进行对比的形式出现。

  2. 2PC在“分布式事务”的范畴,属于数据库层面,XA协议的基础。TCC算是一种特殊的2PC。TCC事务的处理流程与2PC两阶段提交类似,不过2PC通常都是在跨库的DB层面,而TCC本质上就是一个应用层面的2PC,需要通过业务逻辑来实现。

  3. TCC是分布式事务的范畴,但其本质也是分布式一致性的一种协议,只是特指业务上的协议。而一般情况下我们所说的分布式一致性协议,一般是指底层系统实现上的,偏向基础服务上的。如果以后有人对TCC进行改造,描述出底层系统(非业务)的TCC,那么它也属于这篇文章所包含的其中一种分布式一致性协议。对于其他分布式事务的实现方案同理。

其他

  • 从Paxos到Raft再到EPaxos:一文总结:分布式一致性技术是如何演进的?
  • 众所周知,Paxos是出了名的晦涩难懂,不仅难以理解,更难以实现。而Raft则以可理解性和易于实现为目标,Raft的提出大大降低了使用分布式一致性的门槛,将分布式一致性变的大众化、平民化,因此当Raft提出之后,迅速得到青睐,极大地推动了分布式一致性的工程应用。
  • EPaxos的提出比Raft还早,但却长期无人问津,很大一个原因就是EPaxos实在是难以理解。EPaxos基于Paxos,但却比Paxos更难以理解,大大地阻碍了EPaxos的工程应用。不过,是金子总会发光的,EPaxos因着它独特的优势,终于被人们发现,具有广阔的前景。
  • EPaxos更适用于跨AZ跨地域场景,对可用性要求极高的场景,Leader容易形成瓶颈的场景。Multi-Paxos和Raft本身非常相似,适用场景也类似,适用于内网场景,一般的高可用场景,Leader不容易形成瓶颈的场景。

Reference

  • 分布式一致性协议概述
  • 分布式系统:一致性协议
  • 分布式一致性协议
  • 分布式事务:深入理解什么是2PC、3PC及TCC协议
  • 详解分布式一致性机制
  • 漫谈分布式共识问题!!
  • 分布式之系统底层原理!!!!
  • 深度介绍分布式系统原理与设计
  • [区块链:以太坊DApp开发实战]
  • [区块链:分布式商业与智数未来]
<1…161718…22>

211 日志
1 分类
275 标签
RSS
© 2026 Kingson Wu
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4