diff --git a/2021/08/index.html b/2021/08/index.html index efe6a7a5..3c6200b7 100644 --- a/2021/08/index.html +++ b/2021/08/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -394,7 +394,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -431,13 +431,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2021/09/index.html b/2021/09/index.html index b1139734..c377257c 100644 --- a/2021/09/index.html +++ b/2021/09/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -394,7 +394,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -431,13 +431,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2021/10/index.html b/2021/10/index.html index 3064d6a6..3263e03d 100644 --- a/2021/10/index.html +++ b/2021/10/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -354,7 +354,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -391,13 +391,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2021/11/index.html b/2021/11/index.html index 25d569b9..28acfffe 100644 --- a/2021/11/index.html +++ b/2021/11/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -374,7 +374,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -411,13 +411,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2021/12/index.html b/2021/12/index.html index 8515f9d3..5bcee1f6 100644 --- a/2021/12/index.html +++ b/2021/12/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -334,7 +334,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -371,13 +371,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2021/index.html b/2021/index.html index cc9c259c..688ed2b8 100644 --- a/2021/index.html +++ b/2021/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -477,7 +477,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -514,13 +514,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2021/page/2/index.html b/2021/page/2/index.html index cdb29c46..0433bf6b 100644 --- a/2021/page/2/index.html +++ b/2021/page/2/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -477,7 +477,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -514,13 +514,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2021/page/3/index.html b/2021/page/3/index.html index ad8fd8cb..7b129fbe 100644 --- a/2021/page/3/index.html +++ b/2021/page/3/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -357,7 +357,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -394,13 +394,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2022/01/index.html b/2022/01/index.html index 467b9aa3..75af66cd 100644 --- a/2022/01/index.html +++ b/2022/01/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2022/04/index.html b/2022/04/index.html index cad3fca0..c64cfd34 100644 --- a/2022/04/index.html +++ b/2022/04/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2022/05/index.html b/2022/05/index.html index 2ec93cf2..f18bec8d 100644 --- a/2022/05/index.html +++ b/2022/05/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -374,7 +374,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -411,13 +411,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2022/06/index.html b/2022/06/index.html index 6ef0d505..d53340fb 100644 --- a/2022/06/index.html +++ b/2022/06/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -314,7 +314,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -351,13 +351,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2022/10/index.html b/2022/10/index.html index 575292c1..cc8beffe 100644 --- a/2022/10/index.html +++ b/2022/10/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -314,7 +314,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -351,13 +351,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2022/index.html b/2022/index.html index ed3f2f8b..417701c2 100644 --- a/2022/index.html +++ b/2022/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -477,7 +477,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -514,13 +514,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2022/page/2/index.html b/2022/page/2/index.html index 93757814..477a2f50 100644 --- a/2022/page/2/index.html +++ b/2022/page/2/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -297,7 +297,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -334,13 +334,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2023/03/index.html b/2023/03/index.html index 12c751f7..5bfd8a1f 100644 --- a/2023/03/index.html +++ b/2023/03/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2023/06/index.html b/2023/06/index.html index 6d9adbe4..174ef041 100644 --- a/2023/06/index.html +++ b/2023/06/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2023/07/index.html b/2023/07/index.html index bf32aa35..b091f3df 100644 --- a/2023/07/index.html +++ b/2023/07/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2023/08/index.html b/2023/08/index.html index 6df4d1ee..cd12f669 100644 --- a/2023/08/index.html +++ b/2023/08/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2023/10/index.html b/2023/10/index.html index 1642c0c4..b22a11be 100644 --- a/2023/10/index.html +++ b/2023/10/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2023/11/index.html b/2023/11/index.html index 8bc76eee..3c43566a 100644 --- a/2023/11/index.html +++ b/2023/11/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2023/index.html b/2023/index.html index 05fb59da..29cb6313 100644 --- a/2023/index.html +++ b/2023/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -394,7 +394,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -431,13 +431,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2024/04/index.html b/2024/04/index.html index 423df166..690f39ad 100644 --- a/2024/04/index.html +++ b/2024/04/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -294,7 +294,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -331,13 +331,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2024/05/index.html b/2024/05/index.html index 8b2db88c..b7bf069a 100644 --- a/2024/05/index.html +++ b/2024/05/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -314,7 +314,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -351,13 +351,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2024/07/index.html b/2024/07/index.html index 6a89ec5c..811e95ce 100644 --- a/2024/07/index.html +++ b/2024/07/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -374,7 +374,7 @@

蓝色的笔记本

- 27 + 28 标签
@@ -411,13 +411,13 @@

蓝色的笔记本

站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git a/2024/09/index.html b/2024/09/index.html index e07f3304..68943ac4 100644 --- a/2024/09/index.html +++ b/2024/09/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -198,6 +198,26 @@

蓝色的笔记本

2024
+
+
+ + + +
+ +
+ +
+
+
@@ -294,7 +314,7 @@

蓝色的笔记本

@@ -331,13 +351,13 @@

蓝色的笔记本

- 131k + 133k - 1:59 + 2:01 diff --git a/2024/10/index.html b/2024/10/index.html new file mode 100644 index 00000000..de577141 --- /dev/null +++ b/2024/10/index.html @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 归档 | 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

蓝色的笔记本

+ +
+

记录学习内容

+
+ + +
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+
+
+ + 不错! 目前共计 52 篇日志。 继续努力。 +
+ + +
+ 2024 +
+ + + + +
+
+ + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/index.html b/2024/index.html index 5b551e81..87541a2a 100644 --- a/2024/index.html +++ b/2024/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -198,6 +198,46 @@

蓝色的笔记本

2024
+ + + +
@@ -358,26 +398,6 @@

蓝色的笔记本

- - @@ -386,6 +406,9 @@

蓝色的笔记本

+ @@ -454,7 +477,7 @@

蓝色的笔记本

@@ -491,13 +514,13 @@

蓝色的笔记本

- 131k + 133k - 1:59 + 2:01 diff --git a/2024/page/2/index.html b/2024/page/2/index.html new file mode 100644 index 00000000..f12cbd13 --- /dev/null +++ b/2024/page/2/index.html @@ -0,0 +1,448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 归档 | 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

蓝色的笔记本

+ +
+

记录学习内容

+
+ + +
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+
+
+ + 不错! 目前共计 52 篇日志。 继续努力。 +
+ + +
+ 2024 +
+ + + + +
+
+ + + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/Android\347\232\204maven\346\217\222\344\273\266\345\222\214maven-publish\346\217\222\344\273\266.html" "b/Android\347\232\204maven\346\217\222\344\273\266\345\222\214maven-publish\346\217\222\344\273\266.html" index 07a25fbb..0bf07354 100644 --- "a/Android\347\232\204maven\346\217\222\344\273\266\345\222\214maven-publish\346\217\222\344\273\266.html" +++ "b/Android\347\232\204maven\346\217\222\344\273\266\345\222\214maven-publish\346\217\222\344\273\266.html" @@ -401,7 +401,7 @@

- 27 + 28 标签 @@ -438,13 +438,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/about/index.html b/about/index.html index ad0c35b0..327106d0 100644 --- a/about/index.html +++ b/about/index.html @@ -287,7 +287,7 @@

关于 @@ -324,13 +324,13 @@

关于 - 131k + 133k - 1:59 + 2:01 diff --git a/admob-init-performance-test.html b/admob-init-performance-test.html index 896bcb05..c3c667b1 100644 --- a/admob-init-performance-test.html +++ b/admob-init-performance-test.html @@ -479,7 +479,7 @@

- 27 + 28 标签 @@ -516,13 +516,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-aosp-event-loop.html b/android-aosp-event-loop.html index 0cb25d03..b2c22a90 100644 --- a/android-aosp-event-loop.html +++ b/android-aosp-event-loop.html @@ -449,7 +449,7 @@

- 27 + 28 标签 @@ -486,13 +486,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-basic-constraintlayout.html b/android-basic-constraintlayout.html index 12f9118a..70bd2f98 100644 --- a/android-basic-constraintlayout.html +++ b/android-basic-constraintlayout.html @@ -725,7 +725,7 @@

@@ -762,13 +762,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-github-source-measure.html b/android-github-source-measure.html new file mode 100644 index 00000000..597fb862 --- /dev/null +++ b/android-github-source-measure.html @@ -0,0 +1,594 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 源码分析-性能监控之Measure | 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ 源码分析-性能监控之Measure +

+ + +
+ + + + +
+ + +
概述

Measure是一个开源的性能监控项目,它包含:Android、iOS、前端、后端。这里分析一下Android端的逻辑实现。

+
分析

项目的基本结构:

+
    +
  • measure-android

    +
      +
    • measure
    • +
    • measure-android-gradle
    • +
    • sample
    • +
    +
  • +
  • measure模块的内容:

    +
      +
    • ANR捕获:Native实现,注册信号处理器,捕获SIGQUIT信号
    • +
    • AppLaunch:区分冷起、热起、温启动,并对外回调。
    • +
    • AppExit:ActivityManager#getHistoricalProcessExitReasons的使用
    • +
    • performance:
        +
      • cpu usage
      • +
      • memory usage
      • +
      +
    • +
    • NetworkChange:网络变化的监控
    • +
    • ScreenShot:生成屏幕截图,PixelCopy的使用,或者Canvas画上去
    • +
    • 其他模块:周期性的心跳包(Heartbeat)去执行任务。Okhttp拦截器。
    • +
    +
  • +
  • measure-android-gradle

    +
      +
    • Manifest数据读取,AppId、VersionCode、VersionName
    • +
    • Mapping文件上传
    • +
    • Apk、Aab大小信息上传
    • +
    +
  • +
+
总结:

1、冷热起的判断逻辑,这部分代码参考自Square的PaPa有参考价值
2、各功能的对外调用都是接口化的,无侵入性
3、项目简单,阅读起来很顺。
4、包含前后端代码,看板,值得学习。

+ +
+ + + + +
+
赏你一杯咖啡
+ + +
+ + + +
+ +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-github-source-retrofit.html b/android-github-source-retrofit.html index 40701bc9..312d37a6 100644 --- a/android-github-source-retrofit.html +++ b/android-github-source-retrofit.html @@ -426,7 +426,7 @@

- 27 + 28 标签 @@ -463,13 +463,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-github-source-spacex.html b/android-github-source-spacex.html index 6a919d00..4185cab9 100644 --- a/android-github-source-spacex.html +++ b/android-github-source-spacex.html @@ -436,7 +436,7 @@

- 27 + 28 标签 @@ -473,13 +473,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-github-source-workmanager.html b/android-github-source-workmanager.html index 417d2e94..c1cfadaf 100644 --- a/android-github-source-workmanager.html +++ b/android-github-source-workmanager.html @@ -447,7 +447,7 @@

- 27 + 28 标签 @@ -484,13 +484,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-jetpack-compose-sideeffect.html b/android-jetpack-compose-sideeffect.html index d4735c53..9392fb93 100644 --- a/android-jetpack-compose-sideeffect.html +++ b/android-jetpack-compose-sideeffect.html @@ -452,7 +452,7 @@

- 27 + 28 标签 @@ -489,13 +489,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-jetpack-compose-state-management.html b/android-jetpack-compose-state-management.html index 91c3da0c..b1bea41f 100644 --- a/android-jetpack-compose-state-management.html +++ b/android-jetpack-compose-state-management.html @@ -447,7 +447,7 @@

- 27 + 28 标签 @@ -484,13 +484,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-jetpack-startup.html b/android-jetpack-startup.html index b1fbb352..894b7dba 100644 --- a/android-jetpack-startup.html +++ b/android-jetpack-startup.html @@ -401,7 +401,7 @@

- 27 + 28 标签 @@ -438,13 +438,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-library-log.html b/android-library-log.html index 8e8d86c4..c5ef22f8 100644 --- a/android-library-log.html +++ b/android-library-log.html @@ -403,7 +403,7 @@

@@ -440,13 +440,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-library-room-7-tips.html b/android-library-room-7-tips.html index d5806a99..830ffbda 100644 --- a/android-library-room-7-tips.html +++ b/android-library-room-7-tips.html @@ -473,7 +473,7 @@

- 27 + 28 标签 @@ -510,13 +510,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-scoped-storage.html b/android-scoped-storage.html index 429be853..543a53d8 100644 --- a/android-scoped-storage.html +++ b/android-scoped-storage.html @@ -503,7 +503,7 @@

@@ -540,13 +540,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/android-target-30.html b/android-target-30.html index e55282c0..a13099b8 100644 --- a/android-target-30.html +++ b/android-target-30.html @@ -488,7 +488,7 @@

@@ -525,13 +525,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/archives/index.html b/archives/index.html index 5d55c7d1..64bc3fb4 100644 --- a/archives/index.html +++ b/archives/index.html @@ -185,6 +185,247 @@

蓝色的笔记本

+
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +
+

以下内容在一篇公众号里面看到的,觉得很有道理,记录在此,常思之。

+
+

01 沟通:先求同,再求异
明确共同目标,塑造价值认同。保持开放心态,积极倾听对方。

+
+

自评:

+
+

02 共情:先理解,再表达
准确辨识情绪,正确解读语义。听对方想说的,说对方想听的。

+
+

自评:

+
+

03 人际:先交流,再交心
选择交流对象,探索交流领域。尝试交流情感,保持稳定交往。

+
+

自评:

+
+

04 情商:先心情,再事情
安抚对方情绪,恢复正常对话。寻找共同利益,解决冲突矛盾。

+
+

自评:

+
+

05 职场:先升值,再升职
认清商业本质,正视价值交换。接受共性塑造,获得职务晋升。

+
+

自评:

+
+

06 工作:先计划,再行动
设定清晰目标,分析评估现状。制订详细计划,设定执行步骤。

+
+

自评:计划就是把大目标拆成更容易实现的小目标,给自己设定期限,坚定的完成小目标。有了目标,才不会放松自己,浑浑噩噩。

+
+

07 执行:先完成,再完美
舍弃完美主义,坚持效率优先。总结经验教训,快速优化迭代。

+
+

自评:早期写代码时追求完美,总想着要设计好代码。花过多的时间在代码设计上。后面还是想明白了,先把事情做完是最基本的要求,做完后有时间再去优化代码细节。因为思考是逐渐深入的,只有完成了,在完成过程中的思考,才能为后面的更好做好理论铺垫。

+
+

08 学习:先记录,再记忆
准备记录工具,捕捉关键信息。定期整理回顾,转为长期记忆。

+
+

自评:知识要结构化才能变成脑子里的思路,结构化就是对一方面知识进行概括,由多到少,由繁到简,由细节到抽象。记录和整理就是对知识进行结构化。尤其是现在快节奏的生活,大家没时间体系性的看书,都是碎片化的知识,看时很爽,很快忘记,不妨把小知识点记录成系统,归纳到自己的知识体系里面。

+
+

09 能力:先专注,再专业
正确选择方向,排除外界干扰。深度学习知识,持续精进技能。
10 事业:先成长,再成功
磨砺心灵意志,坚持求知探索。明确价值取向,积小胜为大胜。
11 发展:先站住,再站高
明确发展定位,夯实事业基础。进行长远规划,开展品牌建设。

+

12 创新:先仿造,再创造
寻找模仿对象,仔细观察学习。研究原理结构,思考优化改进。

+

13 流程:先僵化,再优化
设计业务流程,坚持落地执行。消除流程阻力,提升流程效率。

+

14 制度:先细化,再简化
杜绝制度弹性,堵住制度漏洞。提炼制度要点,进行制度宣贯。

+

15 管理:先自己,再别人
约束自身言行,做好团队表率。明确团队规则,落实奖惩措施。

+

16 影响:先管理,再领导
建立团队秩序,做好利益平衡。激发团队动能,引领创新变革。

+

总之,做事,顺序不能错,逻辑不能反!

+ + +
+ + + + +
+
+
+
+ + + + + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +
概述

Measure是一个开源的性能监控项目,它包含:Android、iOS、前端、后端。这里分析一下Android端的逻辑实现。

+
分析

项目的基本结构:

+
    +
  • measure-android

    +
      +
    • measure
    • +
    • measure-android-gradle
    • +
    • sample
    • +
    +
  • +
  • measure模块的内容:

    +
      +
    • ANR捕获:Native实现,注册信号处理器,捕获SIGQUIT信号
    • +
    • AppLaunch:区分冷起、热起、温启动,并对外回调。
    • +
    • AppExit:ActivityManager#getHistoricalProcessExitReasons的使用
    • +
    • performance:
        +
      • cpu usage
      • +
      • memory usage
      • +
      +
    • +
    • NetworkChange:网络变化的监控
    • +
    • ScreenShot:生成屏幕截图,PixelCopy的使用,或者Canvas画上去
    • +
    • 其他模块:周期性的心跳包(Heartbeat)去执行任务。Okhttp拦截器。
    • +
    +
  • +
  • measure-android-gradle

    +
      +
    • Manifest数据读取,AppId、VersionCode、VersionName
    • +
    • Mapping文件上传
    • +
    • Apk、Aab大小信息上传
    • +
    +
  • +
+
总结:

1、冷热起的判断逻辑,这部分代码参考自Square的PaPa有参考价值
2、各功能的对外调用都是接口化的,无侵入性
3、项目简单,阅读起来很顺。
4、包含前后端代码,看板,值得学习。

+ + +
+ + + + +
+
+
+
+ + + + + + +
@@ -1345,419 +1586,10 @@

- - - - - -
-

- - -

- - -
- - - - -
- - -

概述

书籍简介
- - - - -
慢思考:大脑超载时代的思考学
- -

关于作者

特奥·康普诺利(Teo Compagnoli)教授是一位在医学、神经精神病学、心理治疗和商业咨询领域都颇有建树的专家。

-
    -
  • 比利时的鲁汶天主教大学获得医学博士
  • -
  • 荷兰的阿姆斯特丹大学获得博士
  • -
-

其他出版物:

-
    -
  • 《压力:朋友和敌人》
  • -
-

本书的结构

    -
  1. 第一部分:解释了大脑的工作机制
  2. -
  3. 第二部分:忽视大脑的优势劣势就会给大脑套上无形的锁链
  4. -
  5. 第三部分:解开大脑锁链的方案——慢思考
  6. -
-

导读

人的大脑有三套负责认知决策的脑系统:

-
    -
  • 反射脑:快速原始无意识处理问题
  • -
  • 思考闹:慢而成熟消耗大量能量
  • -
  • 存储闹:存储信息激发创意
  • -
-

如何保持专注:

-
    -
  • 第一,彻底离线:抽出固定的不受打扰的时间完成专注工作和对话
  • -
  • 第二,批量处理:尽量减少切换次数
  • -
  • 第三,恢复正常的睡眠模式
  • -
  • 第四,科学应对负面压力
  • -
-

第一部分:神奇大脑一个简单而迷人的科学真相

    -
  • 第一章,关于大脑的惊人真相
    大脑里帮助我们处理数据的细胞总数共有1600亿个,大脑并不像机器一样由一个个独立部件组成,而是一套层层叠叠的复杂网络,他没有中枢决策器官。新细胞的产出会随着年龄的增长而减少但不会彻底停止。
    大脑能够与身体里的50万亿~100万亿个细胞进行直接的双向通信,这些细胞组成了我们的“身体脑”。
    身体脑通过三套系统影响全身所有细胞:
      -
    • 反应极其迅速的神经系统
    • -
    • 反应较慢的内分泌系统。
    • -
    • 免疫系统。
    • -
    -
  • -
  • 第二章,果壳里的三种脑
      -
    • 慢而成熟的思考脑
        -
      • 速度慢,需要专注,消耗大量能量,易疲劳,串行处理,制定远期目标并提前做出预判。
      • -
      -
    • -
    • 快而原始的反射脑
        -
      • 速度快,自发无意识,情感网络也属于反射脑的一部分。
      • -
      -
    • -
    • 时刻等待空闲的存储脑
        -
      • 信息分类存储,主要以联想方式保存信息,年龄增加信息检索时间增加,与思考脑保持平衡,其中一个激活另一个就休息。
      • -
      -
    • -
    -
  • -
  • 第三章,思考脑:不能一心二用
  • -
  • 第四章,反射脑:总喜欢抄捷径
  • -
  • 第五章,存储闹:至关重要的放松
  • -
  • 第六章,如何在扁平的世界深入思考
  • -
-

第二部分:脑锁链如何不自觉地摧毁自己的大脑

    -
  • 第七章,1号锁链:随时在线
      -
    • 现代技术让我们被短信邮件通知电话等外部事件所吸引,导致精力分散。
    • -
    • 信息超载,信息的充沛消耗资源,消耗什么资源呢?接收者的注意力!
    • -
    • 决策疲劳:经过一段时间持续的自我控制或是做出大量的小选择以后,人 的自控力、毅力、面对失败时的韧性都会有所衰退,拖延情况加剧, 数学计算的数量和质量下降,决策能力也会变差。
    • -
    -
  • -
  • 第八章,2号锁链:多任务并行
  • -
  • 第九章,3号锁链:低水平压力
  • -
  • 第十章,4号锁链:睡眠不足
  • -
  • 第十一章,离线思考为何如此困难
      -
    • 深入阅读是思考不可或缺的前提
    • -
    • 真正的对话对思考至关重要
        -
      • level1 = 闲聊:重点不在于内容,在于维护关系
      • -
      • level2 = 讨论:说明自己的主观看法、观点、意见、信念和价值判断
      • -
      • level3 = 真正对话:综合彼此看法创造出新意义并由此建立更稳固的关系。能够发起并引导真正的对话,这是智商和情商的重要元素。
      • -
      -
    • -
    • 分散注意力的罪魁祸首
      - -
    • -
    -
  • -
-

第三部分:慢思考如何解放你的大脑

    -
  • 第十二章,1号解锁秘诀:离线思考
      -
    • 抽出固定的不受打扰的时间,来完成专注的工作和对话。状态最好的时间段(早上?晚上?)。
    • -
    • 每周日晚抽出20分钟计划一周的工作,每天睡前抽10分钟安排第二天的工作,这样,睡觉时,存储脑会提前工作。
    • -
    • 纸质阅读更利于理解、阅读速度更快、也更不容易疲劳
    • -
    -
  • -
  • 第十三章,2号解锁秘诀:批量处理
  • -
-

13.1 艾森豪威尔原理(事情的重要性、紧急性四象限)

-
- -
- - -

13.2 帕累托法则(20%的活动创造80%效益,要提高效率,你的找出那些高价值的活动来)

-
- -
- -
    -
  • 递进帕累托法则(平方:4%的活动产生64%的价值,三次方)
  • -
  • 快乐的帕累托法则(做积极有意义让你快乐的事情)
  • -
-

13.3 批量处理:
13.4 合理安排每个人的任务:
13.5 从根源消除多任务:管理者在规划工作流程和项目时应该尽量避免多任务并行。
13.6 如何打败邮件怪兽:邮件会过度分散我们的专注力,要集中批量把它处理了。(这可能是外国人生活的一部分吧)

-
    -
  • 第十四章,3号解锁秘诀:恢复正常的睡眠模式
      -
    • 保证8小时睡眠
    • -
    • 每天同样的时间就寝起床,包括周末(补觉应该早点上床而不是晚起)
    • -
    -
  • -
  • 第十五章,4号解锁秘诀:科学应对负面压力
      -
    • 短暂压力能刺激智力生产力,压力过大持续时间过长会摧毁你的智力生产力。
    • -
    • 频繁任务切换导致的慢性压力会积压成大压力导致思考精疲力尽
    • -
    -
  • -
-
- -
- -
    -
  • 第十六章,ABC模式:如何把坏习惯变成好习惯
  • -
-

总结

这本书的中文名翻译,烂透了!原书名:《脑链:在高度互联的多任务世界中释放你的潜能》核心思想是让你提升大脑利用率,高效工作生活,琐碎工作集中处理,专注。
第一部分介绍大脑的工作机制,第二部分介绍了一些导致我们大脑效率低下的问题,第三部分介绍一些方法解决这些问题。

- - -
- - - - -
-
-
-

- - - - - - - -
- - - - - -
-

- - -

- - -
- - - - -
- - -
-
一、磁盘的结构

磁盘按照物理结构和逻辑结构区分比较好。

-

1.1 HDD物理结构(Hard Disk Drive)

-
    -
  • Platters:盘片
  • -
  • Head:读写头
  • -
  • Spindle:主轴
  • -
  • Actuator Arm:机械臂
  • -
  • Cylinder:柱面
  • -
  • Sector:扇区
  • -
  • Track:磁道:
  • -
-
- - - -
- -

1.2 SSD的物理结构(Solid State Drive)

-

1.2.1 基本存储单元

-
- -
- -

通过向被绝缘层包围的浮栅层充放电来写入擦除数据。(非易失存储器)

-

1.3 逻辑结构

-

文件系统block -> 磁盘block -> n * 扇区

-
- -
- -
- -
- - - -
二、文件系统挂载

文件系统生成后,还不能直接使用,需要借助”mount”操作,将这个文件系统加入到Linux的管理,这样用户才能看到并访问

-
三、虚拟文件系统
- -
- - -

虚拟文件系统为各种文件系统提供一个通用的接口,其支持的文件系统可以划分为三种主要类型:

-
    -
  • 磁盘文件系统(EXT3、NTFS)
  • -
  • 网络文件系统
  • -
  • 特殊文件系统(/proc)
  • -
-

虚拟文件系统通过引入一套通用的文件模型来支持所有的文件系统,通用模型由四大对象组成:

-
    -
  • 超级块对象
  • -
  • 索引节点对象
  • -
  • 目录项对象
  • -
  • 文件对象
  • -
-

3.1 超级快对象:代表一个具体的已安装文件系统

-
1
2
3
struct super_block {
struct super_operations s_op;//操作对象
}
- -

3.2 索引节点对象:代表一个具体的文件

-
1
2
3
struct inode {
struct inode_operations *i_op;
}
- -

3.3 目录项对象:代表一个目录项,是路径的一个组成部分

-
1
2
3
struct dentry {
struct dentry_operations *d_op;
}
- -

3.4 文件对象:代表由进程打开的文件

-
1
2
3
struct file {
struct file_operations *f_op;
}
- - -
四、相关系统调用
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
系统调用说明
mount() unmount() unmount2()安装卸载文件系统
mkdir() rmdir()创建删除目录
unlink() rename()对目录项进行操作
mmap() mmap2() munmap()处理文件内存映射
read() write()进行文件IO操作
select() poll()等待一组文件描述符上发生事件
open() close() create()打开关闭创建
chmod() fchmod() utime()更改文件属性
-
五、参考文献

https://z.itpub.net/article/detail/8ABB71A5EFED33EA9D09353759A91F1C

-

深入理解 Linux Ext 文件系统设计原理

-

第4章 ext文件系统机制原理剖析

-

Linux 虚拟文件系统四大对象:超级块、inode、dentry、file之间关系

-

从内核文件系统看文件读写过程

- - -
- - - - -
-
-
-
- - - - @@ -1827,7 +1659,7 @@

@@ -1864,13 +1696,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/archives/page/2/index.html b/archives/page/2/index.html index 5203d625..e5531a69 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -185,6 +185,415 @@

蓝色的笔记本

+
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

概述

书籍简介
+ + + + +
慢思考:大脑超载时代的思考学
+ +

关于作者

特奥·康普诺利(Teo Compagnoli)教授是一位在医学、神经精神病学、心理治疗和商业咨询领域都颇有建树的专家。

+
    +
  • 比利时的鲁汶天主教大学获得医学博士
  • +
  • 荷兰的阿姆斯特丹大学获得博士
  • +
+

其他出版物:

+
    +
  • 《压力:朋友和敌人》
  • +
+

本书的结构

    +
  1. 第一部分:解释了大脑的工作机制
  2. +
  3. 第二部分:忽视大脑的优势劣势就会给大脑套上无形的锁链
  4. +
  5. 第三部分:解开大脑锁链的方案——慢思考
  6. +
+

导读

人的大脑有三套负责认知决策的脑系统:

+
    +
  • 反射脑:快速原始无意识处理问题
  • +
  • 思考闹:慢而成熟消耗大量能量
  • +
  • 存储闹:存储信息激发创意
  • +
+

如何保持专注:

+
    +
  • 第一,彻底离线:抽出固定的不受打扰的时间完成专注工作和对话
  • +
  • 第二,批量处理:尽量减少切换次数
  • +
  • 第三,恢复正常的睡眠模式
  • +
  • 第四,科学应对负面压力
  • +
+

第一部分:神奇大脑一个简单而迷人的科学真相

    +
  • 第一章,关于大脑的惊人真相
    大脑里帮助我们处理数据的细胞总数共有1600亿个,大脑并不像机器一样由一个个独立部件组成,而是一套层层叠叠的复杂网络,他没有中枢决策器官。新细胞的产出会随着年龄的增长而减少但不会彻底停止。
    大脑能够与身体里的50万亿~100万亿个细胞进行直接的双向通信,这些细胞组成了我们的“身体脑”。
    身体脑通过三套系统影响全身所有细胞:
      +
    • 反应极其迅速的神经系统
    • +
    • 反应较慢的内分泌系统。
    • +
    • 免疫系统。
    • +
    +
  • +
  • 第二章,果壳里的三种脑
      +
    • 慢而成熟的思考脑
        +
      • 速度慢,需要专注,消耗大量能量,易疲劳,串行处理,制定远期目标并提前做出预判。
      • +
      +
    • +
    • 快而原始的反射脑
        +
      • 速度快,自发无意识,情感网络也属于反射脑的一部分。
      • +
      +
    • +
    • 时刻等待空闲的存储脑
        +
      • 信息分类存储,主要以联想方式保存信息,年龄增加信息检索时间增加,与思考脑保持平衡,其中一个激活另一个就休息。
      • +
      +
    • +
    +
  • +
  • 第三章,思考脑:不能一心二用
  • +
  • 第四章,反射脑:总喜欢抄捷径
  • +
  • 第五章,存储闹:至关重要的放松
  • +
  • 第六章,如何在扁平的世界深入思考
  • +
+

第二部分:脑锁链如何不自觉地摧毁自己的大脑

    +
  • 第七章,1号锁链:随时在线
      +
    • 现代技术让我们被短信邮件通知电话等外部事件所吸引,导致精力分散。
    • +
    • 信息超载,信息的充沛消耗资源,消耗什么资源呢?接收者的注意力!
    • +
    • 决策疲劳:经过一段时间持续的自我控制或是做出大量的小选择以后,人 的自控力、毅力、面对失败时的韧性都会有所衰退,拖延情况加剧, 数学计算的数量和质量下降,决策能力也会变差。
    • +
    +
  • +
  • 第八章,2号锁链:多任务并行
  • +
  • 第九章,3号锁链:低水平压力
  • +
  • 第十章,4号锁链:睡眠不足
  • +
  • 第十一章,离线思考为何如此困难
      +
    • 深入阅读是思考不可或缺的前提
    • +
    • 真正的对话对思考至关重要
        +
      • level1 = 闲聊:重点不在于内容,在于维护关系
      • +
      • level2 = 讨论:说明自己的主观看法、观点、意见、信念和价值判断
      • +
      • level3 = 真正对话:综合彼此看法创造出新意义并由此建立更稳固的关系。能够发起并引导真正的对话,这是智商和情商的重要元素。
      • +
      +
    • +
    • 分散注意力的罪魁祸首
      + +
    • +
    +
  • +
+

第三部分:慢思考如何解放你的大脑

    +
  • 第十二章,1号解锁秘诀:离线思考
      +
    • 抽出固定的不受打扰的时间,来完成专注的工作和对话。状态最好的时间段(早上?晚上?)。
    • +
    • 每周日晚抽出20分钟计划一周的工作,每天睡前抽10分钟安排第二天的工作,这样,睡觉时,存储脑会提前工作。
    • +
    • 纸质阅读更利于理解、阅读速度更快、也更不容易疲劳
    • +
    +
  • +
  • 第十三章,2号解锁秘诀:批量处理
  • +
+

13.1 艾森豪威尔原理(事情的重要性、紧急性四象限)

+
+ +
+ + +

13.2 帕累托法则(20%的活动创造80%效益,要提高效率,你的找出那些高价值的活动来)

+
+ +
+ +
    +
  • 递进帕累托法则(平方:4%的活动产生64%的价值,三次方)
  • +
  • 快乐的帕累托法则(做积极有意义让你快乐的事情)
  • +
+

13.3 批量处理:
13.4 合理安排每个人的任务:
13.5 从根源消除多任务:管理者在规划工作流程和项目时应该尽量避免多任务并行。
13.6 如何打败邮件怪兽:邮件会过度分散我们的专注力,要集中批量把它处理了。(这可能是外国人生活的一部分吧)

+
    +
  • 第十四章,3号解锁秘诀:恢复正常的睡眠模式
      +
    • 保证8小时睡眠
    • +
    • 每天同样的时间就寝起床,包括周末(补觉应该早点上床而不是晚起)
    • +
    +
  • +
  • 第十五章,4号解锁秘诀:科学应对负面压力
      +
    • 短暂压力能刺激智力生产力,压力过大持续时间过长会摧毁你的智力生产力。
    • +
    • 频繁任务切换导致的慢性压力会积压成大压力导致思考精疲力尽
    • +
    +
  • +
+
+ +
+ +
    +
  • 第十六章,ABC模式:如何把坏习惯变成好习惯
  • +
+

总结

这本书的中文名翻译,烂透了!原书名:《脑链:在高度互联的多任务世界中释放你的潜能》核心思想是让你提升大脑利用率,高效工作生活,琐碎工作集中处理,专注。
第一部分介绍大脑的工作机制,第二部分介绍了一些导致我们大脑效率低下的问题,第三部分介绍一些方法解决这些问题。

+ + +
+ + + + +
+
+
+
+ + + + + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +
+
一、磁盘的结构

磁盘按照物理结构和逻辑结构区分比较好。

+

1.1 HDD物理结构(Hard Disk Drive)

+
    +
  • Platters:盘片
  • +
  • Head:读写头
  • +
  • Spindle:主轴
  • +
  • Actuator Arm:机械臂
  • +
  • Cylinder:柱面
  • +
  • Sector:扇区
  • +
  • Track:磁道:
  • +
+
+ + + +
+ +

1.2 SSD的物理结构(Solid State Drive)

+

1.2.1 基本存储单元

+
+ +
+ +

通过向被绝缘层包围的浮栅层充放电来写入擦除数据。(非易失存储器)

+

1.3 逻辑结构

+

文件系统block -> 磁盘block -> n * 扇区

+
+ +
+ +
+ +
+ + + +
二、文件系统挂载

文件系统生成后,还不能直接使用,需要借助”mount”操作,将这个文件系统加入到Linux的管理,这样用户才能看到并访问

+
三、虚拟文件系统
+ +
+ + +

虚拟文件系统为各种文件系统提供一个通用的接口,其支持的文件系统可以划分为三种主要类型:

+
    +
  • 磁盘文件系统(EXT3、NTFS)
  • +
  • 网络文件系统
  • +
  • 特殊文件系统(/proc)
  • +
+

虚拟文件系统通过引入一套通用的文件模型来支持所有的文件系统,通用模型由四大对象组成:

+
    +
  • 超级块对象
  • +
  • 索引节点对象
  • +
  • 目录项对象
  • +
  • 文件对象
  • +
+

3.1 超级快对象:代表一个具体的已安装文件系统

+
1
2
3
struct super_block {
struct super_operations s_op;//操作对象
}
+ +

3.2 索引节点对象:代表一个具体的文件

+
1
2
3
struct inode {
struct inode_operations *i_op;
}
+ +

3.3 目录项对象:代表一个目录项,是路径的一个组成部分

+
1
2
3
struct dentry {
struct dentry_operations *d_op;
}
+ +

3.4 文件对象:代表由进程打开的文件

+
1
2
3
struct file {
struct file_operations *f_op;
}
+ + +
四、相关系统调用
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
系统调用说明
mount() unmount() unmount2()安装卸载文件系统
mkdir() rmdir()创建删除目录
unlink() rename()对目录项进行操作
mmap() mmap2() munmap()处理文件内存映射
read() write()进行文件IO操作
select() poll()等待一组文件描述符上发生事件
open() close() create()打开关闭创建
chmod() fchmod() utime()更改文件属性
+
五、参考文献

https://z.itpub.net/article/detail/8ABB71A5EFED33EA9D09353759A91F1C

+

深入理解 Linux Ext 文件系统设计原理

+

第4章 ext文件系统机制原理剖析

+

Linux 虚拟文件系统四大对象:超级块、inode、dentry、file之间关系

+

从内核文件系统看文件读写过程

+ + +
+ + + + +
+
+
+
+ + + + + + +
@@ -1290,284 +1699,10 @@

- - - - - -
-

- - -

- - -
- - - - -
- - -

一、概述

    -
  • 资产回报率(ROA)
  • -
  • 净资产回报率(ROE)
  • -
  • 投入资本回报率(ROIC)
  • -
  • 使用资本回报率(ROCE)
  • -
-

不同的回报率,实际上是衡量公司的不同视角。

-

二、资产回报率(ROA)

2.1 基本概念

运用全部资金获取利润能力的集中体现

-
- -
- -

$$
ROA=\frac{净利润}{总资产}
$$

-
2.2 概念拆分

$$
ROA = 净利润率NPM * 资产利用率AU = \frac{净利润}{营业总收入} * \frac{营业总收入}{总资产} = \frac{(主营业务收入+非主营业务收入)}{总资产}
$$

-
2.3 概念理解

ROA这个回报率衡量的是资产的回报率。
但是一个公司资产负债表上的资产价值更多的是反映了历史而不是当前,
而且不同的行业的ROA具有不可比性。
最简单的例子,很多类金融企业有无息流动负债,增加了总资产,降低了ROA,
但是无偿使用上下游资金实际上是公司有竞争力的体现。

-

三、净资产回报率(ROE)

2.1 基本概念

ROE的视角是从股东的角度看问题,单纯从股权的角度衡量回报,而不考虑公司的资本结构及负债情况。衡量公司赚钱的效率。

-
- -
- -

$$
净资产收益率 = \frac{净利润}{净资产}
$$

-
-

A公司:10亿净资产赚2亿。ROE = 20%
B公司:50亿净资产赚5亿。ROE = 10%

-
-
2.2 概念拆分

$$
净资产收益率 = \frac{净利润}{净资产} = \frac{净利润}{营业收入} * \frac{营业收入}{总资产} * \frac{总资产}{净资产}
$$

-

$$
净资产收益率 = 净利润 * 资产周转率 * 权益乘数
$$

-

$$
权益乘数 = \frac{总资产}{净资产}
$$

-

$$
资产周转率 = \frac{营业收入}{总资产}
$$

-

影响因素:

-
    -
  • 净利润:反应盈利能力
  • -
  • 资产周转率:反应资产使用效率
  • -
  • 权益乘数:反应负债程度
  • -
-

提升ROE的办法:

-
    -
  • 提高周转率
  • -
  • 廉价的债务杠杆
  • -
  • 更高的债务杠杆
  • -
  • 更低的所得税
  • -
  • 更高的运营利润率
  • -
-
2.3 概念理解

ROE对股东来说意义最大,是股票复利增长的源泉。
ROE可以在不同行业与不同企业之间横向比较。
相当于股票这种“股权债券”的收益率。
对投资人来说无论是投资铁路还是互联网,都相当于是买了“股权债券”。
在同等风险情况下,当然是收益率越高越好。
而且,ROE还可以与政府债券、企业债券的收益率跨资产类别横向比较。

-
不足

ROE的问题在于无法反映债务杠杆对净利润的影响。
如果一个企业借更多的债,一般就能产生更多净利润,ROE也会提高。
但是这样的提高是以牺牲企业经营稳健程度为代价的。
因此,分析ROE一定要结合杜邦公式,并与同行业进行比较。

-
-

四、投入资本回报率(ROIC)

- -
- - -

ROIC是从资本的角度看问题,综合考虑股权与债权,衡量投资的效率。与ROIC对应的是平均资金成本(WACC)。如果ROIC小于WACC,就说明投入资本的回报小于平均资本成本,公司是在浪费资本。

-

ROIC=息税前收益(EBIT)*(1-税率)/投入资本

-

$$
ROIC = \frac{息税前收益(EBIT)*(1-税率)}{投入资本}
$$

-

$$
投入资本 = 股东权益 + 有息负债
$$

-

$$
ROIC = \frac{EBIT(1-税率)}{有息负债+权益)}
$$

-

公式中分子是指一家公司如果完全以权益筹资所应报告的净利润,分母是指公司所有要求回报的现金来源的总和,也就是说,尽管应付账款也是公司的一种现金来源,但因其未附带明确的成本而被排除在外。实质上,ROIC是生产经营活动中所有投入资本赚取的收益率,而不论这些投入资本是被称为债务还是权益。

-
- -
- - -

投入资本回报率是EBIT(税及利息前盈利)经过税率调整比上投入的资本,也就是股东权益加负债减去非运营现金和投资。之所以用EBIT就是因为利息是由债务产生的,是对债权的回报,当计算债权加股权的总的投入资本的回报率时应该把利息加回来。

-

投入资本也可以表示为净运营资金(流动运营资产减去无息流动负债)加固定资产,加无形资产及商誉,加其他运营资产。

-

ROIC的问题在于没有考虑无息流动负债的影响。ROIC实际上是衡量投入的总资本的使用效率,与平均资金成本WACC相结合可以揭示一个企业的真正效率。ROIC < WACC 是卖空大师Jim Chanos经常用来寻找卖空对象的一个重要指标。

-

但是,ROIC对于类金融企业的分析不太容易。一些类金融企业如国美、苏宁、联想、格力等,占用了大量上下游资金作为无息流动负债,因此提高了EBIT。但是,和有息负债一样,无息负债也存在风险。虽然不用付利息,但是一旦经营形式改变,这些资金很有可能像“热钱”一样撤走。国美在黄光裕被捕后就陷入了这样的危险境地,只要供应商撤资,国美就会破产。这些企业虽然ROIC很高,但是静态不稳定,动态稳定。

-

五、使用资本回报率(ROCE = Return on Capital Employed)

- -
- -

$$
ROCE資本運用報酬率 = \frac{息税前收益(EBIT)}{已動用資本(Capital Employed)}
$$

-

$$
已動用資本 = 總資產 -流動負債
$$

-

ROCE实质上是从企业价值(EnterpriseValue,EV)的角度,从并购的角度看资本的回报率。ROCE中的使用资本是股东权益加有息负债再减现金。这实质上相当于1倍PB并购企业时的企业价值。因为如果你以1倍PB并购一个企业,你要付的价格就是股东权益,并且承担所有负债,但也获得所有现金。

-

ROCE实际上是从一个并购者的角度看问题,如果并购一个企业,付出企业价值EV后的回报率有多少?这与ROIC最大的不同是:ROIC从企业的拥有者的角度看问题,衡量投入资本的使用效率与回报率。而ROCE是从潜在并购者的角度看问题,衡量如果1倍PB并购付出EV后的回报率,也就是并购到底值不值的问题。这接近价值投资买股票就是买公司的原则。

-

ROCE:使用资本回报率是EBIT(税及利息前盈利)比上使用的资本,也就是所有有息负债加上股东权益。这个指标与ROIC相近,但是使用的是EBIT而没有经过税率调整,因此可以用来比较不同税率的企业。ROCE也容易忽视公司无息负债的融资效应。

-

总之,本质上是从四个不同的视角看问题,衡量不同的指标。只有全面综合考虑,才能更全面的看问题

-

六、参考来源

雪球-老韩7
ROCE資本運用報酬率

- - -
- - - - -
-
-
-

- - - - - - - -
- - - - - -
-

- - -

- - -
- - - - -
- - -
-

我们有一个会被重复调用的lambda表达式:

-
1
2
3
4
5
6
7
8
9
10
11
import kotlin.*

fun main() {
val f: () -> Unit = {
print("A")
print("B")
print("C")
}
f() // ABC
f() // ABC
}
- -

我们给这个lambda加个参数:(String) -> Unit ,因为参数是个函数,为了能调用到函数,我们把它叫做emit吧:

-
1
2
3
4
5
6
7
8
9
10
11
import kotlin.*

fun main() {
val f: ((String) -> Unit) -> Unit = { emit -> // 1
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
- -

添加的参数看起来有点乱🤔,稍微修改一下,抽出来吧:

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: (FlowCollector) -> Unit = {
it.emit("A")
it.emit("B")
it.emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
- -

好像能把it的调用逻辑去掉,这样更简洁:

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
- -

调用lambda表达式不是很方便。如果把它抽成接口🤔

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun main() {
val builder: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
val flow: Flow = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}
flow.collect { print(it) } // ABC
flow.collect { print(it) } // ABC
}
- -

抽成可以重复调用的构建器:

-
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
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun flow(builder: FlowCollector.() -> Unit) = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}

fun main() {
val f: Flow = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
- -

泛型化参数更通用:

-
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
import kotlin.*

fun interface FlowCollector<T> {
suspend fun emit(value: T)
}

interface Flow<T> {
suspend fun collect(collector: FlowCollector<T>)
}

fun <T> flow(builder: suspend FlowCollector<T>.() -> Unit) = object : Flow<T> {
override suspend fun collect(collector: FlowCollector<T>) {
collector.builder()
}
}

suspend fun main() {
val f: Flow<String> = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
- - -

参考

- - -
- - - - -
-
-
-
- - - - @@ -1637,7 +1772,7 @@

@@ -1674,13 +1809,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/archives/page/3/index.html b/archives/page/3/index.html index 60e83e40..4c276bae 100644 --- a/archives/page/3/index.html +++ b/archives/page/3/index.html @@ -185,6 +185,280 @@

蓝色的笔记本

+
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

一、概述

    +
  • 资产回报率(ROA)
  • +
  • 净资产回报率(ROE)
  • +
  • 投入资本回报率(ROIC)
  • +
  • 使用资本回报率(ROCE)
  • +
+

不同的回报率,实际上是衡量公司的不同视角。

+

二、资产回报率(ROA)

2.1 基本概念

运用全部资金获取利润能力的集中体现

+
+ +
+ +

$$
ROA=\frac{净利润}{总资产}
$$

+
2.2 概念拆分

$$
ROA = 净利润率NPM * 资产利用率AU = \frac{净利润}{营业总收入} * \frac{营业总收入}{总资产} = \frac{(主营业务收入+非主营业务收入)}{总资产}
$$

+
2.3 概念理解

ROA这个回报率衡量的是资产的回报率。
但是一个公司资产负债表上的资产价值更多的是反映了历史而不是当前,
而且不同的行业的ROA具有不可比性。
最简单的例子,很多类金融企业有无息流动负债,增加了总资产,降低了ROA,
但是无偿使用上下游资金实际上是公司有竞争力的体现。

+

三、净资产回报率(ROE)

2.1 基本概念

ROE的视角是从股东的角度看问题,单纯从股权的角度衡量回报,而不考虑公司的资本结构及负债情况。衡量公司赚钱的效率。

+
+ +
+ +

$$
净资产收益率 = \frac{净利润}{净资产}
$$

+
+

A公司:10亿净资产赚2亿。ROE = 20%
B公司:50亿净资产赚5亿。ROE = 10%

+
+
2.2 概念拆分

$$
净资产收益率 = \frac{净利润}{净资产} = \frac{净利润}{营业收入} * \frac{营业收入}{总资产} * \frac{总资产}{净资产}
$$

+

$$
净资产收益率 = 净利润 * 资产周转率 * 权益乘数
$$

+

$$
权益乘数 = \frac{总资产}{净资产}
$$

+

$$
资产周转率 = \frac{营业收入}{总资产}
$$

+

影响因素:

+
    +
  • 净利润:反应盈利能力
  • +
  • 资产周转率:反应资产使用效率
  • +
  • 权益乘数:反应负债程度
  • +
+

提升ROE的办法:

+
    +
  • 提高周转率
  • +
  • 廉价的债务杠杆
  • +
  • 更高的债务杠杆
  • +
  • 更低的所得税
  • +
  • 更高的运营利润率
  • +
+
2.3 概念理解

ROE对股东来说意义最大,是股票复利增长的源泉。
ROE可以在不同行业与不同企业之间横向比较。
相当于股票这种“股权债券”的收益率。
对投资人来说无论是投资铁路还是互联网,都相当于是买了“股权债券”。
在同等风险情况下,当然是收益率越高越好。
而且,ROE还可以与政府债券、企业债券的收益率跨资产类别横向比较。

+
不足

ROE的问题在于无法反映债务杠杆对净利润的影响。
如果一个企业借更多的债,一般就能产生更多净利润,ROE也会提高。
但是这样的提高是以牺牲企业经营稳健程度为代价的。
因此,分析ROE一定要结合杜邦公式,并与同行业进行比较。

+
+

四、投入资本回报率(ROIC)

+ +
+ + +

ROIC是从资本的角度看问题,综合考虑股权与债权,衡量投资的效率。与ROIC对应的是平均资金成本(WACC)。如果ROIC小于WACC,就说明投入资本的回报小于平均资本成本,公司是在浪费资本。

+

ROIC=息税前收益(EBIT)*(1-税率)/投入资本

+

$$
ROIC = \frac{息税前收益(EBIT)*(1-税率)}{投入资本}
$$

+

$$
投入资本 = 股东权益 + 有息负债
$$

+

$$
ROIC = \frac{EBIT(1-税率)}{有息负债+权益)}
$$

+

公式中分子是指一家公司如果完全以权益筹资所应报告的净利润,分母是指公司所有要求回报的现金来源的总和,也就是说,尽管应付账款也是公司的一种现金来源,但因其未附带明确的成本而被排除在外。实质上,ROIC是生产经营活动中所有投入资本赚取的收益率,而不论这些投入资本是被称为债务还是权益。

+
+ +
+ + +

投入资本回报率是EBIT(税及利息前盈利)经过税率调整比上投入的资本,也就是股东权益加负债减去非运营现金和投资。之所以用EBIT就是因为利息是由债务产生的,是对债权的回报,当计算债权加股权的总的投入资本的回报率时应该把利息加回来。

+

投入资本也可以表示为净运营资金(流动运营资产减去无息流动负债)加固定资产,加无形资产及商誉,加其他运营资产。

+

ROIC的问题在于没有考虑无息流动负债的影响。ROIC实际上是衡量投入的总资本的使用效率,与平均资金成本WACC相结合可以揭示一个企业的真正效率。ROIC < WACC 是卖空大师Jim Chanos经常用来寻找卖空对象的一个重要指标。

+

但是,ROIC对于类金融企业的分析不太容易。一些类金融企业如国美、苏宁、联想、格力等,占用了大量上下游资金作为无息流动负债,因此提高了EBIT。但是,和有息负债一样,无息负债也存在风险。虽然不用付利息,但是一旦经营形式改变,这些资金很有可能像“热钱”一样撤走。国美在黄光裕被捕后就陷入了这样的危险境地,只要供应商撤资,国美就会破产。这些企业虽然ROIC很高,但是静态不稳定,动态稳定。

+

五、使用资本回报率(ROCE = Return on Capital Employed)

+ +
+ +

$$
ROCE資本運用報酬率 = \frac{息税前收益(EBIT)}{已動用資本(Capital Employed)}
$$

+

$$
已動用資本 = 總資產 -流動負債
$$

+

ROCE实质上是从企业价值(EnterpriseValue,EV)的角度,从并购的角度看资本的回报率。ROCE中的使用资本是股东权益加有息负债再减现金。这实质上相当于1倍PB并购企业时的企业价值。因为如果你以1倍PB并购一个企业,你要付的价格就是股东权益,并且承担所有负债,但也获得所有现金。

+

ROCE实际上是从一个并购者的角度看问题,如果并购一个企业,付出企业价值EV后的回报率有多少?这与ROIC最大的不同是:ROIC从企业的拥有者的角度看问题,衡量投入资本的使用效率与回报率。而ROCE是从潜在并购者的角度看问题,衡量如果1倍PB并购付出EV后的回报率,也就是并购到底值不值的问题。这接近价值投资买股票就是买公司的原则。

+

ROCE:使用资本回报率是EBIT(税及利息前盈利)比上使用的资本,也就是所有有息负债加上股东权益。这个指标与ROIC相近,但是使用的是EBIT而没有经过税率调整,因此可以用来比较不同税率的企业。ROCE也容易忽视公司无息负债的融资效应。

+

总之,本质上是从四个不同的视角看问题,衡量不同的指标。只有全面综合考虑,才能更全面的看问题

+

六、参考来源

雪球-老韩7
ROCE資本運用報酬率

+ + +
+ + + + +
+
+
+
+ + + + + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +
+

我们有一个会被重复调用的lambda表达式:

+
1
2
3
4
5
6
7
8
9
10
11
import kotlin.*

fun main() {
val f: () -> Unit = {
print("A")
print("B")
print("C")
}
f() // ABC
f() // ABC
}
+ +

我们给这个lambda加个参数:(String) -> Unit ,因为参数是个函数,为了能调用到函数,我们把它叫做emit吧:

+
1
2
3
4
5
6
7
8
9
10
11
import kotlin.*

fun main() {
val f: ((String) -> Unit) -> Unit = { emit -> // 1
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
+ +

添加的参数看起来有点乱🤔,稍微修改一下,抽出来吧:

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: (FlowCollector) -> Unit = {
it.emit("A")
it.emit("B")
it.emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
+ +

好像能把it的调用逻辑去掉,这样更简洁:

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
+ +

调用lambda表达式不是很方便。如果把它抽成接口🤔

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun main() {
val builder: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
val flow: Flow = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}
flow.collect { print(it) } // ABC
flow.collect { print(it) } // ABC
}
+ +

抽成可以重复调用的构建器:

+
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
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun flow(builder: FlowCollector.() -> Unit) = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}

fun main() {
val f: Flow = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
+ +

泛型化参数更通用:

+
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
import kotlin.*

fun interface FlowCollector<T> {
suspend fun emit(value: T)
}

interface Flow<T> {
suspend fun collect(collector: FlowCollector<T>)
}

fun <T> flow(builder: suspend FlowCollector<T>.() -> Unit) = object : Flow<T> {
override suspend fun collect(collector: FlowCollector<T>) {
collector.builder()
}
}

suspend fun main() {
val f: Flow<String> = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
+ + +

参考

+ + +
+ + + + +
+
+
+
+ + + + + + +
@@ -1189,247 +1463,10 @@

- - - - - -
-

- - -

- - -
- - - - -
- - -

简介:

本文是 Roman Elizarov 关于CSP中产生死锁问题的讨论,解释了其中的原因,并逐步给出了一种解决方案。部分翻译不恰当的可参考原文

-

原文:

众所周知,使用锁保护共享可变状态可能会导致死锁,但很少有人知道,使用无共享可变状态的CSP或actor模型也会导致死锁,尽管它们并不使用锁。它的死锁以另一种方式表现:通信死锁。

-

要知道,死锁的正式定义并没有直接与锁联系在一起。当每个进程都在循环等待下一个进程时,这组进程(线程/协程/参与者)就处于死锁状态。后面我们会看个例子,这里先道个歉,之前没强调这个问题。

-

The stage

在2018年的KotlinConf我发表了题为”Kotlin协程实践”的演讲,其中讲到了对于构建可信赖软件来说结构性并发是重要的,且介绍了CSP的一些高级概念。其中一个部分有点问题。如果你按照演讲中一字不差的写完代码会导致一个死锁。不知何故,我掉进了这个陷阱,以为它对我来说是安全的,但不是。让我们来分析一下

-

首先来讲,如果应用被组织成数据处理管道,消息进入系统,被不同的协程顺序处理,最后被送出系统,那么这种CSP风格的架构,包括actor模式,都是安全的。更广泛地说,只要代码具有协程的层次结构(或有向无环图),上游协程只向下游发送消息,且每个协程在同一个地方接收传过来的消息并向下游传递响应消息,代码就不会出现死锁。

-
- -
- - -

然而在我的演讲中,我草拟了一个数据处理循环的架构,下载器协程向任务池发送locations,并从任务池获取结果:

-
- -
- -

我演讲中的例子的架构基于3个channel:referenceslocationscontents。下载协程包含以下逻辑:

-
1
2
3
4
5
6
7
8
9
10
while (true) {
select<Unit> {
references.onReceive { ref -> // (1)
val loc = ref.resolveLocation()
...
locations.send(loc) // (2)
}
contents.onReceive { (loc, content) -> ... } // (3)
}
}
-

Downloader从references通道(1)接收,解析对位置的引用并将它们发送到locations通道(2)。它还通过从contents通道(3)接收来自workers的结果来更新其状态。另外,works有以下代码:

-
1
2
3
4
for (loc in locations) {                             // (4)
val content = downloadContent(loc)
contents.send(LocContent(loc, content)) // (5)
}
- -

locations通道接收消息(4),并发送下载后的内容去contents通道(5)

-

即使在两段通信的代码中也很难遵循逻辑,但在CSP中有一种方便的方法来可视化它。我们可以用通信有限状态机(CFSM)表示我们的系统。这些状态相当于挂起点和向通信的转变过程:

-
- -
- -

为了简洁起见,上图中通道名简写。receive -> rcv、send -> snd 。下载器主循环中的select语句相当于D0状态,它能接收来自references通道的消息(1)或者来自contents通道的消息(3),当接收到来自references消息,切换到状态D1,等待发送消息去locations通道,如图中:(2)l.snd

-

Deadlock Demo

我用模拟数据类的方式完善了演讲中的代码,加入了delay(10)downloadContent方法。main函数则持续发送请求给下载器的references通道,它有4个workers且带3秒超时限制。此项目可以完整的运行,正常情况下3s应该处理1000次请求。

-

当你运行该项目时,你会发现只处理了4次请求(和我们定义的worker数量一样)就挂起了,直到3s超时。此外,它没有任何随机性,因为它是在单线程的runBlocking上下文中运行的。

-

为了说服你(还有我自己),这是CSP内在的行为而不是Kotlin实现的bug,我用Go语言实现了一遍。Go语言内建的死锁检测器立即给出了提示:all goroutines are asleep — deadlock ,到底发生了什么呢?

-

开始时所有的worker完成初始化处于W1状态,然后尝试发送回复下载器的消息去contents通道(5),但它是一个对接通道,下载器不能立马收到。下载器处于D1正尝试发送消息去locations通道(2),但由于worker都在尝试发送所以无法接收。死锁发生了,所有的协程都在等待。

-
- -
- -

Solutions that do not work

问题好像出在select表达式。修复它很简单。相对于由下载器通过select处理来自referencescontents的消息,我们可以使用actor模型作为协程重写下载器,它有独立的mailbox通道来处理发送过来的消息。

-
1
2
3
4
5
6
for (msg in mailbox) {
when (msg) {
is Reference -> ...
is LocContent -> ...
}
}
- -

然而,actor模型也不能避免死锁,这种方式和原来一样代码很快被挂起。他们的通讯状态机是相同的。

-

另一个可能被指责的是集合信道——没有缓冲区的信道,因为它们在另一端没有接收器的情况下会暂停发送。即使我们给contentslocations添加buffer也不能解决此问题,只是减少了问题出现的概率或延迟出现。buffer越大出现的概率越低,但无法完全避免死锁的发生,一旦buffer满了发送器还是会挂起并发生死锁。

-

Unlimited-capacity channels

一种明确的避免死锁的解决方案是对被通讯死锁影响的channel中的至少一个使用不限大小的buffer,这里 的代码对contents通道使用了无限制buffer,似乎能正常工作。

-

然而,通过取消通道缓冲区的限制,我们丧失了CPS编程风格的利润丰厚的属性-自动背压传播.如果来自通道的消息的接收方比发送方慢,则发送方将挂起在全缓冲区上以自动减慢速度。有了无限容量的通道,就不会发生这种情况,管理背压的任务完全由应用程序开发人员承担。如果不能管理背压,系统最终可能会耗尽内存,在其缓冲区中收集越来越多的消息。

-

在我们的例子中,把locations通道设置成无限buffer会完全移除对传入引用的背压管理,因为即使所有的worker都处于忙碌状态,下载器也将发送所有的消息去locations通道。
把contents通道设置成无限buffer会更安全,因为它只影响下载内容的最终处理。然而,在无限容量的情况下,我们面临的风险是,下载器会被传入的references淹没,永远无法处理下载的内容。这使我们离最终解决方案更近一步。

-

Solutions that do work

我们调整一下下载器协程中select表达式的顺序,以便先检查contents通道,也就是说contents通道的消息优先级高于references通道:

-
1
2
3
4
5
6
7
8
select<Unit> {
contents.onReceive { ... }
references.onReceive {
...
locations.send(loc) // (2)
}
}

- -

它本身并没有解决这个问题(你可以在这里验证代码),但它给了一个有用的属性——
下载器只有在没有worker被挂起且worker准备发送消息去contents通道时,才发送消息去locations通道(2)。现在,提供至少一个buffer给contents通道就足够了,以确保至少有一个worker可以在(5)发送其内容,并在(4)再次开始从locations接收,从而允许下载程序继续进行:

-
1
val contents = Channel<LocContent>(1)
- -

这里 是能运行的代码。

-

注意,它是如何在3秒内处理比之前的无限渠道“解决方案”更多的下载的。此外,由于contents通道处理具有最高优先级,现在可以安全地拥有无限容量的contents通道。它在缓冲区中保存的消息永远不会超过工作人员的数量加1(为什么是加1 ?这是留给读者的练习)。

-

还有一种替代解决方案,它完全不使用缓冲通道,可以完美地与任何容量的通道一起工作。它加倍select,以避免在locations.send(loc)上挂起下载程序,将这个发送操作折叠为一个select。它实际上是CFSM模型中表示和分析的最简单的一个,但是我现在不会详细介绍它,把它留给将来的故事。你可以看一下这里 对应的代码并在playground中运行它。

-

总结

通信循环(非DAG模式)可能并将导致通道容量有限的通信死锁,除非使用一些死锁预防策略。如果在应用程序中遇到死锁,在了解发生了什么之前,不要尝试使用缓冲通道解决它,否则可能会把问题掩盖起来。

-

请在本文的评论中分享更多解决这种特殊通信循环死锁的有效解决方案。Kotlin和其他CSP/actor运行时中的代码都是受欢迎的(请提供链接,不要将代码粘贴到评论中)。

-

Credits

我要感谢Alexey Semin,他通过这个 github-issue报告了这个问题,并感谢Alexander Gorynin在Kotlin Slack里联系了我。还要感谢Simon Wirtz和Sean McQuillan对本文草稿的有用评论。

- - -
- - - - -
-
-
-

- - - - - - - -
- - - - - -
-

- - -

- - -
- - - - -
- - -

工作

- -
- - 阅读全文 » - -
- - - -
- - - - -
-
-
-
- - - - @@ -1499,7 +1536,7 @@

@@ -1536,13 +1573,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/archives/page/4/index.html b/archives/page/4/index.html index c23537a9..8b9cab27 100644 --- a/archives/page/4/index.html +++ b/archives/page/4/index.html @@ -185,6 +185,243 @@

蓝色的笔记本

+
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

简介:

本文是 Roman Elizarov 关于CSP中产生死锁问题的讨论,解释了其中的原因,并逐步给出了一种解决方案。部分翻译不恰当的可参考原文

+

原文:

众所周知,使用锁保护共享可变状态可能会导致死锁,但很少有人知道,使用无共享可变状态的CSP或actor模型也会导致死锁,尽管它们并不使用锁。它的死锁以另一种方式表现:通信死锁。

+

要知道,死锁的正式定义并没有直接与锁联系在一起。当每个进程都在循环等待下一个进程时,这组进程(线程/协程/参与者)就处于死锁状态。后面我们会看个例子,这里先道个歉,之前没强调这个问题。

+

The stage

在2018年的KotlinConf我发表了题为”Kotlin协程实践”的演讲,其中讲到了对于构建可信赖软件来说结构性并发是重要的,且介绍了CSP的一些高级概念。其中一个部分有点问题。如果你按照演讲中一字不差的写完代码会导致一个死锁。不知何故,我掉进了这个陷阱,以为它对我来说是安全的,但不是。让我们来分析一下

+

首先来讲,如果应用被组织成数据处理管道,消息进入系统,被不同的协程顺序处理,最后被送出系统,那么这种CSP风格的架构,包括actor模式,都是安全的。更广泛地说,只要代码具有协程的层次结构(或有向无环图),上游协程只向下游发送消息,且每个协程在同一个地方接收传过来的消息并向下游传递响应消息,代码就不会出现死锁。

+
+ +
+ + +

然而在我的演讲中,我草拟了一个数据处理循环的架构,下载器协程向任务池发送locations,并从任务池获取结果:

+
+ +
+ +

我演讲中的例子的架构基于3个channel:referenceslocationscontents。下载协程包含以下逻辑:

+
1
2
3
4
5
6
7
8
9
10
while (true) {
select<Unit> {
references.onReceive { ref -> // (1)
val loc = ref.resolveLocation()
...
locations.send(loc) // (2)
}
contents.onReceive { (loc, content) -> ... } // (3)
}
}
+

Downloader从references通道(1)接收,解析对位置的引用并将它们发送到locations通道(2)。它还通过从contents通道(3)接收来自workers的结果来更新其状态。另外,works有以下代码:

+
1
2
3
4
for (loc in locations) {                             // (4)
val content = downloadContent(loc)
contents.send(LocContent(loc, content)) // (5)
}
+ +

locations通道接收消息(4),并发送下载后的内容去contents通道(5)

+

即使在两段通信的代码中也很难遵循逻辑,但在CSP中有一种方便的方法来可视化它。我们可以用通信有限状态机(CFSM)表示我们的系统。这些状态相当于挂起点和向通信的转变过程:

+
+ +
+ +

为了简洁起见,上图中通道名简写。receive -> rcv、send -> snd 。下载器主循环中的select语句相当于D0状态,它能接收来自references通道的消息(1)或者来自contents通道的消息(3),当接收到来自references消息,切换到状态D1,等待发送消息去locations通道,如图中:(2)l.snd

+

Deadlock Demo

我用模拟数据类的方式完善了演讲中的代码,加入了delay(10)downloadContent方法。main函数则持续发送请求给下载器的references通道,它有4个workers且带3秒超时限制。此项目可以完整的运行,正常情况下3s应该处理1000次请求。

+

当你运行该项目时,你会发现只处理了4次请求(和我们定义的worker数量一样)就挂起了,直到3s超时。此外,它没有任何随机性,因为它是在单线程的runBlocking上下文中运行的。

+

为了说服你(还有我自己),这是CSP内在的行为而不是Kotlin实现的bug,我用Go语言实现了一遍。Go语言内建的死锁检测器立即给出了提示:all goroutines are asleep — deadlock ,到底发生了什么呢?

+

开始时所有的worker完成初始化处于W1状态,然后尝试发送回复下载器的消息去contents通道(5),但它是一个对接通道,下载器不能立马收到。下载器处于D1正尝试发送消息去locations通道(2),但由于worker都在尝试发送所以无法接收。死锁发生了,所有的协程都在等待。

+
+ +
+ +

Solutions that do not work

问题好像出在select表达式。修复它很简单。相对于由下载器通过select处理来自referencescontents的消息,我们可以使用actor模型作为协程重写下载器,它有独立的mailbox通道来处理发送过来的消息。

+
1
2
3
4
5
6
for (msg in mailbox) {
when (msg) {
is Reference -> ...
is LocContent -> ...
}
}
+ +

然而,actor模型也不能避免死锁,这种方式和原来一样代码很快被挂起。他们的通讯状态机是相同的。

+

另一个可能被指责的是集合信道——没有缓冲区的信道,因为它们在另一端没有接收器的情况下会暂停发送。即使我们给contentslocations添加buffer也不能解决此问题,只是减少了问题出现的概率或延迟出现。buffer越大出现的概率越低,但无法完全避免死锁的发生,一旦buffer满了发送器还是会挂起并发生死锁。

+

Unlimited-capacity channels

一种明确的避免死锁的解决方案是对被通讯死锁影响的channel中的至少一个使用不限大小的buffer,这里 的代码对contents通道使用了无限制buffer,似乎能正常工作。

+

然而,通过取消通道缓冲区的限制,我们丧失了CPS编程风格的利润丰厚的属性-自动背压传播.如果来自通道的消息的接收方比发送方慢,则发送方将挂起在全缓冲区上以自动减慢速度。有了无限容量的通道,就不会发生这种情况,管理背压的任务完全由应用程序开发人员承担。如果不能管理背压,系统最终可能会耗尽内存,在其缓冲区中收集越来越多的消息。

+

在我们的例子中,把locations通道设置成无限buffer会完全移除对传入引用的背压管理,因为即使所有的worker都处于忙碌状态,下载器也将发送所有的消息去locations通道。
把contents通道设置成无限buffer会更安全,因为它只影响下载内容的最终处理。然而,在无限容量的情况下,我们面临的风险是,下载器会被传入的references淹没,永远无法处理下载的内容。这使我们离最终解决方案更近一步。

+

Solutions that do work

我们调整一下下载器协程中select表达式的顺序,以便先检查contents通道,也就是说contents通道的消息优先级高于references通道:

+
1
2
3
4
5
6
7
8
select<Unit> {
contents.onReceive { ... }
references.onReceive {
...
locations.send(loc) // (2)
}
}

+ +

它本身并没有解决这个问题(你可以在这里验证代码),但它给了一个有用的属性——
下载器只有在没有worker被挂起且worker准备发送消息去contents通道时,才发送消息去locations通道(2)。现在,提供至少一个buffer给contents通道就足够了,以确保至少有一个worker可以在(5)发送其内容,并在(4)再次开始从locations接收,从而允许下载程序继续进行:

+
1
val contents = Channel<LocContent>(1)
+ +

这里 是能运行的代码。

+

注意,它是如何在3秒内处理比之前的无限渠道“解决方案”更多的下载的。此外,由于contents通道处理具有最高优先级,现在可以安全地拥有无限容量的contents通道。它在缓冲区中保存的消息永远不会超过工作人员的数量加1(为什么是加1 ?这是留给读者的练习)。

+

还有一种替代解决方案,它完全不使用缓冲通道,可以完美地与任何容量的通道一起工作。它加倍select,以避免在locations.send(loc)上挂起下载程序,将这个发送操作折叠为一个select。它实际上是CFSM模型中表示和分析的最简单的一个,但是我现在不会详细介绍它,把它留给将来的故事。你可以看一下这里 对应的代码并在playground中运行它。

+

总结

通信循环(非DAG模式)可能并将导致通道容量有限的通信死锁,除非使用一些死锁预防策略。如果在应用程序中遇到死锁,在了解发生了什么之前,不要尝试使用缓冲通道解决它,否则可能会把问题掩盖起来。

+

请在本文的评论中分享更多解决这种特殊通信循环死锁的有效解决方案。Kotlin和其他CSP/actor运行时中的代码都是受欢迎的(请提供链接,不要将代码粘贴到评论中)。

+

Credits

我要感谢Alexey Semin,他通过这个 github-issue报告了这个问题,并感谢Alexander Gorynin在Kotlin Slack里联系了我。还要感谢Simon Wirtz和Sean McQuillan对本文草稿的有用评论。

+ + +
+ + + + +
+
+
+
+ + + + + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

工作

+ +
+ + 阅读全文 » + +
+ + + +
+ + + + +
+
+
+
+ + + + + + +
@@ -1749,302 +1986,10 @@
- - - - - -
-

- - -

- - -
- - - - -
- - -

一、概述

synchronized作为Java内建的关键字和锁机制,理解和使用它是必要的也是有难度的。个人认为深入理解此关键字在于以下几个方面:

-
    -
  • 基础层面:正确理解对象锁和类锁,并熟练使用
  • -
  • 能力提升:
      -
    • 了解对象的内存布局,观察锁如何影响对象的内存布局
    • -
    • 了解锁优化,锁升级及其过程
    • -
    -
  • -
  • 更上一层楼:OpenJDK源码走读
  • -
-

本文只是记录和翻译了一些英文文档的内容,作为笔记以后翻阅。详细内容可看原文。

-

二、对象锁和类锁

1.1 对象锁:修饰代码块和实例方法

-
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
static class ObjectLock {
public void test1() {
synchronized (this) {//此代码块锁住当前对象
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}

public synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}
- - -

1.2 类锁:修饰代码块和静态方法

-
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
 static class ClazzLock {
public void test1() {
synchronized (ClazzLock.class) {//此代码块锁住class类
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}

/**
* 静态方法属于类
*/
public static synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}
- -

三、锁优化

依据一:数据显示,许多锁有局部性特征,也就是说很多锁的锁定和释放都发生在特定的线程上。
依据二:数据显示,大部分Java对象不存在竞争。

-
    -
  • 适应性自旋-Adaptive Spinning
  • -
  • 锁消除-Lock Elimination
  • -
  • 锁粗化-Lock Coarsening
  • -
  • 轻量级锁-Lightweight Locking
  • -
  • 偏向锁-Biased Locking
  • -
-
3.1 偏向锁

当我们开发了一个多线程环境下的模块时,其他人可能把它用在单线程环境下,此时加锁逻辑就是多余的。即使使用轻量级锁,每次获取锁都执行CAS原子指令也是一种性能损耗。使用偏向锁,线程首次获取锁时记录偏向于它自己,当有其他线程获取锁时,偏向锁要撤销,使用其他锁机制,如轻量级锁。

-

lock-field中有一个bit用于记录是否偏向状态,初始状态下是处于偏向锁状态,但没有设置偏向的线程ID。当线程首次获取锁时,发现没有指定偏向的线程,则使用CAS设置偏向线程,来避免竞态条件。

-
3.2 轻量级锁(Thin Lock)

相对于每次对象锁定都获取monitor结构的重量级锁而言,轻量级锁只是使用CAS原子指令修改lock-field(锁信息字段),因此轻量级锁不支持wait和notify。当发生锁竞争时,轻量级锁膨胀,同时分配monitor结构,lock-field更新成monitor的指针。

-

Java的锁是可重入的,所以需要记录当前锁的重入次数和锁的持有者。

-
    -
  • 记录方式一:
    最直接的方式是把lock-field分成两部分,一个记录锁的持有者,一个记录锁重入次数。由于lock-field字段长度固定,所以重入次数被限制了。重入次数达到上限只能升级为重量级锁。
  • -
-
    -
  • 记录方式二:
    当线程需要获取锁时,在获取锁的线程栈中保存lock-records记录。线程获取的所有锁记录都将保存在这个集合中,它的顺序和获取锁的顺序一致。
  • -
-

轻量级锁的变种和提升包含 tasuki-lockmeta-lock 其算法思想是一致的,差异在于实现细节,

-

1、轻量级锁的加锁过程

-

在代码进入同步块的时,如果同步对象锁状态为无锁(锁标志位为“01”,偏向锁位为“0”)虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝(官方称之为 Displaced Mark Word)。然后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针,并将Lock record里的owner指针指向object mark word。如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位设置为“00”,即表示此对象处于轻量级锁定状态。

-

如果这个更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是就说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行。
否则说明多个线程竞争锁,轻量级锁就要膨胀为重量级锁,锁标志的状态值变为“10”,Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也要进入阻塞状态。
而当前线程便尝试使用自旋来获取锁,自旋就是为了不让线程阻塞,而采用循环去获取锁的过程。

-
- -
- -
                 图2.1 轻量级锁CAS操作前/后堆栈与对象的状态
-
-

2、轻量级锁的解锁过程:

-

(1)通过CAS操作尝试把线程中复制的Displaced Mark Word对象替换当前的Mark Word。

-

(2)如果替换成功,整个同步过程就完成了。

-

(3)如果替换失败,说明有其他线程尝试过获取该锁(此时锁已膨胀),那就要在释放锁的同时,唤醒被挂起的线程。

-
3.3 锁消除

锁消除即删除不必要的加锁操作。根据代码逃逸技术,如果判断到一段代码中,堆上的数据不会逃逸出当前线程,那么可以认为这段代码是线程安全的,不必要加锁。

-
1
2
3
4
5
6
7
8
public class Test extends Thread{
public static void main(String[] args) {
contactString("aa", "bb", "cc");
}
public static String contactString(String s1, String s2, String s3) {
return new StringBuffer().append(s1).append(s2).append(s3).toString();
}
}
- -

虽然StringBuffer的append是一个同步方法,但是这段程序中的StringBuffer属于一个局部变量,并且不会从该方法中逃逸出去,所以其实这过程是线程安全的,可以将锁消除。

-
3.4 锁粗化

虚拟机对连续的加锁操作(synchronized append)进行范围扩展(粗化)到整个操作序列的外部。

-
1
2
3
4
5
6
7
public String concatString(String s1,String s2, String s3){
StringBuffer sb = new StringBUffer();
sb.append(s1);
sb.append(s2);
sb.append(s3);
return sb.toString();
}
- -

四、参考资料

1.Evaluating and improving biased locking in the HotSpot virtual machine
2.Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)
3.锁:锁优化(synchronized 锁升级过程、锁消除、锁粗化)
4.Synchronization

- - -
- - - - -
-
-
-
- - - - - - - -
- - - - - -
-

- - -

- - -
- - - - -
- - -

一、什么是Flow

1、如何通过同步和异步方式返回多个值?

1.1 同步方式返回多个值

-
1
2
3
4
5
fun simple(): List<Int> = listOf(1, 2, 3)

fun main() {
simple().forEach { value -> println(value) }
}
-

1.2 同步方式依次返回多个值

-
1
2
3
4
5
6
7
8
9
10
fun simple(): Sequence<Int> = sequence { // sequence builder
for (i in 1..3) {
Thread.sleep(1000) // pretend we are computing it
yield(i) // yield next value
}
}

fun main() {
simple().forEach { value -> println("time = ${System.currentTimeMillis()} ,$value") }
}
- - -

1.3 异步方式返回多个值

-
1
2
3
4
5
6
7
8
suspend fun simple(): List<Int> {
delay(1000) // pretend we are doing something asynchronous here
return listOf(1, 2, 3)
}

fun main() = runBlocking<Unit> {
simple().forEach { value -> println(value) }
}
- -

1.4 如何通过异步的方式依次返回多个值呢?

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fun simple(): Flow<Int> = flow { // flow builder
for (i in 1..3) {
delay(100) // pretend we are doing something useful here
emit(i) // emit next value
}
}

fun main() = runBlocking<Unit> {
// Launch a concurrent coroutine to check if the main thread is blocked
launch {
for (k in 1..3) {
println("I'm not blocked $k")
delay(100)
}
}
// Collect the flow
simple().collect { value -> println(value) }
}
- -

通过flow,我们可以实现异步的数据流。

-
2、Flow是冷数据流

冷数据流:每次调用collect函数时都会触发执行

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun simple(): Flow<Int> = flow { 
println("Flow started")
for (i in 1..3) {
delay(100)
emit(i)
}
}

fun main() = runBlocking<Unit> {
println("Calling simple function...")
val flow = simple()
println("Calling collect...")
flow.collect { value -> println(value) }
println("Calling collect again...")
flow.collect { value -> println(value) }
}
- -
3、Flow的取消
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun simple(): Flow<Int> = flow { 
for (i in 1..3) {
delay(100)
println("Emitting $i")
emit(i)
}
}

fun main() = runBlocking<Unit> {
withTimeoutOrNull(250) { // Timeout after 250ms
simple().collect { value -> println(value) }
}
println("Done")
}
- - -
4、如何构建Flow?
    -
  • flow{ ... }
  • -
  • flowOf
  • -
  • .asFlow()
  • -
-
5、Flow操作符

5.1 中间操作符

-
    -
  • map
  • -
  • filter
  • -
  • transform
  • -
  • take
  • -
-

5.2 终止操作符

-
    -
  • collect
  • -
  • toList / toSet
  • -
  • first / single
  • -
  • reduce / fold
  • -
-

5.3 buffer当流的处理速度慢于发射速度时,通过buffer提前缓存可以提高效率:

-

优化前:耗时1200ms

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
delay(100) // pretend we are asynchronously waiting 100 ms
emit(i) // emit next value
}
}

fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
simple().collect { value ->
delay(300) // pretend we are processing it for 300 ms
println(value)
}
}
println("Collected in $time ms")
}
-

优化后:耗时1000ms

-
1
2
3
4
5
6
7
8
9
val time = measureTimeMillis {
simple()
.buffer() // buffer emissions, don't wait
.collect { value ->
delay(300) // pretend we are processing it for 300 ms
println(value)
}
}
println("Collected in $time ms")
- -

5.4 conflate当生产速度大于消费速度,忽略未来得及处理的值

-
1
2
3
4
5
6
7
8
9
10
11
12
13
val time = measureTimeMillis {
simple()
.conflate() // conflate emissions, don't process each one
.collect { value ->
delay(300) // pretend we are processing it for 300 ms
println(value)
}
}
println("Collected in $time ms")
//输出:
//1
//3
//Collected in 758 ms
- -

5.5 collectLatest 如果消费者很慢,取消它,新值过来时再重新启动。

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val time = measureTimeMillis {
simple()
.collectLatest { value -> // cancel & restart on the latest value
println("Collecting $value")
delay(300) // pretend we are processing it for 300 ms
println("Done $value")
}
}
println("Collected in $time ms")
//output:
//Collecting 1
//Collecting 2
//Collecting 3
//Done 3
//Collected in 741 ms
- -

5.6 多个flow合并:zip / combine

-

使用zip操作符

-
1
2
3
4
5
6
7
8
val nums = (1..3).asFlow() // numbers 1..3
val strs = flowOf("one", "two", "three") // strings
nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string
.collect { println(it) } // collect and print
//output:
//1 -> one
//2 -> two
//3 -> three
- -

当两个flow不同步时:

-
1
2
3
4
5
6
7
8
9
10
11
12
//速度不同步时,使用zip,到达同步点才输出
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string with "zip"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 428 ms from start
//2 -> two at 828 ms from start
//3 -> three at 1230 ms from start
-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
////速度不同步时,使用combine,有值到达即输出,无视同步
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 452 ms from start
//2 -> one at 651 ms from start
//2 -> two at 854 ms from start
//3 -> two at 952 ms from start
//3 -> three at 1256 ms from start
- - -

参考文档:
1.官方文档

- - -
- - - - -
-
-
-
- - - - @@ -2114,7 +2059,7 @@

@@ -2151,13 +2096,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/archives/page/5/index.html b/archives/page/5/index.html index bc532c8d..f0406c2e 100644 --- a/archives/page/5/index.html +++ b/archives/page/5/index.html @@ -185,6 +185,298 @@

蓝色的笔记本

+
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

一、概述

synchronized作为Java内建的关键字和锁机制,理解和使用它是必要的也是有难度的。个人认为深入理解此关键字在于以下几个方面:

+
    +
  • 基础层面:正确理解对象锁和类锁,并熟练使用
  • +
  • 能力提升:
      +
    • 了解对象的内存布局,观察锁如何影响对象的内存布局
    • +
    • 了解锁优化,锁升级及其过程
    • +
    +
  • +
  • 更上一层楼:OpenJDK源码走读
  • +
+

本文只是记录和翻译了一些英文文档的内容,作为笔记以后翻阅。详细内容可看原文。

+

二、对象锁和类锁

1.1 对象锁:修饰代码块和实例方法

+
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
static class ObjectLock {
public void test1() {
synchronized (this) {//此代码块锁住当前对象
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}

public synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}
+ + +

1.2 类锁:修饰代码块和静态方法

+
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
 static class ClazzLock {
public void test1() {
synchronized (ClazzLock.class) {//此代码块锁住class类
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}

/**
* 静态方法属于类
*/
public static synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}
+ +

三、锁优化

依据一:数据显示,许多锁有局部性特征,也就是说很多锁的锁定和释放都发生在特定的线程上。
依据二:数据显示,大部分Java对象不存在竞争。

+
    +
  • 适应性自旋-Adaptive Spinning
  • +
  • 锁消除-Lock Elimination
  • +
  • 锁粗化-Lock Coarsening
  • +
  • 轻量级锁-Lightweight Locking
  • +
  • 偏向锁-Biased Locking
  • +
+
3.1 偏向锁

当我们开发了一个多线程环境下的模块时,其他人可能把它用在单线程环境下,此时加锁逻辑就是多余的。即使使用轻量级锁,每次获取锁都执行CAS原子指令也是一种性能损耗。使用偏向锁,线程首次获取锁时记录偏向于它自己,当有其他线程获取锁时,偏向锁要撤销,使用其他锁机制,如轻量级锁。

+

lock-field中有一个bit用于记录是否偏向状态,初始状态下是处于偏向锁状态,但没有设置偏向的线程ID。当线程首次获取锁时,发现没有指定偏向的线程,则使用CAS设置偏向线程,来避免竞态条件。

+
3.2 轻量级锁(Thin Lock)

相对于每次对象锁定都获取monitor结构的重量级锁而言,轻量级锁只是使用CAS原子指令修改lock-field(锁信息字段),因此轻量级锁不支持wait和notify。当发生锁竞争时,轻量级锁膨胀,同时分配monitor结构,lock-field更新成monitor的指针。

+

Java的锁是可重入的,所以需要记录当前锁的重入次数和锁的持有者。

+
    +
  • 记录方式一:
    最直接的方式是把lock-field分成两部分,一个记录锁的持有者,一个记录锁重入次数。由于lock-field字段长度固定,所以重入次数被限制了。重入次数达到上限只能升级为重量级锁。
  • +
+
    +
  • 记录方式二:
    当线程需要获取锁时,在获取锁的线程栈中保存lock-records记录。线程获取的所有锁记录都将保存在这个集合中,它的顺序和获取锁的顺序一致。
  • +
+

轻量级锁的变种和提升包含 tasuki-lockmeta-lock 其算法思想是一致的,差异在于实现细节,

+

1、轻量级锁的加锁过程

+

在代码进入同步块的时,如果同步对象锁状态为无锁(锁标志位为“01”,偏向锁位为“0”)虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝(官方称之为 Displaced Mark Word)。然后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针,并将Lock record里的owner指针指向object mark word。如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位设置为“00”,即表示此对象处于轻量级锁定状态。

+

如果这个更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是就说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行。
否则说明多个线程竞争锁,轻量级锁就要膨胀为重量级锁,锁标志的状态值变为“10”,Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也要进入阻塞状态。
而当前线程便尝试使用自旋来获取锁,自旋就是为了不让线程阻塞,而采用循环去获取锁的过程。

+
+ +
+ +
                 图2.1 轻量级锁CAS操作前/后堆栈与对象的状态
+
+

2、轻量级锁的解锁过程:

+

(1)通过CAS操作尝试把线程中复制的Displaced Mark Word对象替换当前的Mark Word。

+

(2)如果替换成功,整个同步过程就完成了。

+

(3)如果替换失败,说明有其他线程尝试过获取该锁(此时锁已膨胀),那就要在释放锁的同时,唤醒被挂起的线程。

+
3.3 锁消除

锁消除即删除不必要的加锁操作。根据代码逃逸技术,如果判断到一段代码中,堆上的数据不会逃逸出当前线程,那么可以认为这段代码是线程安全的,不必要加锁。

+
1
2
3
4
5
6
7
8
public class Test extends Thread{
public static void main(String[] args) {
contactString("aa", "bb", "cc");
}
public static String contactString(String s1, String s2, String s3) {
return new StringBuffer().append(s1).append(s2).append(s3).toString();
}
}
+ +

虽然StringBuffer的append是一个同步方法,但是这段程序中的StringBuffer属于一个局部变量,并且不会从该方法中逃逸出去,所以其实这过程是线程安全的,可以将锁消除。

+
3.4 锁粗化

虚拟机对连续的加锁操作(synchronized append)进行范围扩展(粗化)到整个操作序列的外部。

+
1
2
3
4
5
6
7
public String concatString(String s1,String s2, String s3){
StringBuffer sb = new StringBUffer();
sb.append(s1);
sb.append(s2);
sb.append(s3);
return sb.toString();
}
+ +

四、参考资料

1.Evaluating and improving biased locking in the HotSpot virtual machine
2.Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)
3.锁:锁优化(synchronized 锁升级过程、锁消除、锁粗化)
4.Synchronization

+ + +
+ + + + +
+
+
+
+ + + + + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

一、什么是Flow

1、如何通过同步和异步方式返回多个值?

1.1 同步方式返回多个值

+
1
2
3
4
5
fun simple(): List<Int> = listOf(1, 2, 3)

fun main() {
simple().forEach { value -> println(value) }
}
+

1.2 同步方式依次返回多个值

+
1
2
3
4
5
6
7
8
9
10
fun simple(): Sequence<Int> = sequence { // sequence builder
for (i in 1..3) {
Thread.sleep(1000) // pretend we are computing it
yield(i) // yield next value
}
}

fun main() {
simple().forEach { value -> println("time = ${System.currentTimeMillis()} ,$value") }
}
+ + +

1.3 异步方式返回多个值

+
1
2
3
4
5
6
7
8
suspend fun simple(): List<Int> {
delay(1000) // pretend we are doing something asynchronous here
return listOf(1, 2, 3)
}

fun main() = runBlocking<Unit> {
simple().forEach { value -> println(value) }
}
+ +

1.4 如何通过异步的方式依次返回多个值呢?

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fun simple(): Flow<Int> = flow { // flow builder
for (i in 1..3) {
delay(100) // pretend we are doing something useful here
emit(i) // emit next value
}
}

fun main() = runBlocking<Unit> {
// Launch a concurrent coroutine to check if the main thread is blocked
launch {
for (k in 1..3) {
println("I'm not blocked $k")
delay(100)
}
}
// Collect the flow
simple().collect { value -> println(value) }
}
+ +

通过flow,我们可以实现异步的数据流。

+
2、Flow是冷数据流

冷数据流:每次调用collect函数时都会触发执行

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun simple(): Flow<Int> = flow { 
println("Flow started")
for (i in 1..3) {
delay(100)
emit(i)
}
}

fun main() = runBlocking<Unit> {
println("Calling simple function...")
val flow = simple()
println("Calling collect...")
flow.collect { value -> println(value) }
println("Calling collect again...")
flow.collect { value -> println(value) }
}
+ +
3、Flow的取消
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun simple(): Flow<Int> = flow { 
for (i in 1..3) {
delay(100)
println("Emitting $i")
emit(i)
}
}

fun main() = runBlocking<Unit> {
withTimeoutOrNull(250) { // Timeout after 250ms
simple().collect { value -> println(value) }
}
println("Done")
}
+ + +
4、如何构建Flow?
    +
  • flow{ ... }
  • +
  • flowOf
  • +
  • .asFlow()
  • +
+
5、Flow操作符

5.1 中间操作符

+
    +
  • map
  • +
  • filter
  • +
  • transform
  • +
  • take
  • +
+

5.2 终止操作符

+
    +
  • collect
  • +
  • toList / toSet
  • +
  • first / single
  • +
  • reduce / fold
  • +
+

5.3 buffer当流的处理速度慢于发射速度时,通过buffer提前缓存可以提高效率:

+

优化前:耗时1200ms

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
delay(100) // pretend we are asynchronously waiting 100 ms
emit(i) // emit next value
}
}

fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
simple().collect { value ->
delay(300) // pretend we are processing it for 300 ms
println(value)
}
}
println("Collected in $time ms")
}
+

优化后:耗时1000ms

+
1
2
3
4
5
6
7
8
9
val time = measureTimeMillis {
simple()
.buffer() // buffer emissions, don't wait
.collect { value ->
delay(300) // pretend we are processing it for 300 ms
println(value)
}
}
println("Collected in $time ms")
+ +

5.4 conflate当生产速度大于消费速度,忽略未来得及处理的值

+
1
2
3
4
5
6
7
8
9
10
11
12
13
val time = measureTimeMillis {
simple()
.conflate() // conflate emissions, don't process each one
.collect { value ->
delay(300) // pretend we are processing it for 300 ms
println(value)
}
}
println("Collected in $time ms")
//输出:
//1
//3
//Collected in 758 ms
+ +

5.5 collectLatest 如果消费者很慢,取消它,新值过来时再重新启动。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val time = measureTimeMillis {
simple()
.collectLatest { value -> // cancel & restart on the latest value
println("Collecting $value")
delay(300) // pretend we are processing it for 300 ms
println("Done $value")
}
}
println("Collected in $time ms")
//output:
//Collecting 1
//Collecting 2
//Collecting 3
//Done 3
//Collected in 741 ms
+ +

5.6 多个flow合并:zip / combine

+

使用zip操作符

+
1
2
3
4
5
6
7
8
val nums = (1..3).asFlow() // numbers 1..3
val strs = flowOf("one", "two", "three") // strings
nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string
.collect { println(it) } // collect and print
//output:
//1 -> one
//2 -> two
//3 -> three
+ +

当两个flow不同步时:

+
1
2
3
4
5
6
7
8
9
10
11
12
//速度不同步时,使用zip,到达同步点才输出
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string with "zip"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 428 ms from start
//2 -> two at 828 ms from start
//3 -> three at 1230 ms from start
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
////速度不同步时,使用combine,有值到达即输出,无视同步
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 452 ms from start
//2 -> one at 651 ms from start
//2 -> two at 854 ms from start
//3 -> two at 952 ms from start
//3 -> three at 1256 ms from start
+ + +

参考文档:
1.官方文档

+ + +
+ + + + +
+
+
+
+ + + + + + +
@@ -1371,202 +1663,10 @@

- - - - - -
-

- - -

- - -
- - - - -
- - -

Leetode-2 两数相加

-

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

-
- -
- - 阅读全文 » - -
- - - -
- - - - -
-
-
-

- - - - - - - -
- - - - - -
-

- - -

- - -
- - - - -
- - -

给你单链表的头结点 head,请你反转链表,并返回反转后的链表。

- -
- - 阅读全文 » - -
- - - -
- - - - -
-
-
-
- - - - @@ -1636,7 +1736,7 @@

@@ -1673,13 +1773,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/archives/page/6/index.html b/archives/page/6/index.html new file mode 100644 index 00000000..97d74d47 --- /dev/null +++ b/archives/page/6/index.html @@ -0,0 +1,598 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

蓝色的笔记本

+ +
+

记录学习内容

+
+ + +
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

Leetode-2 两数相加

+

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

+
+ +
+ + 阅读全文 » + +
+ + + +
+ + + + +
+
+
+
+ + + + + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

给你单链表的头结点 head,请你反转链表,并返回反转后的链表。

+ +
+ + 阅读全文 » + +
+ + + +
+ + + + +
+
+
+
+ + + + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/atom.xml b/atom.xml index ad96d4ba..fe5d9d86 100644 --- a/atom.xml +++ b/atom.xml @@ -6,7 +6,7 @@ - 2024-09-22T06:35:15.822Z + 2024-10-21T10:29:03.762Z https://wangduwei.top/ @@ -16,6 +16,59 @@ Hexo + + 做事必须搞清的十六个顺序 + + https://wangduwei.top/%E5%81%9A%E4%BA%8B%E5%BF%85%E9%A1%BB%E6%90%9E%E6%B8%85%E7%9A%84%E5%8D%81%E5%85%AD%E4%B8%AA%E9%A1%BA%E5%BA%8F.html + 2024-10-19T12:27:56.000Z + 2024-10-21T10:29:03.762Z + + + + + + + <blockquote> +<p>以下内容在一篇公众号里面看到的,觉得很有道理,记录在此,常思之。</p> +</blockquote> +<p>01 沟通:先求同,再求异<br> + + + + + + + + + + + + 源码分析-性能监控之Measure + + https://wangduwei.top/android-github-source-measure.html + 2024-09-24T07:42:26.000Z + 2024-10-22T09:06:07.973Z + + + + + + + <h5 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h5><p><a + + + + + + + + + + + + + + 《高纬度思考法》 @@ -454,56 +507,4 @@ - - 投资回报率 - - https://wangduwei.top/econonmics-roa-roe-roic-roce.html - 2022-06-13T09:04:39.000Z - 2024-04-29T11:50:54.577Z - - - - - - - <h4 id="一、概述"><a href="#一、概述" class="headerlink" - - - - - - - - - - - - - - Kotlin Flow的工作原理 - - https://wangduwei.top/kotlin-lang-flow-under-the-hood.html - 2022-05-25T03:08:23.000Z - 2024-04-29T11:50:54.582Z - - - - - - - <hr> -<p>我们有一个会被重复调用的lambda表达式:</p> -<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span - - - - - - - - - - - - diff --git a/baidusitemap.xml b/baidusitemap.xml index 2037fd15..fef3032e 100644 --- a/baidusitemap.xml +++ b/baidusitemap.xml @@ -1,5 +1,13 @@ + + https://wangduwei.top/android-github-source-measure.html + 2024-10-22 + + + https://wangduwei.top/%E5%81%9A%E4%BA%8B%E5%BF%85%E9%A1%BB%E6%90%9E%E6%B8%85%E7%9A%84%E5%8D%81%E5%85%AD%E4%B8%AA%E9%A1%BA%E5%BA%8F.html + 2024-10-21 + https://wangduwei.top/%E3%80%8A%E9%AB%98%E7%BA%AC%E5%BA%A6%E6%80%9D%E8%80%83%E6%B3%95%E3%80%8B.html 2024-09-22 @@ -193,11 +201,11 @@ 2024-04-29 - https://wangduwei.top/android-github-source-workmanager.html + https://wangduwei.top/android-github-source-spacex.html 2024-04-29 - https://wangduwei.top/android-github-source-spacex.html + https://wangduwei.top/android-github-source-workmanager.html 2024-04-29 \ No newline at end of file diff --git a/base-economic-concept.html b/base-economic-concept.html index a0144819..06c559aa 100644 --- a/base-economic-concept.html +++ b/base-economic-concept.html @@ -489,7 +489,7 @@

- 27 + 28 标签 @@ -526,13 +526,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/basic-encryption-algorithm.html b/basic-encryption-algorithm.html index 6c07a3e6..742c81ba 100644 --- a/basic-encryption-algorithm.html +++ b/basic-encryption-algorithm.html @@ -448,7 +448,7 @@
@@ -485,13 +485,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/categories/Reading/index.html b/categories/Reading/index.html index 4e2f69e8..05ca6370 100644 --- a/categories/Reading/index.html +++ b/categories/Reading/index.html @@ -340,7 +340,7 @@

Reading @@ -377,13 +377,13 @@

Reading - 131k + 133k - 1:59 + 2:01 diff --git a/categories/index.html b/categories/index.html index ac304eb0..55dcb3c4 100644 --- a/categories/index.html +++ b/categories/index.html @@ -213,7 +213,7 @@

分类 目前共计 4 个分类 @@ -294,7 +294,7 @@

分类 @@ -331,13 +331,13 @@

分类 - 131k + 133k - 1:59 + 2:01 diff --git "a/categories/\345\267\245\344\275\234/index.html" "b/categories/\345\267\245\344\275\234/index.html" index bc28a515..710b60ff 100644 --- "a/categories/\345\267\245\344\275\234/index.html" +++ "b/categories/\345\267\245\344\275\234/index.html" @@ -294,7 +294,7 @@

工作 @@ -331,13 +331,13 @@

工作 - 131k + 133k - 1:59 + 2:01 diff --git "a/categories/\347\273\217\346\265\216\345\255\246/index.html" "b/categories/\347\273\217\346\265\216\345\255\246/index.html" index 3cda4f36..5587fce6 100644 --- "a/categories/\347\273\217\346\265\216\345\255\246/index.html" +++ "b/categories/\347\273\217\346\265\216\345\255\246/index.html" @@ -337,7 +337,7 @@

经济学 @@ -374,13 +374,13 @@

经济学 - 131k + 133k - 1:59 + 2:01 diff --git "a/categories/\350\256\241\347\256\227\346\234\272/index.html" "b/categories/\350\256\241\347\256\227\346\234\272/index.html" index 027e825a..99e1d869 100644 --- "a/categories/\350\256\241\347\256\227\346\234\272/index.html" +++ "b/categories/\350\256\241\347\256\227\346\234\272/index.html" @@ -195,6 +195,29 @@

计算机 +
+ 2024 +
+ +
2023
@@ -382,26 +405,6 @@

计算机

-
-
- - - -
- -
- -
-
- @@ -480,7 +483,7 @@

计算机
- 27 + 28 标签
@@ -517,13 +520,13 @@

计算机 站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git "a/categories/\350\256\241\347\256\227\346\234\272/page/2/index.html" "b/categories/\350\256\241\347\256\227\346\234\272/page/2/index.html" index 40cc8186..86f6aed3 100644 --- "a/categories/\350\256\241\347\256\227\346\234\272/page/2/index.html" +++ "b/categories/\350\256\241\347\256\227\346\234\272/page/2/index.html" @@ -195,6 +195,29 @@

计算机 +
+ 2022 +
+ +
+
+ + + +
+ +
+ +
+
2021
@@ -379,26 +402,6 @@

计算机 -
-
- - - -
- -
- -
-
- @@ -477,7 +480,7 @@

计算机
- 27 + 28 标签
@@ -514,13 +517,13 @@

计算机 站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git "a/categories/\350\256\241\347\256\227\346\234\272/page/3/index.html" "b/categories/\350\256\241\347\256\227\346\234\272/page/3/index.html" index 60685215..4962cfbd 100644 --- "a/categories/\350\256\241\347\256\227\346\234\272/page/3/index.html" +++ "b/categories/\350\256\241\347\256\227\346\234\272/page/3/index.html" @@ -199,6 +199,26 @@

计算机 2021 +
+
+ + + +
+ +
+ +
+
+
@@ -379,26 +399,6 @@

计算机

-
-
- - - -
- -
- -
-
- @@ -477,7 +477,7 @@

计算机
- 27 + 28 标签
@@ -514,13 +514,13 @@

计算机 站点总字数: - 131k + 133k | 站点阅读时长 ≈ - 1:59 + 2:01 diff --git "a/categories/\350\256\241\347\256\227\346\234\272/page/4/index.html" "b/categories/\350\256\241\347\256\227\346\234\272/page/4/index.html" index b3aaa17c..4669178f 100644 --- "a/categories/\350\256\241\347\256\227\346\234\272/page/4/index.html" +++ "b/categories/\350\256\241\347\256\227\346\234\272/page/4/index.html" @@ -199,6 +199,26 @@

计算机 2021 +
+
+ + + +
+ +
+ +
+
+
@@ -297,7 +317,7 @@

计算机 @@ -334,13 +354,13 @@

计算机 - 131k + 133k - 1:59 + 2:01 diff --git a/cpu-cache-overview.html b/cpu-cache-overview.html index f5321d3b..e669a4d0 100644 --- a/cpu-cache-overview.html +++ b/cpu-cache-overview.html @@ -466,7 +466,7 @@

@@ -503,13 +503,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/cpu-pipline-overview.html b/cpu-pipline-overview.html index e6e1aeb6..2708a64f 100644 --- a/cpu-pipline-overview.html +++ b/cpu-pipline-overview.html @@ -467,7 +467,7 @@
@@ -504,13 +504,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/cs-data-structure-bloomfilter.html b/cs-data-structure-bloomfilter.html index 81f7369c..11eb5645 100644 --- a/cs-data-structure-bloomfilter.html +++ b/cs-data-structure-bloomfilter.html @@ -417,7 +417,7 @@

- 27 + 28 标签 @@ -454,13 +454,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/cs-operating-systems-file-system.html b/cs-operating-systems-file-system.html index 2a16125d..794a8b8f 100644 --- a/cs-operating-systems-file-system.html +++ b/cs-operating-systems-file-system.html @@ -520,7 +520,7 @@
@@ -557,13 +557,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/css/main.css b/css/main.css index 733430ee..7dbcbd4d 100644 --- a/css/main.css +++ b/css/main.css @@ -1168,7 +1168,7 @@ pre .javascript .function { } .links-of-author a::before, .links-of-author span.exturl::before { - background: #94aaff; + background: #de4749; border-radius: 50%; content: ' '; display: inline-block; diff --git a/econonmics-roa-roe-roic-roce.html b/econonmics-roa-roe-roic-roce.html index 2296d09a..8c679c3b 100644 --- a/econonmics-roa-roe-roic-roce.html +++ b/econonmics-roa-roe-roic-roce.html @@ -489,7 +489,7 @@

@@ -526,13 +526,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/ep-good-developer-manifesto.html b/ep-good-developer-manifesto.html index f0030ac7..e6450367 100644 --- a/ep-good-developer-manifesto.html +++ b/ep-good-developer-manifesto.html @@ -411,7 +411,7 @@

@@ -448,13 +448,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/file-format-class.html b/file-format-class.html index 509933d1..58dfdd67 100644 --- a/file-format-class.html +++ b/file-format-class.html @@ -513,7 +513,7 @@

@@ -550,13 +550,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/file-format-elf-relocation.html b/file-format-elf-relocation.html index 248422ad..1a410778 100644 --- a/file-format-elf-relocation.html +++ b/file-format-elf-relocation.html @@ -432,7 +432,7 @@

@@ -469,13 +469,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/file-format-elf.html b/file-format-elf.html index 6889dc61..ed831846 100644 --- a/file-format-elf.html +++ b/file-format-elf.html @@ -618,7 +618,7 @@

@@ -655,13 +655,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/flutter-state-bloc.html b/flutter-state-bloc.html index eb90812c..bd8a2e3d 100644 --- a/flutter-state-bloc.html +++ b/flutter-state-bloc.html @@ -433,7 +433,7 @@

- 27 + 28 标签 @@ -470,13 +470,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/flutter-state-provider.html b/flutter-state-provider.html index 72c597bc..02256e8f 100644 --- a/flutter-state-provider.html +++ b/flutter-state-provider.html @@ -471,7 +471,7 @@

参考 @@ -508,13 +508,13 @@

参考 - 131k + 133k - 1:59 + 2:01 diff --git a/flutter-widget-row.html b/flutter-widget-row.html index f0f522b5..3908208f 100644 --- a/flutter-widget-row.html +++ b/flutter-widget-row.html @@ -497,7 +497,7 @@

- 27 + 28 标签 @@ -534,13 +534,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/index.html b/index.html index f44e0b1e..daa3703a 100644 --- a/index.html +++ b/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -198,6 +198,46 @@

蓝色的笔记本

2024
+
+ + +
@@ -358,49 +398,6 @@

蓝色的笔记本

- -
- 2023 -
- - - @@ -410,7 +407,7 @@

蓝色的笔记本

@@ -480,7 +477,7 @@

蓝色的笔记本

@@ -517,13 +514,13 @@

蓝色的笔记本

- 131k + 133k - 1:59 + 2:01 diff --git a/java-multithreading-synchronized.html b/java-multithreading-synchronized.html index 55a6bf80..6a05f0b4 100644 --- a/java-multithreading-synchronized.html +++ b/java-multithreading-synchronized.html @@ -469,7 +469,7 @@

@@ -506,13 +506,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/java-object-layout.html b/java-object-layout.html index 31a8d7d4..090b713f 100644 --- a/java-object-layout.html +++ b/java-object-layout.html @@ -494,7 +494,7 @@
@@ -531,13 +531,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-coroutine-deep-recursion.html b/kotlin-coroutine-deep-recursion.html index 20523725..8bdf1e2a 100644 --- a/kotlin-coroutine-deep-recursion.html +++ b/kotlin-coroutine-deep-recursion.html @@ -446,7 +446,7 @@

@@ -483,13 +483,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-flow-under-the-hood.html b/kotlin-lang-flow-under-the-hood.html index b8e40901..17e5ca0a 100644 --- a/kotlin-lang-flow-under-the-hood.html +++ b/kotlin-lang-flow-under-the-hood.html @@ -430,7 +430,7 @@

@@ -467,13 +467,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-flow.html b/kotlin-lang-flow.html index ef816fbf..0cb46112 100644 --- a/kotlin-lang-flow.html +++ b/kotlin-lang-flow.html @@ -467,7 +467,7 @@

@@ -504,13 +504,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-inline-func-param.html b/kotlin-lang-inline-func-param.html index 9025f304..c3bf4914 100644 --- a/kotlin-lang-inline-func-param.html +++ b/kotlin-lang-inline-func-param.html @@ -544,7 +544,7 @@
- 27 + 28 标签 @@ -581,13 +581,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-jvm-annotation.html b/kotlin-lang-jvm-annotation.html index e3dc7419..7fd11c31 100644 --- a/kotlin-lang-jvm-annotation.html +++ b/kotlin-lang-jvm-annotation.html @@ -483,7 +483,7 @@

[参 @@ -520,13 +520,13 @@

[参 - 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-jvmstatic-with-interface.html b/kotlin-lang-jvmstatic-with-interface.html index 0cfffcb0..8db0a9a6 100644 --- a/kotlin-lang-jvmstatic-with-interface.html +++ b/kotlin-lang-jvmstatic-with-interface.html @@ -442,7 +442,7 @@

参考 @@ -479,13 +479,13 @@

参考 - 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-sequence.html b/kotlin-lang-sequence.html index 9e102ca1..1d1e2f53 100644 --- a/kotlin-lang-sequence.html +++ b/kotlin-lang-sequence.html @@ -563,7 +563,7 @@

- 27 + 28 标签 @@ -600,13 +600,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-use-dsl.html b/kotlin-lang-use-dsl.html index 2654271d..cb60d357 100644 --- a/kotlin-lang-use-dsl.html +++ b/kotlin-lang-use-dsl.html @@ -510,7 +510,7 @@

- 27 + 28 标签 @@ -547,13 +547,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/kotlin-lang-use-mutable-collection.html b/kotlin-lang-use-mutable-collection.html index 2721fdbf..ed63ce50 100644 --- a/kotlin-lang-use-mutable-collection.html +++ b/kotlin-lang-use-mutable-collection.html @@ -417,7 +417,7 @@

@@ -454,13 +454,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/leetcode-list-add.html b/leetcode-list-add.html index abec3ea7..4ffdc955 100644 --- a/leetcode-list-add.html +++ b/leetcode-list-add.html @@ -443,7 +443,7 @@

- 27 + 28 标签 @@ -480,13 +480,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/leetcode-reverse-list.html b/leetcode-reverse-list.html index 95b2c23a..c45bde1f 100644 --- a/leetcode-reverse-list.html +++ b/leetcode-reverse-list.html @@ -456,7 +456,7 @@

@@ -493,13 +493,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git a/model-csp-deadlocks.html b/model-csp-deadlocks.html index 5a64375b..a311ea68 100644 --- a/model-csp-deadlocks.html +++ b/model-csp-deadlocks.html @@ -34,8 +34,8 @@ - + @@ -371,8 +371,8 @@

Credi
@@ -469,7 +469,7 @@

Credi @@ -506,13 +506,13 @@

Credi - 131k + 133k - 1:59 + 2:01 diff --git a/my-work-of-this-week-01.html b/my-work-of-this-week-01.html index ccf153b7..fd2f383e 100644 --- a/my-work-of-this-week-01.html +++ b/my-work-of-this-week-01.html @@ -437,7 +437,7 @@

@@ -474,13 +474,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/page/2/index.html b/page/2/index.html index 0de8f2c8..fb742874 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -190,14 +190,57 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
+
+ 2024 +
+ +
2023
+ +
@@ -361,46 +404,6 @@

蓝色的笔记本

- - - -
@@ -410,7 +413,7 @@

蓝色的笔记本

@@ -480,7 +483,7 @@

蓝色的笔记本

@@ -517,13 +520,13 @@

蓝色的笔记本

- 131k + 133k - 1:59 + 2:01 diff --git a/page/3/index.html b/page/3/index.html index 05e0963a..a6ad4a0e 100644 --- a/page/3/index.html +++ b/page/3/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -198,6 +198,46 @@

蓝色的笔记本

2022
+ + + +
@@ -361,46 +401,6 @@

蓝色的笔记本

- - - - @@ -410,7 +410,7 @@

蓝色的笔记本

@@ -480,7 +480,7 @@

蓝色的笔记本

@@ -517,13 +517,13 @@

蓝色的笔记本

- 131k + 133k - 1:59 + 2:01 diff --git a/page/4/index.html b/page/4/index.html index 8c663193..08511bfe 100644 --- a/page/4/index.html +++ b/page/4/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -198,6 +198,46 @@

蓝色的笔记本

2021
+ + + +
@@ -358,46 +398,6 @@

蓝色的笔记本

- - - - @@ -407,7 +407,7 @@

蓝色的笔记本

@@ -477,7 +477,7 @@

蓝色的笔记本

@@ -514,13 +514,13 @@

蓝色的笔记本

- 131k + 133k - 1:59 + 2:01 diff --git a/page/5/index.html b/page/5/index.html index 2daa0113..184f5902 100644 --- a/page/5/index.html +++ b/page/5/index.html @@ -190,7 +190,7 @@

蓝色的笔记本

- 还行! 目前共计 50 篇日志。 继续努力。 + 不错! 目前共计 52 篇日志。 继续努力。
@@ -198,6 +198,46 @@

蓝色的笔记本

2021
+ + + +
@@ -358,46 +398,6 @@

蓝色的笔记本

- - - - @@ -407,7 +407,7 @@

蓝色的笔记本

@@ -477,7 +477,7 @@

蓝色的笔记本

@@ -514,13 +514,13 @@

蓝色的笔记本

- 131k + 133k - 1:59 + 2:01 diff --git a/page/6/index.html b/page/6/index.html new file mode 100644 index 00000000..da19b635 --- /dev/null +++ b/page/6/index.html @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 归档 | 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

蓝色的笔记本

+ +
+

记录学习内容

+
+ + +
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+
+
+ + 不错! 目前共计 52 篇日志。 继续努力。 +
+ + +
+ 2021 +
+ + + + + + +
+
+ + + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/principles-of-economics.html b/principles-of-economics.html index a94bb407..5f73489e 100644 --- a/principles-of-economics.html +++ b/principles-of-economics.html @@ -432,7 +432,7 @@
- 27 + 28 标签 @@ -469,13 +469,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git a/search.xml b/search.xml index 417b0761..0fe4e5ae 100644 --- a/search.xml +++ b/search.xml @@ -473,6 +473,52 @@ View + + 源码分析-性能监控之Measure + /android-github-source-measure.html + 概述

Measure是一个开源的性能监控项目,它包含:Android、iOS、前端、后端。这里分析一下Android端的逻辑实现。

+
分析

项目的基本结构:

+
    +
  • measure-android

    +
      +
    • measure
    • +
    • measure-android-gradle
    • +
    • sample
    • +
    +
  • +
  • measure模块的内容:

    +
      +
    • ANR捕获:Native实现,注册信号处理器,捕获SIGQUIT信号
    • +
    • AppLaunch:区分冷起、热起、温启动,并对外回调。
    • +
    • AppExit:ActivityManager#getHistoricalProcessExitReasons的使用
    • +
    • performance:
        +
      • cpu usage
      • +
      • memory usage
      • +
      +
    • +
    • NetworkChange:网络变化的监控
    • +
    • ScreenShot:生成屏幕截图,PixelCopy的使用,或者Canvas画上去
    • +
    • 其他模块:周期性的心跳包(Heartbeat)去执行任务。Okhttp拦截器。
    • +
    +
  • +
  • measure-android-gradle

    +
      +
    • Manifest数据读取,AppId、VersionCode、VersionName
    • +
    • Mapping文件上传
    • +
    • Apk、Aab大小信息上传
    • +
    +
  • +
+
总结:

1、冷热起的判断逻辑,这部分代码参考自Square的PaPa有参考价值
2、各功能的对外调用都是接口化的,无侵入性
3、项目简单,阅读起来很顺。
4、包含前后端代码,看板,值得学习。

+]]> + + 计算机 + + + Android + 安卓框架 + + 源码分析-网络框架之Retrofit /android-github-source-retrofit.html @@ -500,6 +546,42 @@ 安卓框架 + + 源码分析-项目架构之SpaceX + /android-github-source-spacex.html + 一、概述

此文是对Github开源项目SpaceX-prepare-for-Clean-Architecture-liftoff 的源码阅读记录。它是一个为了阐述对Clean Architecture的理解而作的Demo项目,是一个值得学习的项目。

+

二、源码分析

2.1 模块之间的依赖关系

项目包含以下library:

+
    +
  • app
  • +
  • buildSrc
  • +
  • core
  • +
  • core-android-test
  • +
  • data
  • +
  • data-api
  • +
  • domain
  • +
  • navigation
  • +
  • presentation
  • +
+

模块之间的依赖关系可用下图简述:

+
+ +
+ +

2.2 类和模块之间的关系
+ +
+ + +

三、总结

项目重在阐述架构思想所以比较简单,其中很多东西值得我们在项目中借鉴。数据层的架构模式参看martin fowler 的文章。

+]]> + + 计算机 + + + Android + 架构 + + 源码分析-WorkManager /android-github-source-workmanager.html @@ -546,42 +628,6 @@ Android - - 源码分析-项目架构之SpaceX - /android-github-source-spacex.html - 一、概述

此文是对Github开源项目SpaceX-prepare-for-Clean-Architecture-liftoff 的源码阅读记录。它是一个为了阐述对Clean Architecture的理解而作的Demo项目,是一个值得学习的项目。

-

二、源码分析

2.1 模块之间的依赖关系

项目包含以下library:

-
    -
  • app
  • -
  • buildSrc
  • -
  • core
  • -
  • core-android-test
  • -
  • data
  • -
  • data-api
  • -
  • domain
  • -
  • navigation
  • -
  • presentation
  • -
-

模块之间的依赖关系可用下图简述:

-
- -
- -

2.2 类和模块之间的关系
- -
- - -

三、总结

项目重在阐述架构思想所以比较简单,其中很多东西值得我们在项目中借鉴。数据层的架构模式参看martin fowler 的文章。

-]]> - - 计算机 - - - Android - 架构 - - Jetpack Compose Side Effects /android-jetpack-compose-sideeffect.html @@ -995,6 +1041,97 @@ Android + + 估值指标 + /base-economic-concept.html + + + +英文名称 +中文名称 +计算方式 +理解 + + + +PE = Price-to-Earning Ratio +市盈率 +每股股价/每股盈余 = 市值/净利润 +创造财富的能力、回收成本的时间 + + +PS = Price-to-Sales Ratio +市销率 +每股股价/每股营收 = 市值/营收 +获得公司1元的销售收入需要投入多少钱 + + +PCF =Price-to-Cash-Flow Ratio +市现率 +每股股价/每股现金流 = 市值/12月现金流 + + + +PB = Price-to-Book Ratio +市净率 +每股股价/每股净资产 = 市值/净资产 +净资产的溢价程度 + + +

一、市盈率

1.1 PE - 静态市盈率

+
+

① 市盈率 = 当日收盘价 / 上一年度每股税后利润

+
+
+

② 市盈率 = 当前总市值 / 上年度净利润

+
+

理解:

+
    +
  • 公司需要累计多少年的盈利才能达到目前的市价水平。
  • +
  • 值越低说明投资回收期短,风险越小,投资价值越高。
  • +
  • 值越大说明翻本期长,风险大。
  • +
+

缺点:

+
    +
  • 取的是上一年度的净利润,是一个过去的值,有点滞后。
  • +
+

例子:
你花了240w买了一套二手房,打算进行出租赚点外快,已知去年平均月租2w,一年收益大概24w。以去年这些数据为参考,你预计十年后才能赚回成本240w,所以市盈率 = 10。

+

1.2 动态市盈率
为了弥补静态市盈率的滞后性,增加动态市盈率作为参考指标。

+
+

市盈率 = 当前总市值 / X

+
+

根据当前的时间节点不同计算X的值:
X = 当年最近一个季度的净利润 * 4
X = 最近半年净利润 * 2
X = 最近三季度净利润 * 1.5

+

1.3 静态市盈率 vs 动态市盈率

+
    +
  • 静态市盈率反映的是过去的数据,动态市盈率反映的是未来的预估
  • +
  • 动态市盈率 > 静态市盈率,说明最近(一个季度、半年、三个季度)公司的利润下降了。
  • +
+

1.4 TTM-Trailing Twelve Months

+
    +
  • 最近十二个月市盈率,也叫滚动市盈率。
  • +
  • 它也是一个对过去情况的分析说明。
  • +
+

二、每股净值产

+

每股净值产 = (总资产 - 总负债) / 总股数

+
+
+ +
+ + +

三、市净率

3.1 PB-市净率

+
+

市净率 = 每股市价 / 每股净值产
每股净资产 = 股东权益 / 总股本

+
+

市净率越低那么它的投资价值就越高,这也就意味着它的风险越低。

+]]>
+ + 经济学 + + + Economics + +
对称/非对称加密和数字签名 /basic-encryption-algorithm.html @@ -1107,6 +1244,36 @@ 计算机基础 + + 数据结构之布隆过滤器 + /cs-data-structure-bloomfilter.html + +

概念

一种空间高效的概率型数据结构,用于判断一个元素是否存在于集合中。

+

空间高效:用几个比特位来标识存在与否,不占用太多内存空间。
概率型:有几率把一个不存在的元素判定为存在。

+

Hash表存在的问题:数据量很大时,占用内存太多了。

+

基本操作

插入操作:

初始bit数组A[m-1]全部置0,通过映射函数,将要插入的值随机映射到数组范围内,将该位置为1

+
+ +
+ + +
查找操作:

将要查找的元素通过映射函数,映射到数组中,判断该bit位是否为1

+
+ +
+ + + +

应用

    +
  • 网页爬虫对 URL 去重,避免爬取相同的 URL 地址;
  • +
  • 反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱;
  • +
+

参考资料

图片来源
1

+]]>
+ + 计算机 + +
CPU流水线工作原理 /cpu-pipline-overview.html @@ -1171,36 +1338,6 @@ CPU - - 数据结构之布隆过滤器 - /cs-data-structure-bloomfilter.html - -

概念

一种空间高效的概率型数据结构,用于判断一个元素是否存在于集合中。

-

空间高效:用几个比特位来标识存在与否,不占用太多内存空间。
概率型:有几率把一个不存在的元素判定为存在。

-

Hash表存在的问题:数据量很大时,占用内存太多了。

-

基本操作

插入操作:

初始bit数组A[m-1]全部置0,通过映射函数,将要插入的值随机映射到数组范围内,将该位置为1

-
- -
- - -
查找操作:

将要查找的元素通过映射函数,映射到数组中,判断该bit位是否为1

-
- -
- - - -

应用

    -
  • 网页爬虫对 URL 去重,避免爬取相同的 URL 地址;
  • -
  • 反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱;
  • -
-

参考资料

图片来源
1

-]]>
- - 计算机 - -
操作系统之文件系统 /cs-operating-systems-file-system.html @@ -1431,97 +1568,6 @@ 软件哲学 - - 估值指标 - /base-economic-concept.html - - - -英文名称 -中文名称 -计算方式 -理解 - - - -PE = Price-to-Earning Ratio -市盈率 -每股股价/每股盈余 = 市值/净利润 -创造财富的能力、回收成本的时间 - - -PS = Price-to-Sales Ratio -市销率 -每股股价/每股营收 = 市值/营收 -获得公司1元的销售收入需要投入多少钱 - - -PCF =Price-to-Cash-Flow Ratio -市现率 -每股股价/每股现金流 = 市值/12月现金流 - - - -PB = Price-to-Book Ratio -市净率 -每股股价/每股净资产 = 市值/净资产 -净资产的溢价程度 - - -

一、市盈率

1.1 PE - 静态市盈率

-
-

① 市盈率 = 当日收盘价 / 上一年度每股税后利润

-
-
-

② 市盈率 = 当前总市值 / 上年度净利润

-
-

理解:

-
    -
  • 公司需要累计多少年的盈利才能达到目前的市价水平。
  • -
  • 值越低说明投资回收期短,风险越小,投资价值越高。
  • -
  • 值越大说明翻本期长,风险大。
  • -
-

缺点:

-
    -
  • 取的是上一年度的净利润,是一个过去的值,有点滞后。
  • -
-

例子:
你花了240w买了一套二手房,打算进行出租赚点外快,已知去年平均月租2w,一年收益大概24w。以去年这些数据为参考,你预计十年后才能赚回成本240w,所以市盈率 = 10。

-

1.2 动态市盈率
为了弥补静态市盈率的滞后性,增加动态市盈率作为参考指标。

-
-

市盈率 = 当前总市值 / X

-
-

根据当前的时间节点不同计算X的值:
X = 当年最近一个季度的净利润 * 4
X = 最近半年净利润 * 2
X = 最近三季度净利润 * 1.5

-

1.3 静态市盈率 vs 动态市盈率

-
    -
  • 静态市盈率反映的是过去的数据,动态市盈率反映的是未来的预估
  • -
  • 动态市盈率 > 静态市盈率,说明最近(一个季度、半年、三个季度)公司的利润下降了。
  • -
-

1.4 TTM-Trailing Twelve Months

-
    -
  • 最近十二个月市盈率,也叫滚动市盈率。
  • -
  • 它也是一个对过去情况的分析说明。
  • -
-

二、每股净值产

-

每股净值产 = (总资产 - 总负债) / 总股数

-
-
- -
- - -

三、市净率

3.1 PB-市净率

-
-

市净率 = 每股市价 / 每股净值产
每股净资产 = 股东权益 / 总股本

-
-

市净率越低那么它的投资价值就越高,这也就意味着它的风险越低。

-]]>
- - 经济学 - - - Economics - -
Class文件的存储格式 /file-format-class.html @@ -2294,6 +2340,41 @@

参考:

Deep recursion with coroutines

+]]> + + 计算机 + + + Kotlin + +
+ + Kotlin Flow的工作原理 + /kotlin-lang-flow-under-the-hood.html + +

我们有一个会被重复调用的lambda表达式:

+
import kotlin.*

fun main() {
val f: () -> Unit = {
print("A")
print("B")
print("C")
}
f() // ABC
f() // ABC
}
+ +

我们给这个lambda加个参数:(String) -> Unit ,因为参数是个函数,为了能调用到函数,我们把它叫做emit吧:

+
import kotlin.*

fun main() {
val f: ((String) -> Unit) -> Unit = { emit -> // 1
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
+ +

添加的参数看起来有点乱🤔,稍微修改一下,抽出来吧:

+
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: (FlowCollector) -> Unit = {
it.emit("A")
it.emit("B")
it.emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
+ +

好像能把it的调用逻辑去掉,这样更简洁:

+
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
+ +

调用lambda表达式不是很方便。如果把它抽成接口🤔

+
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun main() {
val builder: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
val flow: Flow = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}
flow.collect { print(it) } // ABC
flow.collect { print(it) } // ABC
}
+ +

抽成可以重复调用的构建器:

+
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun flow(builder: FlowCollector.() -> Unit) = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}

fun main() {
val f: Flow = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
+ +

泛型化参数更通用:

+
import kotlin.*

fun interface FlowCollector<T> {
suspend fun emit(value: T)
}

interface Flow<T> {
suspend fun collect(collector: FlowCollector<T>)
}

fun <T> flow(builder: suspend FlowCollector<T>.() -> Unit) = object : Flow<T> {
override suspend fun collect(collector: FlowCollector<T>) {
collector.builder()
}
}

suspend fun main() {
val f: Flow<String> = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
+ + +

参考

]]>
计算机 @@ -2359,167 +2440,17 @@

使用zip操作符

val nums = (1..3).asFlow() // numbers 1..3
val strs = flowOf("one", "two", "three") // strings
nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string
.collect { println(it) } // collect and print
//output:
//1 -> one
//2 -> two
//3 -> three
-

当两个flow不同步时:

-
//速度不同步时,使用zip,到达同步点才输出
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string with "zip"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 428 ms from start
//2 -> two at 828 ms from start
//3 -> three at 1230 ms from start
-
////速度不同步时,使用combine,有值到达即输出,无视同步
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 452 ms from start
//2 -> one at 651 ms from start
//2 -> two at 854 ms from start
//3 -> two at 952 ms from start
//3 -> three at 1256 ms from start
- - -

参考文档:
1.官方文档

-]]> - - 计算机 - - - Kotlin - -
- - Kotlin Flow的工作原理 - /kotlin-lang-flow-under-the-hood.html - -

我们有一个会被重复调用的lambda表达式:

-
import kotlin.*

fun main() {
val f: () -> Unit = {
print("A")
print("B")
print("C")
}
f() // ABC
f() // ABC
}
- -

我们给这个lambda加个参数:(String) -> Unit ,因为参数是个函数,为了能调用到函数,我们把它叫做emit吧:

-
import kotlin.*

fun main() {
val f: ((String) -> Unit) -> Unit = { emit -> // 1
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
- -

添加的参数看起来有点乱🤔,稍微修改一下,抽出来吧:

-
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: (FlowCollector) -> Unit = {
it.emit("A")
it.emit("B")
it.emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
- -

好像能把it的调用逻辑去掉,这样更简洁:

-
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

fun main() {
val f: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
f { print(it) } // ABC
f { print(it) } // ABC
}
- -

调用lambda表达式不是很方便。如果把它抽成接口🤔

-
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun main() {
val builder: FlowCollector.() -> Unit = {
emit("A")
emit("B")
emit("C")
}
val flow: Flow = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}
flow.collect { print(it) } // ABC
flow.collect { print(it) } // ABC
}
- -

抽成可以重复调用的构建器:

-
import kotlin.*

fun interface FlowCollector {
fun emit(value: String)
}

interface Flow {
fun collect(collector: FlowCollector)
}

fun flow(builder: FlowCollector.() -> Unit) = object : Flow {
override fun collect(collector: FlowCollector) {
collector.builder()
}
}

fun main() {
val f: Flow = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
- -

泛型化参数更通用:

-
import kotlin.*

fun interface FlowCollector<T> {
suspend fun emit(value: T)
}

interface Flow<T> {
suspend fun collect(collector: FlowCollector<T>)
}

fun <T> flow(builder: suspend FlowCollector<T>.() -> Unit) = object : Flow<T> {
override suspend fun collect(collector: FlowCollector<T>) {
collector.builder()
}
}

suspend fun main() {
val f: Flow<String> = flow {
emit("A")
emit("B")
emit("C")
}
f.collect { print(it) } // ABC
f.collect { print(it) } // ABC
}
- - -

参考

-]]>
- - 计算机 - - - Kotlin - -
- - Kotlin中的JVM注解 - /kotlin-lang-jvm-annotation.html - Kotlin提供了一些注解可以帮助开发者更好地兼容Java。下面探索一下Kotlin中JVM注解的使用,以及在Java中使用Kotlin类时注解对我们的影响。

-

1、@JvmName

用于文件、函数、属性、getter和setter。

-
1.1 给文件添加@JvmName注解

默认情况下,一个Kotlin文件中的functionproperties会被编译成filenameKt.class,其中的class会被编译成classname.class:

- - - - - -
- -
1.2 给函数名添加@JvmName注解
- -
- -
1.3 给getter和setting添加@JvmName

@get:JvmName("getContent")
@set:JvmName("setContent")
var text = ""

- -

2、@JvmDefault

和Java8一样,Kotlin的接口也支持默认方法实现。即使针对Java7及以下版本,他也能正常编译,因为Kotlin使用静态内部类实现默认方法。

-
- -
- -

当在Java中实现此接口时,需要复写对应的方法,否则将报错。

-
- -
- -

如果我们希望它在Java8中不报错,可以使用@JvmDefault注解标识方法:

-
interface Document {
@JvmDefault
fun getType() = "document"
}
- -

3、@JvmStatic

针对object classcompanion object使用此注解,可以避免Java访问时的INSTANCE调用

- - - - - -
- -

4、@JvmOverloads

Kotlin的默认参数可以帮助我们减少函数重载,简化方法调用参数。在Java中调用含默认参数的Kotlin函数时,需要提供全部参数。

- - - - - -
- -

5、@Throws

Kotlin没有受检测异常,try-catch是非必须的。如果希望在Java调用中检测到异常,可以使用@Throws注解

-
- -
- -

6、@JvmWildcard & @JvmSuppressWildcard

-

7、@JvmMultifileClass

当在多个文件中定义的顶层函数或属性想要合并到一个编译的class中时,可以使用此注解。

-
- -
- - -

8、@JvmPackageName

和@JvmName一样,此注解可以修改包名,但是他被标记为internal,只能在kotlin库内部使用,这里不做过多介绍。

-

9、注解一览

- -
- -

[参考]

1.Guide to JVM Platform Annotations in Kotlin

-]]>
- - 计算机 - - - Kotlin - -
- - Kotlin之JvmStatic和override冲突问题 - /kotlin-lang-jvmstatic-with-interface.html - 一、问题

为了方便Java代码调用Kotlin的object类,我们通常会对object类的方法添加@JvmStatic注解。

- - - - - -
- -

然而、当object类实现某个接口时,对应的方法却不能添加@JvmStatic注解。

-
- -
- - -

二、解决

要想解决上述问题,只需要将object类的实现做一些转换:
-
-

interface Play2 {
fun play()
}

class Singleton2 {

private companion object : Play2 {
@JvmStatic
override fun play() {
}
}
}
- -

三、思考

-

为什么第一种方式会报错,而第二种方式没问题呢?

-
-

通过反编译查看Java代码我们发现:object类的方法会被直接编译成Java的static方法

-
public final class Singleton implements Play {
public static final Singleton INSTANCE;

@JvmStatic
public static void play() {
}

private Singleton() {
}

static {
Singleton var0 = new Singleton();
INSTANCE = var0;
}
}
+

当两个flow不同步时:

+
//速度不同步时,使用zip,到达同步点才输出
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string with "zip"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 428 ms from start
//2 -> two at 828 ms from start
//3 -> three at 1230 ms from start
+
////速度不同步时,使用combine,有值到达即输出,无视同步
val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms
val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms
val startTime = System.currentTimeMillis() // remember the start time
nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine"
.collect { value -> // collect and print
println("$value at ${System.currentTimeMillis() - startTime} ms from start")
}
//output:
//1 -> one at 452 ms from start
//2 -> one at 651 ms from start
//2 -> two at 854 ms from start
//3 -> two at 952 ms from start
//3 -> three at 1256 ms from start
-

而companion object则会被编译成静态内部类

-
public final class Singleton2 {
/** @deprecated */
@Deprecated
public static final Singleton2.Companion Companion = new Singleton2.Companion((DefaultConstructorMarker)null);

@JvmStatic
public static void play() {
Companion.play();
}

private static final class Companion implements Play2 {
@JvmStatic
public void play() {
}

private Companion() {
}

// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}

-

由于static方法是不能重写(override)的,所以同一个关键字不能作用于一个函数。而通过静态内部类的方式,在类的层次增加静态能力,从而消除了方法的static关键字。

-

参考

issue-KT-21342

+

参考文档:
1.官方文档

]]> 计算机 - Java Kotlin @@ -2668,6 +2599,121 @@ Kotlin + + Kotlin中的JVM注解 + /kotlin-lang-jvm-annotation.html + Kotlin提供了一些注解可以帮助开发者更好地兼容Java。下面探索一下Kotlin中JVM注解的使用,以及在Java中使用Kotlin类时注解对我们的影响。

+

1、@JvmName

用于文件、函数、属性、getter和setter。

+
1.1 给文件添加@JvmName注解

默认情况下,一个Kotlin文件中的functionproperties会被编译成filenameKt.class,其中的class会被编译成classname.class:

+ + + + + +
+ +
1.2 给函数名添加@JvmName注解
+ +
+ +
1.3 给getter和setting添加@JvmName

@get:JvmName("getContent")
@set:JvmName("setContent")
var text = ""

+ +

2、@JvmDefault

和Java8一样,Kotlin的接口也支持默认方法实现。即使针对Java7及以下版本,他也能正常编译,因为Kotlin使用静态内部类实现默认方法。

+
+ +
+ +

当在Java中实现此接口时,需要复写对应的方法,否则将报错。

+
+ +
+ +

如果我们希望它在Java8中不报错,可以使用@JvmDefault注解标识方法:

+
interface Document {
@JvmDefault
fun getType() = "document"
}
+ +

3、@JvmStatic

针对object classcompanion object使用此注解,可以避免Java访问时的INSTANCE调用

+ + + + + +
+ +

4、@JvmOverloads

Kotlin的默认参数可以帮助我们减少函数重载,简化方法调用参数。在Java中调用含默认参数的Kotlin函数时,需要提供全部参数。

+ + + + + +
+ +

5、@Throws

Kotlin没有受检测异常,try-catch是非必须的。如果希望在Java调用中检测到异常,可以使用@Throws注解

+
+ +
+ +

6、@JvmWildcard & @JvmSuppressWildcard

+

7、@JvmMultifileClass

当在多个文件中定义的顶层函数或属性想要合并到一个编译的class中时,可以使用此注解。

+
+ +
+ + +

8、@JvmPackageName

和@JvmName一样,此注解可以修改包名,但是他被标记为internal,只能在kotlin库内部使用,这里不做过多介绍。

+

9、注解一览

+ +
+ +

[参考]

1.Guide to JVM Platform Annotations in Kotlin

+]]>
+ + 计算机 + + + Kotlin + +
+ + Kotlin之JvmStatic和override冲突问题 + /kotlin-lang-jvmstatic-with-interface.html + 一、问题

为了方便Java代码调用Kotlin的object类,我们通常会对object类的方法添加@JvmStatic注解。

+ + + + + +
+ +

然而、当object类实现某个接口时,对应的方法却不能添加@JvmStatic注解。

+
+ +
+ + +

二、解决

要想解决上述问题,只需要将object类的实现做一些转换:
+
+

interface Play2 {
fun play()
}

class Singleton2 {

private companion object : Play2 {
@JvmStatic
override fun play() {
}
}
}
+ +

三、思考

+

为什么第一种方式会报错,而第二种方式没问题呢?

+
+

通过反编译查看Java代码我们发现:object类的方法会被直接编译成Java的static方法

+
public final class Singleton implements Play {
public static final Singleton INSTANCE;

@JvmStatic
public static void play() {
}

private Singleton() {
}

static {
Singleton var0 = new Singleton();
INSTANCE = var0;
}
}
+ +

而companion object则会被编译成静态内部类

+
public final class Singleton2 {
/** @deprecated */
@Deprecated
public static final Singleton2.Companion Companion = new Singleton2.Companion((DefaultConstructorMarker)null);

@JvmStatic
public static void play() {
Companion.play();
}

private static final class Companion implements Play2 {
@JvmStatic
public void play() {
}

private Companion() {
}

// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}

+ +

由于static方法是不能重写(override)的,所以同一个关键字不能作用于一个函数。而通过静态内部类的方式,在类的层次增加静态能力,从而消除了方法的static关键字。

+

参考

issue-KT-21342

+]]> + + 计算机 + + + Java + Kotlin + + Effective Kotlin-51:使用Sequence优化集合操作 /kotlin-lang-sequence.html @@ -3006,60 +3052,6 @@ 链表 - - LeetCode 反转单链表 - /leetcode-reverse-list.html - LeetCode-206 反转单链表

-

给你单链表的头结点 head,请你反转链表,并返回反转后的链表。

-
-

问题分析:

-

这是初始状态的链表

-
- -
-由于反转链表后 **head** 结点将指向空(null),我们可以假设存在这么一个为空的结点prev。 - -

尝试一次反转后,我们发现,后续结点信息丢失了!我们不得不声明一个新的变量保存原链表的信息。

-
- -
- -

所以,我们一共需要三个指针来记录转换过程

- -

分析到这里,我们再回到初始状态 :

-
- -
- -

接下来我们进行第一次反转,head.next 指向虚拟的空结点,且后续链表信息没有丢失。

-
- -
- -

三个指针一起往后移动一个单位。我们发现此时链表又回到了最初的状态。

-
- -
- - -

至此,我们可以尝试写出如下代码:

-
public static ListNode reverseIteratively(ListNode head) {
ListNode pre = null;
ListNode next = null;

while (head != null) {
next = head.next;

//改变指针方向,对第一个节点来说,他的前一个节点是null
head.next = pre;
//向前移动两个指针
pre = head;
head = next;
}
return pre;
}
- - -

思考:
你能使用递归的方式改写上述代码逻辑吗?

-]]> - - 计算机 - - - LeetCode - 算法 - List - - 无等级CSP中的死锁 /model-csp-deadlocks.html @@ -3123,8 +3115,62 @@ 计算机 - Kotlin Concurrency + Kotlin + + + + LeetCode 反转单链表 + /leetcode-reverse-list.html + LeetCode-206 反转单链表
+

给你单链表的头结点 head,请你反转链表,并返回反转后的链表。

+
+

问题分析:

+

这是初始状态的链表

+
+ +
+由于反转链表后 **head** 结点将指向空(null),我们可以假设存在这么一个为空的结点prev。 + +

尝试一次反转后,我们发现,后续结点信息丢失了!我们不得不声明一个新的变量保存原链表的信息。

+
+ +
+ +

所以,我们一共需要三个指针来记录转换过程

+ +

分析到这里,我们再回到初始状态 :

+
+ +
+ +

接下来我们进行第一次反转,head.next 指向虚拟的空结点,且后续链表信息没有丢失。

+
+ +
+ +

三个指针一起往后移动一个单位。我们发现此时链表又回到了最初的状态。

+
+ +
+ + +

至此,我们可以尝试写出如下代码:

+
public static ListNode reverseIteratively(ListNode head) {
ListNode pre = null;
ListNode next = null;

while (head != null) {
next = head.next;

//改变指针方向,对第一个节点来说,他的前一个节点是null
head.next = pre;
//向前移动两个指针
pre = head;
head = next;
}
return pre;
}
+ + +

思考:
你能使用递归的方式改写上述代码逻辑吗?

+]]>
+ + 计算机 + + + LeetCode + 算法 + List
@@ -3974,4 +4020,54 @@ Reading + + 做事必须搞清的十六个顺序 + /%E5%81%9A%E4%BA%8B%E5%BF%85%E9%A1%BB%E6%90%9E%E6%B8%85%E7%9A%84%E5%8D%81%E5%85%AD%E4%B8%AA%E9%A1%BA%E5%BA%8F.html + +

以下内容在一篇公众号里面看到的,觉得很有道理,记录在此,常思之。

+ +

01 沟通:先求同,再求异
明确共同目标,塑造价值认同。保持开放心态,积极倾听对方。

+
+

自评:

+
+

02 共情:先理解,再表达
准确辨识情绪,正确解读语义。听对方想说的,说对方想听的。

+
+

自评:

+
+

03 人际:先交流,再交心
选择交流对象,探索交流领域。尝试交流情感,保持稳定交往。

+
+

自评:

+
+

04 情商:先心情,再事情
安抚对方情绪,恢复正常对话。寻找共同利益,解决冲突矛盾。

+
+

自评:

+
+

05 职场:先升值,再升职
认清商业本质,正视价值交换。接受共性塑造,获得职务晋升。

+
+

自评:

+
+

06 工作:先计划,再行动
设定清晰目标,分析评估现状。制订详细计划,设定执行步骤。

+
+

自评:计划就是把大目标拆成更容易实现的小目标,给自己设定期限,坚定的完成小目标。有了目标,才不会放松自己,浑浑噩噩。

+
+

07 执行:先完成,再完美
舍弃完美主义,坚持效率优先。总结经验教训,快速优化迭代。

+
+

自评:早期写代码时追求完美,总想着要设计好代码。花过多的时间在代码设计上。后面还是想明白了,先把事情做完是最基本的要求,做完后有时间再去优化代码细节。因为思考是逐渐深入的,只有完成了,在完成过程中的思考,才能为后面的更好做好理论铺垫。

+
+

08 学习:先记录,再记忆
准备记录工具,捕捉关键信息。定期整理回顾,转为长期记忆。

+
+

自评:知识要结构化才能变成脑子里的思路,结构化就是对一方面知识进行概括,由多到少,由繁到简,由细节到抽象。记录和整理就是对知识进行结构化。尤其是现在快节奏的生活,大家没时间体系性的看书,都是碎片化的知识,看时很爽,很快忘记,不妨把小知识点记录成系统,归纳到自己的知识体系里面。

+
+

09 能力:先专注,再专业
正确选择方向,排除外界干扰。深度学习知识,持续精进技能。
10 事业:先成长,再成功
磨砺心灵意志,坚持求知探索。明确价值取向,积小胜为大胜。
11 发展:先站住,再站高
明确发展定位,夯实事业基础。进行长远规划,开展品牌建设。

+

12 创新:先仿造,再创造
寻找模仿对象,仔细观察学习。研究原理结构,思考优化改进。

+

13 流程:先僵化,再优化
设计业务流程,坚持落地执行。消除流程阻力,提升流程效率。

+

14 制度:先细化,再简化
杜绝制度弹性,堵住制度漏洞。提炼制度要点,进行制度宣贯。

+

15 管理:先自己,再别人
约束自身言行,做好团队表率。明确团队规则,落实奖惩措施。

+

16 影响:先管理,再领导
建立团队秩序,做好利益平衡。激发团队动能,引领创新变革。

+

总之,做事,顺序不能错,逻辑不能反!

+]]>
+ + 道理 + +
diff --git a/sitemap.xml b/sitemap.xml index d18b1664..3089a65f 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1,6 +1,20 @@ + + https://wangduwei.top/android-github-source-measure.html + + 2024-10-22 + + + + + https://wangduwei.top/%E5%81%9A%E4%BA%8B%E5%BF%85%E9%A1%BB%E6%90%9E%E6%B8%85%E7%9A%84%E5%8D%81%E5%85%AD%E4%B8%AA%E9%A1%BA%E5%BA%8F.html + + 2024-10-21 + + + https://wangduwei.top/%E3%80%8A%E9%AB%98%E7%BA%AC%E5%BA%A6%E6%80%9D%E8%80%83%E6%B3%95%E3%80%8B.html @@ -359,14 +373,14 @@ - https://wangduwei.top/android-github-source-workmanager.html + https://wangduwei.top/android-github-source-spacex.html 2024-04-29 - https://wangduwei.top/android-github-source-spacex.html + https://wangduwei.top/android-github-source-workmanager.html 2024-04-29 @@ -375,7 +389,7 @@ https://wangduwei.top/ - 2024-09-22 + 2024-10-22 daily 1.0 @@ -383,189 +397,196 @@ https://wangduwei.top/tags/Android/ - 2024-09-22 + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/ - 2024-09-22 + https://wangduwei.top/tags/View/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/CPU/ - 2024-09-22 + https://wangduwei.top/tags/%E5%AE%89%E5%8D%93%E6%A1%86%E6%9E%B6/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/Flutter/ - 2024-09-22 + https://wangduwei.top/tags/%E6%9E%B6%E6%9E%84/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/Java/ - 2024-09-22 + https://wangduwei.top/tags/Compose/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/Kotlin/ - 2024-09-22 + https://wangduwei.top/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/View/ - 2024-09-22 + https://wangduwei.top/tags/Economics/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/%E5%AE%89%E5%8D%93%E6%A1%86%E6%9E%B6/ - 2024-09-22 + https://wangduwei.top/tags/cryptography/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/%E6%9E%B6%E6%9E%84/ - 2024-09-22 + https://wangduwei.top/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/Compose/ - 2024-09-22 + https://wangduwei.top/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/ - 2024-09-22 + https://wangduwei.top/tags/CPU/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/cryptography/ - 2024-09-22 + https://wangduwei.top/tags/Linux/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA/ - 2024-09-22 + https://wangduwei.top/tags/%E7%BB%8F%E6%B5%8E%E5%AD%A6/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/Linux/ - 2024-09-22 + https://wangduwei.top/tags/%E8%BD%AF%E4%BB%B6%E5%93%B2%E5%AD%A6/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/%E7%BB%8F%E6%B5%8E%E5%AD%A6/ - 2024-09-22 + https://wangduwei.top/tags/Java/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/%E8%BD%AF%E4%BB%B6%E5%93%B2%E5%AD%A6/ - 2024-09-22 + https://wangduwei.top/tags/File/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/Economics/ - 2024-09-22 + https://wangduwei.top/tags/C-C/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/File/ - 2024-09-22 + https://wangduwei.top/tags/Flutter/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/C-C/ - 2024-09-22 + https://wangduwei.top/tags/Concurrency/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/Concurrency/ - 2024-09-22 + https://wangduwei.top/tags/JVM/ + 2024-10-22 daily 0.6 - https://wangduwei.top/tags/JVM/ - 2024-09-22 + https://wangduwei.top/tags/Kotlin/ + 2024-10-22 daily 0.6 https://wangduwei.top/tags/LeetCode/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/tags/%E7%AE%97%E6%B3%95/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/tags/%E9%93%BE%E8%A1%A8/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/tags/List/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/tags/%E5%B7%A5%E4%BD%9C/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/tags/Reading/ - 2024-09-22 + 2024-10-22 + daily + 0.6 + + + + https://wangduwei.top/tags/%E9%81%93%E7%90%86/ + 2024-10-22 daily 0.6 @@ -574,28 +595,28 @@ https://wangduwei.top/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/categories/%E7%BB%8F%E6%B5%8E%E5%AD%A6/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/categories/%E5%B7%A5%E4%BD%9C/ - 2024-09-22 + 2024-10-22 daily 0.6 https://wangduwei.top/categories/Reading/ - 2024-09-22 + 2024-10-22 daily 0.6 diff --git a/tags/Android/index.html b/tags/Android/index.html index 6a275a05..1cce5b91 100644 --- a/tags/Android/index.html +++ b/tags/Android/index.html @@ -195,6 +195,29 @@

Android +
+ 2024 +
+ +
2022
@@ -382,26 +405,6 @@

Android - - @@ -409,6 +412,9 @@

Android + @@ -477,7 +483,7 @@

Android @@ -514,13 +520,13 @@

Android - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Android/page/2/index.html b/tags/Android/page/2/index.html new file mode 100644 index 00000000..9eb3df44 --- /dev/null +++ b/tags/Android/page/2/index.html @@ -0,0 +1,448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 标签: Android | 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

蓝色的笔记本

+ +
+

记录学习内容

+
+ + +
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+
+
+

Android + 标签 +

+
+ + +
+ 2021 +
+ + + +
+
+ + + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tags/C-C/index.html b/tags/C-C/index.html index 8d85640c..11e561be 100644 --- a/tags/C-C/index.html +++ b/tags/C-C/index.html @@ -294,7 +294,7 @@

C/C++ @@ -331,13 +331,13 @@

C/C++ - 131k + 133k - 1:59 + 2:01 diff --git a/tags/CPU/index.html b/tags/CPU/index.html index 6bae42a8..b1069bda 100644 --- a/tags/CPU/index.html +++ b/tags/CPU/index.html @@ -294,7 +294,7 @@

CPU @@ -331,13 +331,13 @@

CPU - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Compose/index.html b/tags/Compose/index.html index 5c0d3a5f..5faaafd5 100644 --- a/tags/Compose/index.html +++ b/tags/Compose/index.html @@ -294,7 +294,7 @@

Compose @@ -331,13 +331,13 @@

Compose - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Concurrency/index.html b/tags/Concurrency/index.html index 328920e9..492293ac 100644 --- a/tags/Concurrency/index.html +++ b/tags/Concurrency/index.html @@ -314,7 +314,7 @@

Concurrency @@ -351,13 +351,13 @@

Concurrency - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Economics/index.html b/tags/Economics/index.html index 1b20ddf3..0168e52a 100644 --- a/tags/Economics/index.html +++ b/tags/Economics/index.html @@ -294,7 +294,7 @@

Economics @@ -331,13 +331,13 @@

Economics - 131k + 133k - 1:59 + 2:01 diff --git a/tags/File/index.html b/tags/File/index.html index 68cc63be..577675b9 100644 --- a/tags/File/index.html +++ b/tags/File/index.html @@ -314,7 +314,7 @@

File @@ -351,13 +351,13 @@

File - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Flutter/index.html b/tags/Flutter/index.html index f420e472..0de6592d 100644 --- a/tags/Flutter/index.html +++ b/tags/Flutter/index.html @@ -334,7 +334,7 @@

Flutter @@ -371,13 +371,13 @@

Flutter - 131k + 133k - 1:59 + 2:01 diff --git a/tags/JVM/index.html b/tags/JVM/index.html index a9ba9160..d3a7ab50 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -294,7 +294,7 @@

JVM @@ -331,13 +331,13 @@

JVM - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Java/index.html b/tags/Java/index.html index d80580fe..1a9318f8 100644 --- a/tags/Java/index.html +++ b/tags/Java/index.html @@ -357,7 +357,7 @@

Java @@ -394,13 +394,13 @@

Java - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Kotlin/index.html b/tags/Kotlin/index.html index aa1464f0..5ac5ebfb 100644 --- a/tags/Kotlin/index.html +++ b/tags/Kotlin/index.html @@ -477,7 +477,7 @@

Kotlin @@ -514,13 +514,13 @@

Kotlin - 131k + 133k - 1:59 + 2:01 diff --git a/tags/LeetCode/index.html b/tags/LeetCode/index.html index 4bd719c8..2fdef54d 100644 --- a/tags/LeetCode/index.html +++ b/tags/LeetCode/index.html @@ -314,7 +314,7 @@

LeetCode @@ -351,13 +351,13 @@

LeetCode - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Linux/index.html b/tags/Linux/index.html index 27dadf2a..63fd364d 100644 --- a/tags/Linux/index.html +++ b/tags/Linux/index.html @@ -294,7 +294,7 @@

Linux @@ -331,13 +331,13 @@

Linux - 131k + 133k - 1:59 + 2:01 diff --git a/tags/List/index.html b/tags/List/index.html index 35b12aee..90debaa4 100644 --- a/tags/List/index.html +++ b/tags/List/index.html @@ -294,7 +294,7 @@

List @@ -331,13 +331,13 @@

List - 131k + 133k - 1:59 + 2:01 diff --git a/tags/Reading/index.html b/tags/Reading/index.html index 7f9dea08..aa68b222 100644 --- a/tags/Reading/index.html +++ b/tags/Reading/index.html @@ -360,7 +360,7 @@

Reading @@ -397,13 +397,13 @@

Reading - 131k + 133k - 1:59 + 2:01 diff --git a/tags/View/index.html b/tags/View/index.html index 2fc5f786..c705c7bb 100644 --- a/tags/View/index.html +++ b/tags/View/index.html @@ -294,7 +294,7 @@

View @@ -331,13 +331,13 @@

View - 131k + 133k - 1:59 + 2:01 diff --git a/tags/cryptography/index.html b/tags/cryptography/index.html index 8c4f7d91..d9d4d199 100644 --- a/tags/cryptography/index.html +++ b/tags/cryptography/index.html @@ -294,7 +294,7 @@

cryptography @@ -331,13 +331,13 @@

cryptography - 131k + 133k - 1:59 + 2:01 diff --git a/tags/index.html b/tags/index.html index 4a912652..98f56580 100644 --- a/tags/index.html +++ b/tags/index.html @@ -210,10 +210,10 @@

标签
@@ -294,7 +294,7 @@

标签

@@ -331,13 +331,13 @@

标签 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\345\256\211\345\215\223\346\241\206\346\236\266/index.html" "b/tags/\345\256\211\345\215\223\346\241\206\346\236\266/index.html" index 73a1b502..bb4f64cc 100644 --- "a/tags/\345\256\211\345\215\223\346\241\206\346\236\266/index.html" +++ "b/tags/\345\256\211\345\215\223\346\241\206\346\236\266/index.html" @@ -195,6 +195,29 @@

安卓框架 +
+ 2024 +
+ +
2021
@@ -294,7 +317,7 @@

安卓框架 @@ -331,13 +354,13 @@

安卓框架 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\345\267\245\344\275\234/index.html" "b/tags/\345\267\245\344\275\234/index.html" index 36407b16..7286a31d 100644 --- "a/tags/\345\267\245\344\275\234/index.html" +++ "b/tags/\345\267\245\344\275\234/index.html" @@ -294,7 +294,7 @@

工作 @@ -331,13 +331,13 @@

工作 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\346\225\260\346\215\256\345\272\223/index.html" "b/tags/\346\225\260\346\215\256\345\272\223/index.html" index 63659525..dd9dfcf2 100644 --- "a/tags/\346\225\260\346\215\256\345\272\223/index.html" +++ "b/tags/\346\225\260\346\215\256\345\272\223/index.html" @@ -294,7 +294,7 @@

数据库 @@ -331,13 +331,13 @@

数据库 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\346\236\266\346\236\204/index.html" "b/tags/\346\236\266\346\236\204/index.html" index 1adcf775..56c963cc 100644 --- "a/tags/\346\236\266\346\236\204/index.html" +++ "b/tags/\346\236\266\346\236\204/index.html" @@ -294,7 +294,7 @@

架构 @@ -331,13 +331,13 @@

架构 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\347\256\227\346\263\225/index.html" "b/tags/\347\256\227\346\263\225/index.html" index aad383ae..e9aad182 100644 --- "a/tags/\347\256\227\346\263\225/index.html" +++ "b/tags/\347\256\227\346\263\225/index.html" @@ -314,7 +314,7 @@

算法 @@ -351,13 +351,13 @@

算法 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\347\273\217\346\265\216\345\255\246/index.html" "b/tags/\347\273\217\346\265\216\345\255\246/index.html" index a28c2450..4151a95a 100644 --- "a/tags/\347\273\217\346\265\216\345\255\246/index.html" +++ "b/tags/\347\273\217\346\265\216\345\255\246/index.html" @@ -317,7 +317,7 @@

经济学 @@ -354,13 +354,13 @@

经济学 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\350\256\241\347\256\227\346\234\272/index.html" "b/tags/\350\256\241\347\256\227\346\234\272/index.html" index 274714a3..8218af76 100644 --- "a/tags/\350\256\241\347\256\227\346\234\272/index.html" +++ "b/tags/\350\256\241\347\256\227\346\234\272/index.html" @@ -294,7 +294,7 @@

计算机 @@ -331,13 +331,13 @@

计算机 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" index eef645d1..ba6eaff5 100644 --- "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" +++ "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" @@ -317,7 +317,7 @@

计算机基础 @@ -354,13 +354,13 @@

计算机基础 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\350\275\257\344\273\266\345\223\262\345\255\246/index.html" "b/tags/\350\275\257\344\273\266\345\223\262\345\255\246/index.html" index 769d6e7e..64151a82 100644 --- "a/tags/\350\275\257\344\273\266\345\223\262\345\255\246/index.html" +++ "b/tags/\350\275\257\344\273\266\345\223\262\345\255\246/index.html" @@ -294,7 +294,7 @@

软件哲学 @@ -331,13 +331,13 @@

软件哲学 - 131k + 133k - 1:59 + 2:01 diff --git "a/tags/\351\201\223\347\220\206/index.html" "b/tags/\351\201\223\347\220\206/index.html" new file mode 100644 index 00000000..bee4a7ce --- /dev/null +++ "b/tags/\351\201\223\347\220\206/index.html" @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 标签: 道理 | 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

蓝色的笔记本

+ +
+

记录学习内容

+
+ + +
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+
+
+

道理 + 标签 +

+
+ + +
+ 2024 +
+ + + +
+
+ + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/tags/\351\223\276\350\241\250/index.html" "b/tags/\351\223\276\350\241\250/index.html" index 41361ba4..c036ccd6 100644 --- "a/tags/\351\223\276\350\241\250/index.html" +++ "b/tags/\351\223\276\350\241\250/index.html" @@ -294,7 +294,7 @@

链表 @@ -331,13 +331,13 @@

链表 - 131k + 133k - 1:59 + 2:01 diff --git "a/\343\200\212\345\274\202\347\261\273-\344\270\215\344\270\200\346\240\267\347\232\204\346\210\220\345\212\237\345\220\257\347\244\272\345\275\225\343\200\213.html" "b/\343\200\212\345\274\202\347\261\273-\344\270\215\344\270\200\346\240\267\347\232\204\346\210\220\345\212\237\345\220\257\347\244\272\345\275\225\343\200\213.html" index 50c567b8..6b855654 100644 --- "a/\343\200\212\345\274\202\347\261\273-\344\270\215\344\270\200\346\240\267\347\232\204\346\210\220\345\212\237\345\220\257\347\244\272\345\275\225\343\200\213.html" +++ "b/\343\200\212\345\274\202\347\261\273-\344\270\215\344\270\200\346\240\267\347\232\204\346\210\220\345\212\237\345\220\257\347\244\272\345\275\225\343\200\213.html" @@ -547,7 +547,7 @@

- 27 + 28 标签 @@ -584,13 +584,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git "a/\343\200\212\346\200\235\350\200\203\357\274\214\345\277\253\344\270\216\346\205\242\343\200\213-\347\254\2547\347\253\240-\345\255\227\346\257\215B\344\270\216\346\225\260\345\255\22713.html" "b/\343\200\212\346\200\235\350\200\203\357\274\214\345\277\253\344\270\216\346\205\242\343\200\213-\347\254\2547\347\253\240-\345\255\227\346\257\215B\344\270\216\346\225\260\345\255\22713.html" index 7142e196..5ef56754 100644 --- "a/\343\200\212\346\200\235\350\200\203\357\274\214\345\277\253\344\270\216\346\205\242\343\200\213-\347\254\2547\347\253\240-\345\255\227\346\257\215B\344\270\216\346\225\260\345\255\22713.html" +++ "b/\343\200\212\346\200\235\350\200\203\357\274\214\345\277\253\344\270\216\346\205\242\343\200\213-\347\254\2547\347\253\240-\345\255\227\346\257\215B\344\270\216\346\225\260\345\255\22713.html" @@ -438,7 +438,7 @@

- 27 + 28 标签 @@ -475,13 +475,13 @@

- 131k + 133k - 1:59 + 2:01 diff --git "a/\343\200\212\346\205\242\346\200\235\350\200\203\343\200\213.html" "b/\343\200\212\346\205\242\346\200\235\350\200\203\343\200\213.html" index 05b358f2..aee946a8 100644 --- "a/\343\200\212\346\205\242\346\200\235\350\200\203\343\200\213.html" +++ "b/\343\200\212\346\205\242\346\200\235\350\200\203\343\200\213.html" @@ -543,7 +543,7 @@

总结 @@ -580,13 +580,13 @@

总结 - 131k + 133k - 1:59 + 2:01 diff --git "a/\343\200\212\350\256\244\347\237\245\345\244\251\346\200\247\343\200\213.html" "b/\343\200\212\350\256\244\347\237\245\345\244\251\346\200\247\343\200\213.html" index fa0aec3a..e8253b42 100644 --- "a/\343\200\212\350\256\244\347\237\245\345\244\251\346\200\247\343\200\213.html" +++ "b/\343\200\212\350\256\244\347\237\245\345\244\251\346\200\247\343\200\213.html" @@ -581,7 +581,7 @@

- 27 + 28 标签 @@ -618,13 +618,13 @@
- 131k + 133k - 1:59 + 2:01 diff --git "a/\343\200\212\351\253\230\347\272\254\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" "b/\343\200\212\351\253\230\347\272\254\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" index ff865e98..8c09894f 100644 --- "a/\343\200\212\351\253\230\347\272\254\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" +++ "b/\343\200\212\351\253\230\347\272\254\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" @@ -404,7 +404,10 @@

总结 数据结构之布隆过滤器 -
+
+
@@ -481,7 +484,7 @@

总结 @@ -518,13 +521,13 @@

总结 - 131k + 133k - 1:59 + 2:01 diff --git "a/\343\200\212\351\272\273\347\234\201\347\220\206\345\267\245\346\267\261\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" "b/\343\200\212\351\272\273\347\234\201\347\220\206\345\267\245\346\267\261\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" index b13dfc7f..4de56fbc 100644 --- "a/\343\200\212\351\272\273\347\234\201\347\220\206\345\267\245\346\267\261\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" +++ "b/\343\200\212\351\272\273\347\234\201\347\220\206\345\267\245\346\267\261\345\272\246\346\200\235\350\200\203\346\263\225\343\200\213.html" @@ -545,7 +545,7 @@

总结 @@ -582,13 +582,13 @@

总结 - 131k + 133k - 1:59 + 2:01 diff --git "a/\345\201\232\344\272\213\345\277\205\351\241\273\346\220\236\346\270\205\347\232\204\345\215\201\345\205\255\344\270\252\351\241\272\345\272\217.html" "b/\345\201\232\344\272\213\345\277\205\351\241\273\346\220\236\346\270\205\347\232\204\345\215\201\345\205\255\344\270\252\351\241\272\345\272\217.html" new file mode 100644 index 00000000..c1050664 --- /dev/null +++ "b/\345\201\232\344\272\213\345\277\205\351\241\273\346\220\236\346\270\205\347\232\204\345\215\201\345\205\255\344\270\252\351\241\272\345\272\217.html" @@ -0,0 +1,587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 做事必须搞清的十六个顺序 | 蓝色的笔记本 + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

蓝色的笔记本

+ +
+

记录学习内容

+
+ + +
+ + + + + + + + +
+ +
+ +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ 做事必须搞清的十六个顺序 +

+ + +
+ + + + +
+ + +
+

以下内容在一篇公众号里面看到的,觉得很有道理,记录在此,常思之。

+
+

01 沟通:先求同,再求异
明确共同目标,塑造价值认同。保持开放心态,积极倾听对方。

+
+

自评:

+
+

02 共情:先理解,再表达
准确辨识情绪,正确解读语义。听对方想说的,说对方想听的。

+
+

自评:

+
+

03 人际:先交流,再交心
选择交流对象,探索交流领域。尝试交流情感,保持稳定交往。

+
+

自评:

+
+

04 情商:先心情,再事情
安抚对方情绪,恢复正常对话。寻找共同利益,解决冲突矛盾。

+
+

自评:

+
+

05 职场:先升值,再升职
认清商业本质,正视价值交换。接受共性塑造,获得职务晋升。

+
+

自评:

+
+

06 工作:先计划,再行动
设定清晰目标,分析评估现状。制订详细计划,设定执行步骤。

+
+

自评:计划就是把大目标拆成更容易实现的小目标,给自己设定期限,坚定的完成小目标。有了目标,才不会放松自己,浑浑噩噩。

+
+

07 执行:先完成,再完美
舍弃完美主义,坚持效率优先。总结经验教训,快速优化迭代。

+
+

自评:早期写代码时追求完美,总想着要设计好代码。花过多的时间在代码设计上。后面还是想明白了,先把事情做完是最基本的要求,做完后有时间再去优化代码细节。因为思考是逐渐深入的,只有完成了,在完成过程中的思考,才能为后面的更好做好理论铺垫。

+
+

08 学习:先记录,再记忆
准备记录工具,捕捉关键信息。定期整理回顾,转为长期记忆。

+
+

自评:知识要结构化才能变成脑子里的思路,结构化就是对一方面知识进行概括,由多到少,由繁到简,由细节到抽象。记录和整理就是对知识进行结构化。尤其是现在快节奏的生活,大家没时间体系性的看书,都是碎片化的知识,看时很爽,很快忘记,不妨把小知识点记录成系统,归纳到自己的知识体系里面。

+
+

09 能力:先专注,再专业
正确选择方向,排除外界干扰。深度学习知识,持续精进技能。
10 事业:先成长,再成功
磨砺心灵意志,坚持求知探索。明确价值取向,积小胜为大胜。
11 发展:先站住,再站高
明确发展定位,夯实事业基础。进行长远规划,开展品牌建设。

+

12 创新:先仿造,再创造
寻找模仿对象,仔细观察学习。研究原理结构,思考优化改进。

+

13 流程:先僵化,再优化
设计业务流程,坚持落地执行。消除流程阻力,提升流程效率。

+

14 制度:先细化,再简化
杜绝制度弹性,堵住制度漏洞。提炼制度要点,进行制度宣贯。

+

15 管理:先自己,再别人
约束自身言行,做好团队表率。明确团队规则,落实奖惩措施。

+

16 影响:先管理,再领导
建立团队秩序,做好利益平衡。激发团队动能,引领创新变革。

+

总之,做事,顺序不能错,逻辑不能反!

+ +
+ + + + +
+
赏你一杯咖啡
+ + +
+ + + +
+ +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +