├── .gitignore ├── LICENSE ├── README.md ├── about-control ├── 关于控制系统-v0.3.pptx └── 指数特征-v0.6.xlsx ├── antlr-practice ├── Material.md └── README.md ├── broken-thoughts ├── 2020.md ├── README.md └── images │ ├── 122038467-3473da00-ce08-11eb-884e-68d4b2a9eff9.png │ ├── 122039611-6e91ab80-ce09-11eb-8ed8-33b84c2a4724.JPG │ ├── 122039863-b1538380-ce09-11eb-9978-0cd3de349267.JPG │ ├── 122043335-d0541480-ce0d-11eb-8fb1-38b561b4de47.png │ ├── 122043467-efeb3d00-ce0d-11eb-853e-8a02879c6e1f.png │ ├── 122043943-80298200-ce0e-11eb-9aad-7734902a29ba.jpg │ ├── 122045887-d3043900-ce10-11eb-9988-556d714e138c.png │ ├── 122046774-e663d400-ce11-11eb-97f7-a261ac338142.png │ ├── 122047539-dac4dd00-ce12-11eb-9415-7dc2ddfb3fd9.jpg │ ├── 122066128-0cdf3a80-ce25-11eb-8896-0cbb9c7dfb2c.png │ ├── 122679418-58c32280-d21d-11eb-9a74-6717fdf5a9cd.JPG │ ├── 122679671-60cf9200-d21e-11eb-8213-aaa78aa8291d.jpg │ ├── 122702626-5f37b580-d282-11eb-9b37-f77332d6b91d.png │ ├── 122702815-c7869700-d282-11eb-9828-7f00ff271789.png │ ├── 122704841-16cec680-d287-11eb-994e-6863eef2e243.png │ ├── 2021-06-29-14-42-38.png │ ├── 2021-06-29-14-46-29.png │ ├── 2021-06-29-15-04-10.png │ ├── 2021-06-29-15-31-26.png │ ├── 2021-06-29-15-31-45.png │ ├── 2021-06-29-15-32-00.png │ ├── 2021-06-29-15-47-17.png │ ├── 2021-06-29-15-48-18.png │ ├── 2021-06-29-15-52-27.png │ ├── 2021-06-29-19-49-25.png │ ├── 2021-06-29-20-12-27.png │ ├── 2021-07-05-15-34-11.png │ ├── 2021-07-07-13-42-45.png │ ├── 2021-07-07-13-43-38.png │ ├── 2021-07-07-21-20-52.png │ ├── 2021-07-16-11-34-34.png │ ├── 2021-07-16-14-59-30.png │ ├── 2021-07-16-15-01-29.png │ ├── 2021-07-16-15-02-18.png │ ├── 2021-07-16-15-03-32.png │ └── IMG_20210406_180932.jpg ├── cache-practice ├── README.md ├── cache-stock.jpg ├── cache.png └── cache1.png ├── compiler-flow-code-review ├── README.md └── images │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ ├── 05.png │ └── 06.png ├── git ├── README.md ├── git-gitlab-usage.pptx ├── git-usage-and-principle-v0.3.1.pptx ├── github-git-cheat-sheet.pdf ├── images │ ├── git.png │ ├── github.jpg │ ├── gitlab.jpg │ └── why-git.png └── study-material.md ├── hitchhikers-guide-to-open-source └── 开源漫游者指南-v0.9.1.pptx ├── how-to-write-a-issue.md ├── images ├── LICENSE.png └── miscellany-icon.png ├── lb-distribution-uniformity-analysis ├── README.md ├── legacy │ ├── gateway_flow_limiter_analysis_base_poisson.ipynb │ └── gateway_flow_limiter_formula_base_poisson.ipynb ├── poisson_intro.ipynb └── prepare-study │ ├── hello_numpy.ipynb │ └── plotting_equations.ipynb ├── lisp-practice ├── README.md ├── lisp-web-app-quick-start.md └── lisp.png ├── machine-learning-knowledge-points └── those-machine-learning-knowledge-points-that-tormented-newbies-v0.1.pptx ├── multi-response-async-request-pattern-analysis-model ├── README.md ├── graphs.graffle └── images │ ├── 1618292665069-9fc78672-1655-43ea-842e-6b210f4c8a73.jpeg │ ├── 1618293290350-ce2483ac-9a28-4995-9024-37f5747519e4.jpeg │ ├── 1618379271816-ae9bdff5-9990-44c3-8983-023ca4841f04.jpeg │ └── 1620446578486-1114da0f-c3c7-4996-bbee-e34345c5bbfe.jpeg ├── practice-of-software-reliability-design ├── 服务框架的可靠性设计与实践-2017-08-12.pptx └── 软件可靠性设计的实践-v0.9.2.pptx ├── product-logic-for-platform-product ├── README.md ├── product-arch.png └── zxl.png ├── rpc-intro └── rpc-intro-v0.3.pptx ├── software-engeering.pptx ├── system-load-calculation-and-looks ├── README.md ├── load.py ├── system-load-icon.png └── what-system-load-look-like.ipynb └── what-is-my-wanted-blog-system └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | 3 | 4 | ################################################# 5 | # IDE/Editor 6 | ################################################# 7 | 8 | 9 | ### Vim template 10 | [._]*.s[a-w][a-z] 11 | [._]s[a-w][a-z] 12 | *.un~ 13 | Session.vim 14 | .netrwhist 15 | *~ 16 | 17 | 18 | ### vs code 19 | .vscode/ 20 | 21 | 22 | ### SublimeText template 23 | # cache files for sublime text 24 | *.tmlanguage.cache 25 | *.tmPreferences.cache 26 | *.stTheme.cache 27 | 28 | # workspace files are user-specific 29 | *.sublime-workspace 30 | 31 | # project files should be checked into the repository, unless a significant 32 | # proportion of contributors will probably not be using SublimeText 33 | # *.sublime-project 34 | 35 | # sftp configuration file 36 | sftp-config.json 37 | 38 | 39 | ################################################# 40 | # OS 41 | ################################################# 42 | 43 | ### OSX template 44 | .DS_Store 45 | .AppleDouble 46 | .LSOverride 47 | 48 | # Icon must end with two \r 49 | Icon 50 | 51 | 52 | ### Linux template 53 | # KDE directory preferences 54 | .directory 55 | 56 | # Linux trash folder which might appear on any partition or disk 57 | .Trash-* 58 | 59 | 60 | ### Windows template 61 | # Windows image file caches 62 | Thumbs.db 63 | ehthumbs.db 64 | ehthumbs_vista.db 65 | 66 | # Folder config file 67 | Desktop.ini 68 | 69 | # Recycle Bin used on file shares 70 | $RECYCLE.BIN/ 71 | 72 | # Windows Installer files 73 | *.cab 74 | *.msi 75 | *.msm 76 | *.msp 77 | 78 | # Windows shortcuts 79 | *.lnk 80 | 81 | 82 | ### MicrosoftOffice template 83 | *.tmp 84 | 85 | # Word temporary 86 | ~$*.doc* 87 | 88 | # Excel temporary 89 | ~$*.xls* 90 | 91 | # Excel Backup File 92 | *.xlk 93 | 94 | 95 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution-NonCommercial-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More_considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 58 | Public License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-NonCommercial-ShareAlike 4.0 International Public License 63 | ("Public License"). To the extent this Public License may be 64 | interpreted as a contract, You are granted the Licensed Rights in 65 | consideration of Your acceptance of these terms and conditions, and the 66 | Licensor grants You such rights in consideration of benefits the 67 | Licensor receives from making the Licensed Material available under 68 | these terms and conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-NC-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution, NonCommercial, and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. NonCommercial means not primarily intended for or directed towards 126 | commercial advantage or monetary compensation. For purposes of 127 | this Public License, the exchange of the Licensed Material for 128 | other material subject to Copyright and Similar Rights by digital 129 | file-sharing or similar means is NonCommercial provided there is 130 | no payment of monetary compensation in connection with the 131 | exchange. 132 | 133 | l. Share means to provide material to the public by any means or 134 | process that requires permission under the Licensed Rights, such 135 | as reproduction, public display, public performance, distribution, 136 | dissemination, communication, or importation, and to make material 137 | available to the public including in ways that members of the 138 | public may access the material from a place and at a time 139 | individually chosen by them. 140 | 141 | m. Sui Generis Database Rights means rights other than copyright 142 | resulting from Directive 96/9/EC of the European Parliament and of 143 | the Council of 11 March 1996 on the legal protection of databases, 144 | as amended and/or succeeded, as well as other essentially 145 | equivalent rights anywhere in the world. 146 | 147 | n. You means the individual or entity exercising the Licensed Rights 148 | under this Public License. Your has a corresponding meaning. 149 | 150 | 151 | Section 2 -- Scope. 152 | 153 | a. License grant. 154 | 155 | 1. Subject to the terms and conditions of this Public License, 156 | the Licensor hereby grants You a worldwide, royalty-free, 157 | non-sublicensable, non-exclusive, irrevocable license to 158 | exercise the Licensed Rights in the Licensed Material to: 159 | 160 | a. reproduce and Share the Licensed Material, in whole or 161 | in part, for NonCommercial purposes only; and 162 | 163 | b. produce, reproduce, and Share Adapted Material for 164 | NonCommercial purposes only. 165 | 166 | 2. Exceptions and Limitations. For the avoidance of doubt, where 167 | Exceptions and Limitations apply to Your use, this Public 168 | License does not apply, and You do not need to comply with 169 | its terms and conditions. 170 | 171 | 3. Term. The term of this Public License is specified in Section 172 | 6(a). 173 | 174 | 4. Media and formats; technical modifications allowed. The 175 | Licensor authorizes You to exercise the Licensed Rights in 176 | all media and formats whether now known or hereafter created, 177 | and to make technical modifications necessary to do so. The 178 | Licensor waives and/or agrees not to assert any right or 179 | authority to forbid You from making technical modifications 180 | necessary to exercise the Licensed Rights, including 181 | technical modifications necessary to circumvent Effective 182 | Technological Measures. For purposes of this Public License, 183 | simply making modifications authorized by this Section 2(a) 184 | (4) never produces Adapted Material. 185 | 186 | 5. Downstream recipients. 187 | 188 | a. Offer from the Licensor -- Licensed Material. Every 189 | recipient of the Licensed Material automatically 190 | receives an offer from the Licensor to exercise the 191 | Licensed Rights under the terms and conditions of this 192 | Public License. 193 | 194 | b. Additional offer from the Licensor -- Adapted Material. 195 | Every recipient of Adapted Material from You 196 | automatically receives an offer from the Licensor to 197 | exercise the Licensed Rights in the Adapted Material 198 | under the conditions of the Adapter's License You apply. 199 | 200 | c. No downstream restrictions. You may not offer or impose 201 | any additional or different terms or conditions on, or 202 | apply any Effective Technological Measures to, the 203 | Licensed Material if doing so restricts exercise of the 204 | Licensed Rights by any recipient of the Licensed 205 | Material. 206 | 207 | 6. No endorsement. Nothing in this Public License constitutes or 208 | may be construed as permission to assert or imply that You 209 | are, or that Your use of the Licensed Material is, connected 210 | with, or sponsored, endorsed, or granted official status by, 211 | the Licensor or others designated to receive attribution as 212 | provided in Section 3(a)(1)(A)(i). 213 | 214 | b. Other rights. 215 | 216 | 1. Moral rights, such as the right of integrity, are not 217 | licensed under this Public License, nor are publicity, 218 | privacy, and/or other similar personality rights; however, to 219 | the extent possible, the Licensor waives and/or agrees not to 220 | assert any such rights held by the Licensor to the limited 221 | extent necessary to allow You to exercise the Licensed 222 | Rights, but not otherwise. 223 | 224 | 2. Patent and trademark rights are not licensed under this 225 | Public License. 226 | 227 | 3. To the extent possible, the Licensor waives any right to 228 | collect royalties from You for the exercise of the Licensed 229 | Rights, whether directly or through a collecting society 230 | under any voluntary or waivable statutory or compulsory 231 | licensing scheme. In all other cases the Licensor expressly 232 | reserves any right to collect such royalties, including when 233 | the Licensed Material is used other than for NonCommercial 234 | purposes. 235 | 236 | 237 | Section 3 -- License Conditions. 238 | 239 | Your exercise of the Licensed Rights is expressly made subject to the 240 | following conditions. 241 | 242 | a. Attribution. 243 | 244 | 1. If You Share the Licensed Material (including in modified 245 | form), You must: 246 | 247 | a. retain the following if it is supplied by the Licensor 248 | with the Licensed Material: 249 | 250 | i. identification of the creator(s) of the Licensed 251 | Material and any others designated to receive 252 | attribution, in any reasonable manner requested by 253 | the Licensor (including by pseudonym if 254 | designated); 255 | 256 | ii. a copyright notice; 257 | 258 | iii. a notice that refers to this Public License; 259 | 260 | iv. a notice that refers to the disclaimer of 261 | warranties; 262 | 263 | v. a URI or hyperlink to the Licensed Material to the 264 | extent reasonably practicable; 265 | 266 | b. indicate if You modified the Licensed Material and 267 | retain an indication of any previous modifications; and 268 | 269 | c. indicate the Licensed Material is licensed under this 270 | Public License, and include the text of, or the URI or 271 | hyperlink to, this Public License. 272 | 273 | 2. You may satisfy the conditions in Section 3(a)(1) in any 274 | reasonable manner based on the medium, means, and context in 275 | which You Share the Licensed Material. For example, it may be 276 | reasonable to satisfy the conditions by providing a URI or 277 | hyperlink to a resource that includes the required 278 | information. 279 | 3. If requested by the Licensor, You must remove any of the 280 | information required by Section 3(a)(1)(A) to the extent 281 | reasonably practicable. 282 | 283 | b. ShareAlike. 284 | 285 | In addition to the conditions in Section 3(a), if You Share 286 | Adapted Material You produce, the following conditions also apply. 287 | 288 | 1. The Adapter's License You apply must be a Creative Commons 289 | license with the same License Elements, this version or 290 | later, or a BY-NC-SA Compatible License. 291 | 292 | 2. You must include the text of, or the URI or hyperlink to, the 293 | Adapter's License You apply. You may satisfy this condition 294 | in any reasonable manner based on the medium, means, and 295 | context in which You Share Adapted Material. 296 | 297 | 3. You may not offer or impose any additional or different terms 298 | or conditions on, or apply any Effective Technological 299 | Measures to, Adapted Material that restrict exercise of the 300 | rights granted under the Adapter's License You apply. 301 | 302 | 303 | Section 4 -- Sui Generis Database Rights. 304 | 305 | Where the Licensed Rights include Sui Generis Database Rights that 306 | apply to Your use of the Licensed Material: 307 | 308 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 309 | to extract, reuse, reproduce, and Share all or a substantial 310 | portion of the contents of the database for NonCommercial purposes 311 | only; 312 | 313 | b. if You include all or a substantial portion of the database 314 | contents in a database in which You have Sui Generis Database 315 | Rights, then the database in which You have Sui Generis Database 316 | Rights (but not its individual contents) is Adapted Material, 317 | including for purposes of Section 3(b); and 318 | 319 | c. You must comply with the conditions in Section 3(a) if You Share 320 | all or a substantial portion of the contents of the database. 321 | 322 | For the avoidance of doubt, this Section 4 supplements and does not 323 | replace Your obligations under this Public License where the Licensed 324 | Rights include other Copyright and Similar Rights. 325 | 326 | 327 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 328 | 329 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 330 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 331 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 332 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 333 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 334 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 335 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 336 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 337 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 338 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 339 | 340 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 341 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 342 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 343 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 344 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 345 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 346 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 347 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 348 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 349 | 350 | c. The disclaimer of warranties and limitation of liability provided 351 | above shall be interpreted in a manner that, to the extent 352 | possible, most closely approximates an absolute disclaimer and 353 | waiver of all liability. 354 | 355 | 356 | Section 6 -- Term and Termination. 357 | 358 | a. This Public License applies for the term of the Copyright and 359 | Similar Rights licensed here. However, if You fail to comply with 360 | this Public License, then Your rights under this Public License 361 | terminate automatically. 362 | 363 | b. Where Your right to use the Licensed Material has terminated under 364 | Section 6(a), it reinstates: 365 | 366 | 1. automatically as of the date the violation is cured, provided 367 | it is cured within 30 days of Your discovery of the 368 | violation; or 369 | 370 | 2. upon express reinstatement by the Licensor. 371 | 372 | For the avoidance of doubt, this Section 6(b) does not affect any 373 | right the Licensor may have to seek remedies for Your violations 374 | of this Public License. 375 | 376 | c. For the avoidance of doubt, the Licensor may also offer the 377 | Licensed Material under separate terms or conditions or stop 378 | distributing the Licensed Material at any time; however, doing so 379 | will not terminate this Public License. 380 | 381 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 382 | License. 383 | 384 | 385 | Section 7 -- Other Terms and Conditions. 386 | 387 | a. The Licensor shall not be bound by any additional or different 388 | terms or conditions communicated by You unless expressly agreed. 389 | 390 | b. Any arrangements, understandings, or agreements regarding the 391 | Licensed Material not stated herein are separate from and 392 | independent of the terms and conditions of this Public License. 393 | 394 | 395 | Section 8 -- Interpretation. 396 | 397 | a. For the avoidance of doubt, this Public License does not, and 398 | shall not be interpreted to, reduce, limit, restrict, or impose 399 | conditions on any use of the Licensed Material that could lawfully 400 | be made without permission under this Public License. 401 | 402 | b. To the extent possible, if any provision of this Public License is 403 | deemed unenforceable, it shall be automatically reformed to the 404 | minimum extent necessary to make it enforceable. If the provision 405 | cannot be reformed, it shall be severed from this Public License 406 | without affecting the enforceability of the remaining terms and 407 | conditions. 408 | 409 | c. No term or condition of this Public License will be waived and no 410 | failure to comply consented to unless expressly agreed to by the 411 | Licensor. 412 | 413 | d. Nothing in this Public License constitutes or may be interpreted 414 | as a limitation upon, or waiver of, any privileges and immunities 415 | that apply to the Licensor or You, including from the legal 416 | processes of any jurisdiction or authority. 417 | 418 | ======================================================================= 419 | 420 | Creative Commons is not a party to its public licenses. 421 | Notwithstanding, Creative Commons may elect to apply one of its public 422 | licenses to material it publishes and in those instances will be 423 | considered the "Licensor." Except for the limited purpose of indicating 424 | that material is shared under a Creative Commons public license or as 425 | otherwise permitted by the Creative Commons policies published at 426 | creativecommons.org/policies, Creative Commons does not authorize the 427 | use of the trademark "Creative Commons" or any other trademark or logo 428 | of Creative Commons without its prior written consent including, 429 | without limitation, in connection with any unauthorized modifications 430 | to any of its public licenses or any other arrangements, 431 | understandings, or agreements concerning use of licensed material. For 432 | the avoidance of doubt, this paragraph does not form part of the public 433 | licenses. 434 | 435 | Creative Commons may be contacted at creativecommons.org. 436 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 📚 🐣 软件实践文集 2 | 3 | 4 | 5 | [![知识共享协议(CC协议)](https://img.shields.io/badge/License-Creative%20Commons-FE6B3A.svg?logo=apache) ![Licence: CC BY-NC-SA 4.0](images/LICENSE.png)](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh) 6 | [![GitHub stars](https://img.shields.io/github/stars/oldratlee/software-practice-miscellany.svg?style=social&label=Star)](https://github.com/oldratlee/software-practice-miscellany/stargazers) 7 | [![GitHub forks](https://img.shields.io/github/forks/oldratlee/software-practice-miscellany.svg?style=social&label=Fork)](https://github.com/software-practice-miscellany/software-practice-miscellany/fork) 8 | 9 | 记录与整理平时自己的 10 | 11 | - 软件实践的讨论 12 | - 软件实践主题的思考 13 | 14 | 主题不限,有趣有料就好~ 🥤 15 | 16 | > PS:比起写博客,直接用`github`仓库的`Markdown`来记录真是简单省事! 😂 17 | 18 | - 🙈 [自己](http://weibo.com/oldratlee)写的这些内容难免有不足和不对之处,欢迎 👏 19 | - 建议,[提交`Issue`](https://github.com/oldratlee/software-practice-miscellany/issues/new) 20 | - 指正,[`Fork`后提通过`Pull Request`贡献修改](https://github.com/oldratlee/software-practice-miscellany/fork) 21 | - 如果理解上有疑问 或是 应用过程中碰到疑惑,请[提交 🙌 `Issue`](https://github.com/oldratlee/software-practice-miscellany/issues/new) ,一起学习交流讨论! 22 | 23 | ---------------------------------------- 24 | 25 | 26 | 27 | 28 | - [⏳ 按内容时间排序](#-%E6%8C%89%E5%86%85%E5%AE%B9%E6%97%B6%E9%97%B4%E6%8E%92%E5%BA%8F) 29 | - [🎵 按内容主题分类](#-%E6%8C%89%E5%86%85%E5%AE%B9%E4%B8%BB%E9%A2%98%E5%88%86%E7%B1%BB) 30 | - [实践讨论](#%E5%AE%9E%E8%B7%B5%E8%AE%A8%E8%AE%BA) 31 | - [如何做开源项目](#%E5%A6%82%E4%BD%95%E5%81%9A%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE) 32 | - [系统设计与分析](#%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%88%86%E6%9E%90) 33 | - [`SCM`](#scm) 34 | - [软件文档](#%E8%BD%AF%E4%BB%B6%E6%96%87%E6%A1%A3) 35 | - [编程语言](#%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80) 36 | 37 | 38 | 39 | ---------------------------------------- 40 | 41 | # ⏳ 按内容时间排序 42 | 43 | 44 | 45 | > 下一节是 [⬇️ **按内容主题分类** ⬇️](#-%E6%8C%89%E5%86%85%E5%AE%B9%E4%B8%BB%E9%A2%98%E5%88%86%E7%B1%BB) 46 | 47 | - **2021年** [软件实践碎碎念](broken-thoughts/README.md) 48 | - **2021-06** [平台产品逻辑与执行](product-logic-for-platform-product/README.md) 49 | - **全接管业务的功能** 是平台的目标,直接体现了平台的核心竞争力。 50 | 全接管业务的平台功能的多少/比例 可以用来度量 平台的成熟程度。 51 | - 在平台产品功能中,要区分 哪些是接管的功能,哪些是整合的功能。 52 | - **不要用美好正义的愿望 来替代 残酷务实的逻辑。** 53 | 即产品逻辑 推演要包含给出 如何『做成』一个产品(可行性),而不仅是给出 为什么要『要做』一个产品(有需求)。 54 | - 排除法 对于不确定的规划的事 是不适用的;因为 事情是不是有解/整体组合功能是不是能发展出来 还是未知的。 55 | - **2021-04** [多响应异步请求模式下需求满足的分析模型](multi-response-async-request-pattern-analysis-model/README.md) 56 | - 请求的3个关注维度`CRC`:**完整性**(`Completeness`)、**响应性**(`Responsiveness`)与**正确性**(`Correctness`)。 57 | - `CRC`也是请求的平衡维度,所谓平衡是指:当不可兼得时,可互相置换。 58 | - **请求所关注与平衡的CRC维度模型 也一样适用于 同步请求模式,并不耦合 多响应异步请求模式。** 59 | 只是多响应异步请求模式下的复杂性,在分析上对请求维度模型的需要变得迫切了。 60 | 我们可以用请求维度`CRC`模型作为 引入多响应异步请求模式后对产品/用户体验的优化程度 的一种度量方式。 61 | - 多响应/异步的模式下,相对于传统的同步模式,可以为业务提供了更灵活方便的策略。 62 | - **2020年** [软件实践碎碎念](broken-thoughts/2020.md) 63 | - **2020-08** [`compileflow`开源项目的Code Review](compiler-flow-code-review/README.md) 64 | - Review与交流讨论的过程 是自己整理学习的过程。大部分的整理内容 其实是独立于具体的一个开源项目。 65 | - 涉及如 代码实现(文档、可靠性、专业性)、系统设计(领域/模型拆分的原则与实践、扩展设计)、工程实践(版本管理、构建、测试)。 66 | - **2020-08** | 2017-08 … 2014 分享PPT [软件可靠性设计的实践](practice-of-software-reliability-design/软件可靠性设计的实践-v0.9.2.pptx) 67 | - **2020-07** 分享PPT [Git/VCS的使用与原则 简介](git/git-usage-and-principle-v0.3.1.pptx) 68 | - **2020-03** [系统`Load`的样子与计算方式](system-load-calculation-and-looks/README.md) 69 | 你常常看的`Load 1/5/15`是怎么回事? 70 | - **2020-02** 分享PPT [开源漫游者指南:开源的工作内容与要点](hitchhikers-guide-to-open-source/开源漫游者指南-v0.9.1.pptx) 71 | - 开源是一个充分竞争的环境,不能没有差异化或有明显缺陷,有问题无法隐藏。竞争三要素:1) 成本 2) 差异化 3) 专业化 72 | - 产品有明确的独特性、差异化(性能/功能) => 拉新/启动 73 | - 产品界面的部分 重要 => 留存 74 | - 持续发版/用户(大)Case收集透出(活跃、质量) => 流失 vs. 口碑传播 75 | - 伸手当是主流;一般用户成为贡献者都是小提交贡献;核心贡献者 肯定会是大厂公司的人,注重形成公司间团队的合作联盟。 76 | - **2019-10** [任务分发均匀性的模型量化分析](lb-distribution-uniformity-analysis/README.md) 77 | - 任务分发在软件系统的很多地方会出现。 78 | - 任务分发/`LB`的均匀性是一个需要考虑的问题,会导致不必要的过载甚至宕机。 79 | - **2017-03** [`Cache`实践](cache-practice/README.md) 80 | - 应用开发中,`Cache`毫无疑问是很重要的一块:提升应用性能的关键,降低像`DB`这样关键资源的负荷; 81 | - 但`Cache`的使用有很多要注意的问题与陷阱。 82 | - **2015-06** 分享PPT [Git/GitLab(Github)使用](git/git-gitlab-usage.pptx) 83 | - **2015-06** 软件文档 [如何写一个`issue`](how-to-write-a-issue.md) 84 | - **2014-12** [Git学习资料](git/study-material.md) 85 | - **2014-09** [Why Git](git/README.md) 86 | - **2014-09** 编程语言 [`Lisp` Practice](lisp-practice/README.md) 87 | 对于大多数程序员来说,`Lisp`是编程语言中的一个神。 88 | 89 | # 🎵 按内容主题分类 90 | 91 | 92 | 93 | > 上一节是 [⬆️ **按内容时间排序** ⬆️](#-%E6%8C%89%E5%86%85%E5%AE%B9%E6%97%B6%E9%97%B4%E6%8E%92%E5%BA%8F) 94 | 95 | ## 实践讨论 96 | 97 | - 软件实践碎碎念 98 | - [2021年](broken-thoughts/README.md) 99 | - [2020年](broken-thoughts/2020.md) 100 | - Code Review 101 | - [`compileflow`开源项目的Code Review](compiler-flow-code-review/README.md) 102 | - Review与交流讨论的过程 是自己整理学习的过程。大部分的整理内容 其实是独立于具体的一个开源项目。 103 | - 涉及如 代码实现(文档、可靠性、专业性)、系统设计(领域/模型拆分的原则与实践、扩展设计)、工程实践(版本管理、构建、测试)。 104 | 105 | ## 如何做开源项目 106 | 107 | - 分享PPT [开源漫游者指南:开源的工作内容与要点](hitchhikers-guide-to-open-source/开源漫游者指南-v0.9.1.pptx) 108 | - 开源是一个充分竞争的环境,不能没有差异化或有明显缺陷,有问题无法隐藏。竞争三要素:1) 成本 2) 差异化 3) 专业化 109 | - 产品有明确的独特性、差异化(性能/功能) => 拉新/启动 110 | - 产品界面的部分 重要 => 留存 111 | - 持续发版/用户(大)Case收集透出(活跃、质量) => 流失 vs. 口碑传播 112 | - 伸手当是主流;一般用户成为贡献者都是小提交贡献;核心贡献者 肯定会是大厂公司的人,注重形成公司间团队的合作联盟。 113 | 114 | ## 系统设计与分析 115 | 116 | - 分享PPT [软件可靠性设计的实践](practice-of-software-reliability-design/软件可靠性设计的实践-v0.9.2.pptx) 117 | - [平台产品逻辑与执行](product-logic-for-platform-product/README.md) 118 | - **全接管业务的功能** 是平台的目标,直接体现了平台的核心竞争力。 119 | 全接管业务的平台功能的多少/比例 可以用来度量 平台的成熟程度。 120 | - 在平台产品功能中,要区分 哪些是接管的功能,哪些是整合的功能。 121 | - **不要用美好正义的愿望 来替代 残酷务实的逻辑。** 122 | 即产品逻辑 推演要包含给出 如何『做成』一个产品(可行性),而不仅是给出 为什么要『要做』一个产品(有需求)。 123 | - 排除法 对于不确定的规划的事 是不适用的;因为 事情是不是有解/整体组合功能是不是能发展出来 还是未知的。 124 | - [多响应异步请求模式下需求满足的分析模型](multi-response-async-request-pattern-analysis-model/README.md) 125 | - 请求的3个关注维度`CRC`:**完整性**(`Completeness`)、**响应性**(`Responsiveness`)与**正确性**(`Correctness`)。 126 | - `CRC`也是请求的平衡维度,所谓平衡是指:当不可兼得时,可互相置换。 127 | - **请求所关注与平衡的CRC维度模型 也一样适用于 同步请求模式,并不耦合 多响应异步请求模式。** 128 | 只是多响应异步请求模式下的复杂性,在分析上对请求维度模型的需要变得迫切了。 129 | 我们可以用请求维度`CRC`模型作为 引入多响应异步请求模式后对产品/用户体验的优化程度 的一种度量方式。 130 | - 多响应/异步的模式下,相对于传统的同步模式,可以为业务提供了更灵活方便的策略。 131 | - [任务分发均匀性的模型量化分析](lb-distribution-uniformity-analysis/README.md) 132 | - 任务分发在软件系统的很多地方会出现。 133 | - 任务分发/`LB`的均匀性是一个需要考虑的问题,会导致不必要的过载甚至宕机。 134 | - [`Cache`实践](cache-practice/README.md) 135 | - 应用开发中,`Cache`毫无疑问是很重要的一块:提升应用性能的关键,降低像`DB`这样关键资源的负荷; 136 | - 但`Cache`的使用有很多要注意的问题与陷阱。 137 | - [系统`Load`的样子与计算方式](system-load-calculation-and-looks/README.md) 138 | 你常常看的`Load 1/5/15`是怎么回事? 139 | 140 | ## `SCM` 141 | 142 | - [Why Git](git/README.md) 143 | - [Git学习资料](git/study-material.md) 144 | - 分享PPT 145 | - [Git/VCS的使用与原则 简介](git/git-usage-and-principle-v0.3.1.pptx) 146 | - [Git/GitLab(Github)使用](git/git-gitlab-usage.pptx) 147 | 148 | ## 软件文档 149 | 150 | - [如何写一个`issue`](how-to-write-a-issue.md) 151 | 152 | ## 编程语言 153 | 154 | - [`Lisp` Practice](lisp-practice/README.md) 155 | 对于大多数程序员来说,`Lisp`是编程语言中的一个神。 156 | -------------------------------------------------------------------------------- /about-control/关于控制系统-v0.3.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/about-control/关于控制系统-v0.3.pptx -------------------------------------------------------------------------------- /about-control/指数特征-v0.6.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/about-control/指数特征-v0.6.xlsx -------------------------------------------------------------------------------- /antlr-practice/Material.md: -------------------------------------------------------------------------------- 1 | `Antlr`资料 2 | =============================== 3 | 4 | 官方资料 5 | ----------------------- 6 | 7 | - [Home Page](http://www.antlr.org/) 8 | - [Documentation](https://theantlrguy.atlassian.net/wiki/display/ANTLR4/ANTLR+4+Documentation) 9 | - [`Antlr` 4 `GitHub` Repository](https://github.com/antlr/antlr4) 10 | - [`Antlr` 3 Home Page](http://www.antlr3.org/) 11 | - [`Antlr` 3 Documentation](https://theantlrguy.atlassian.net/wiki/display/ANTLR3/ANTLR+v3+documentation) 12 | 13 | 文章 14 | ----------------------- 15 | 16 | - [ibm developerworks - 使用`Antlr`开发领域语言](https://www.ibm.com/developerworks/cn/java/j-lo-antlr/) 17 | - [The `ANTLR` Parser Generator](http://www.bearcave.com/software/antlr/index.html) 18 | 19 | 插件 20 | ----------------------- 21 | 22 | - [IntelliJ IDEA plugin - ANTLRWorks](https://plugins.jetbrains.com/plugin/953) 23 | - [ANTLR 4 IDE for Eclipse](https://github.com/jknack/antlr4ide) 24 | 25 | 书籍 26 | ----------------------- 27 | 28 | - [ANTLR 4权威指南](https://book.douban.com/subject/27082372/) | [The Definitive ANTLR 4 Reference](https://book.douban.com/subject/17912658/) 29 | - [编程语言实现模式](https://book.douban.com/subject/10482195/) | [Language Implementation Patterns](https://book.douban.com/subject/4030327/) 30 | - 更多见[`amazon`搜索](http://www.amazon.com/s/ref=nb_sb_noss?url=node%3D5&field-keywords=antlr) 31 | -------------------------------------------------------------------------------- /antlr-practice/README.md: -------------------------------------------------------------------------------- 1 | `Antlr` Practice 2 | =============================== 3 | -------------------------------------------------------------------------------- /broken-thoughts/2020.md: -------------------------------------------------------------------------------- 1 | # 软件实践碎碎念 - 2020 2 | 3 | ---------------------------------------- 4 | 5 | 6 | 7 | 8 | - [《架构设计分享》听的记录&感想 - 2020-12-31](#%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1%E5%88%86%E4%BA%AB%E5%90%AC%E7%9A%84%E8%AE%B0%E5%BD%95%E6%84%9F%E6%83%B3---2020-12-31) 9 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA) 10 | - [面向业务价值的流管及其演进 - 2020-12-29](#%E9%9D%A2%E5%90%91%E4%B8%9A%E5%8A%A1%E4%BB%B7%E5%80%BC%E7%9A%84%E6%B5%81%E7%AE%A1%E5%8F%8A%E5%85%B6%E6%BC%94%E8%BF%9B---2020-12-29) 11 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-1) 12 | - [深度/底层优化 - 2020-12-25](#%E6%B7%B1%E5%BA%A6%E5%BA%95%E5%B1%82%E4%BC%98%E5%8C%96---2020-12-25) 13 | - [发展与文化 - 2020-12-24](#%E5%8F%91%E5%B1%95%E4%B8%8E%E6%96%87%E5%8C%96---2020-12-24) 14 | - [软件工程基本定理(the Fundamental Theorem of Software Engineering/`FTSE`)、间接层 - 2020-12-13](#%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%9F%BA%E6%9C%AC%E5%AE%9A%E7%90%86the-fundamental-theorem-of-software-engineeringftse%E9%97%B4%E6%8E%A5%E5%B1%82---2020-12-13) 15 | - [数据分析思维 - 2020-12-11](#%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E6%80%9D%E7%BB%B4---2020-12-11) 16 | - [代码是负债,越少越好!解决用户问题的系统才是资产! - 2020-11-20](#%E4%BB%A3%E7%A0%81%E6%98%AF%E8%B4%9F%E5%80%BA%E8%B6%8A%E5%B0%91%E8%B6%8A%E5%A5%BD%E8%A7%A3%E5%86%B3%E7%94%A8%E6%88%B7%E9%97%AE%E9%A2%98%E7%9A%84%E7%B3%BB%E7%BB%9F%E6%89%8D%E6%98%AF%E8%B5%84%E4%BA%A7---2020-11-20) 17 | - [伟大的库 - 2020-11-05](#%E4%BC%9F%E5%A4%A7%E7%9A%84%E5%BA%93---2020-11-05) 18 | - [表达与咨询 - 2020-10-30](#%E8%A1%A8%E8%BE%BE%E4%B8%8E%E5%92%A8%E8%AF%A2---2020-10-30) 19 | - [单位引起的故障及其应对实践 - 2020-10-29](#%E5%8D%95%E4%BD%8D%E5%BC%95%E8%B5%B7%E7%9A%84%E6%95%85%E9%9A%9C%E5%8F%8A%E5%85%B6%E5%BA%94%E5%AF%B9%E5%AE%9E%E8%B7%B5---2020-10-29) 20 | - [你又在滥用继承!继承不是为了复用代码,而为了被复用 - 2020-10-20](#%E4%BD%A0%E5%8F%88%E5%9C%A8%E6%BB%A5%E7%94%A8%E7%BB%A7%E6%89%BF%E7%BB%A7%E6%89%BF%E4%B8%8D%E6%98%AF%E4%B8%BA%E4%BA%86%E5%A4%8D%E7%94%A8%E4%BB%A3%E7%A0%81%E8%80%8C%E4%B8%BA%E4%BA%86%E8%A2%AB%E5%A4%8D%E7%94%A8---2020-10-20) 21 | - [`ConcurrentMap`/`ConcurrentHashMap`的`computeIfAbsent`只执行一次吗? - 2020-10-12](#concurrentmapconcurrenthashmap%E7%9A%84computeifabsent%E5%8F%AA%E6%89%A7%E8%A1%8C%E4%B8%80%E6%AC%A1%E5%90%97---2020-10-12) 22 | - [面向对象/过程化程序设计、依赖策略 - 2020-10-10](#%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BF%87%E7%A8%8B%E5%8C%96%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E4%BE%9D%E8%B5%96%E7%AD%96%E7%95%A5---2020-10-10) 23 | - [Statistical Thinking - 2020-09-16](#statistical-thinking---2020-09-16) 24 | - [近义多个的概念名 - 2020-09-08](#%E8%BF%91%E4%B9%89%E5%A4%9A%E4%B8%AA%E7%9A%84%E6%A6%82%E5%BF%B5%E5%90%8D---2020-09-08) 25 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-2) 26 | - [整洁的架构/编程范式 - 2020-08-28](#%E6%95%B4%E6%B4%81%E7%9A%84%E6%9E%B6%E6%9E%84%E7%BC%96%E7%A8%8B%E8%8C%83%E5%BC%8F---2020-08-28) 27 | - [并发 - 2020-08-28](#%E5%B9%B6%E5%8F%91---2020-08-28) 28 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-3) 29 | - [软件设计书籍 - 2020-08-19](#%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E4%B9%A6%E7%B1%8D---2020-08-19) 30 | - [模块形状(深/高瘦程度)作为抽象/系统设计/建模的好坏的判断 - 2020-08-07](#%E6%A8%A1%E5%9D%97%E5%BD%A2%E7%8A%B6%E6%B7%B1%E9%AB%98%E7%98%A6%E7%A8%8B%E5%BA%A6%E4%BD%9C%E4%B8%BA%E6%8A%BD%E8%B1%A1%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E5%BB%BA%E6%A8%A1%E7%9A%84%E5%A5%BD%E5%9D%8F%E7%9A%84%E5%88%A4%E6%96%AD---2020-08-07) 31 | - [Unknown is Unknown! - 2020-08-24](#unknown-is-unknown---2020-08-24) 32 | - [Reactive programming: lessons learned - 2020-06-01](#reactive-programming-lessons-learned---2020-06-01) 33 | - [每当我想放弃 Scala,我就写写 Python 和 Java - 2020-05-08](#%E6%AF%8F%E5%BD%93%E6%88%91%E6%83%B3%E6%94%BE%E5%BC%83-scala%E6%88%91%E5%B0%B1%E5%86%99%E5%86%99-python-%E5%92%8C-java---2020-05-08) 34 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-4) 35 | - [业务价值体感化的套路模式 - 2020-05-02](#%E4%B8%9A%E5%8A%A1%E4%BB%B7%E5%80%BC%E4%BD%93%E6%84%9F%E5%8C%96%E7%9A%84%E5%A5%97%E8%B7%AF%E6%A8%A1%E5%BC%8F---2020-05-02) 36 | - [基础设计理念的持续滚动成为代差 - 2020-05-01](#%E5%9F%BA%E7%A1%80%E8%AE%BE%E8%AE%A1%E7%90%86%E5%BF%B5%E7%9A%84%E6%8C%81%E7%BB%AD%E6%BB%9A%E5%8A%A8%E6%88%90%E4%B8%BA%E4%BB%A3%E5%B7%AE---2020-05-01) 37 | - [事实和观点 - 2020-04-30](#%E4%BA%8B%E5%AE%9E%E5%92%8C%E8%A7%82%E7%82%B9---2020-04-30) 38 | - [Lombok与语法糖 - 2020-04-28](#lombok%E4%B8%8E%E8%AF%AD%E6%B3%95%E7%B3%96---2020-04-28) 39 | - [《程序员修炼之道》 - 2020-04-16](#%E7%A8%8B%E5%BA%8F%E5%91%98%E4%BF%AE%E7%82%BC%E4%B9%8B%E9%81%93---2020-04-16) 40 | - [代码设计 - 2020-04-16](#%E4%BB%A3%E7%A0%81%E8%AE%BE%E8%AE%A1---2020-04-16) 41 | 42 | 43 | 44 | ---------------------------------------- 45 | 46 | ## 《架构设计分享》听的记录&感想 - 2020-12-31 47 | 48 | 1. 详情是商品?灯、商品vs详情页 49 | * 关于 虚拟与透明 50 | * 关于 抽象(关注、选择的特征) 51 | * 关于 内涵、外延 52 | 2. 分类原则,平时我个人常常说成 维度, 53 | * 如policy。因为发现出现在多层中而表达混乱时,是因为有一个需要关注的一维度没有显式表达出来 54 | - 维度不够(分析的信息丢失不足) 55 | 3. 分层 与 分治 56 | * 推荐 《恰如其分的软件架构:风险驱动的设计方法》第13章 模型关系 57 | https://book.douban.com/subject/24872314/ 58 | 4. 设计模式 会去套模式,自然长出来 59 | * 问题出发,而不是手段(可套用的设计模式)。 60 | * 设计模式是对 解决手段 的 统一表达,为了高效交流 61 | 5. 交流、元概念 62 | * 元概念 往往不定义 或说 63 | - 表述内涵极困难 64 | - 前期表述出来也没有 指导(因为过抽象) 65 | - 但大家在脑子里会有直觉感受 66 | * 用如xxx、yyy举例的方式来表述 就方便、节省时间,即用 67 | * 大家真理解/琢磨/实战之后 再给定义描述内涵,这时又觉得精髓有有用了 68 | * 如何高效的讨论交流,tip 1: 69 | 前期时、对入门者,不要讨论元概念的定义/内涵 70 | 71 | ---------------------------------------- 72 | 73 | - 关于 虚拟与透明: 74 | - 无中生有 是 虚拟 75 | - 有而无视 是 透明 76 | - 恰如其分的软件架构 https://book.douban.com/subject/24872314/ 77 | - 第13章 模型关系 讲了概念(模型中的 Node)间的N种关系(模型中的连线),(较meta的内容)。 78 | - ![](images/2021-06-29-15-04-10.png) 79 | - 逻辑学中「外延」与「内涵」是什么意思? https://www.zhihu.com/answer/83324512 80 | 81 | ### 大家的讨论 82 | 83 | - Mr. G 84 | - 另外一个重要的点是:架构要讲人话,尽量用约定俗成的概念,少造概念 85 | - Reply By `@oldratlee`: 86 | - 如无必要,优先用大家平时的用语/概念名 87 | - 直到不行、有缺陷、概念不够用时,造新 88 | - 用词要仔细推敲,影响是巨大的 89 | 90 | ## 面向业务价值的流管及其演进 - 2020-12-29 91 | 92 | Posted by Mr. L 93 | 94 | 马克尼(`MARCONI`)解决了多年来的`GraphQL`的难题,按照业务标识/身份等管控粒度分级限流。 95 | 最近有不少人在问,之前的解决办法提供多个TQL- MTOP接口,采取高中低业务分级 哈。 96 | 97 | ### 大家的讨论 98 | 99 | - Reply By `@oldratlee`: 100 | 1. 从做`reactive` 演进到 高可用/自适应限流`Noah` (即reactive回压、技术架构的流控) 101 | 2. 再到 `marconi`(面向业务价值的流量管控:业务标识管理、服务分级、面向业务架构) 102 | 3. Marconi进一步上跳演进 应该是,业务线(如淘宝)的产品迭代试错(不是一个功能的上线)、即泳道 103 | - 相信这个是现在的痛点、也是后面很长一段时间的结构性问题,相信Marconi是其中的关键主导。 104 | - [`@hepin1989`](https://github.com/hepin1989): 105 | - 在系统资源有限,而“系统的用户”存在不确定性行为的情况下,就需要马可尼。 106 | - Mr. L 107 | - 『description:给人看的说明』,有个性的文档 108 | - 『给人看』这个词有点趣味性,好比小米手机给屌丝用的? 109 | - Reply By `@oldratlee`: 110 | - 文档这句 来源于设计问题的讨论: 111 | - id 不要有 string信息,int 就好?(系统内部运转用的、方便简单、唯一) 112 | - 如果 意图是『给人看的』,编码到 description 就好了 113 | - 讨论思辨了1个小时,达成共识 114 | - [`@hepin1989`](https://github.com/hepin1989): 115 | - 韩国人在一生中无法避免的三个东西:死亡、纳税和三星。 116 | - 希望我们基础软件也可以做到这种水平。 117 | - Reply By `@oldratlee`: 118 | - 有三样东西是不能隐藏的:咳嗽、贫穷和爱。 119 | - PS: 「有三样东西是不能隐藏的:咳嗽、贫穷和爱」这句话的出处是哪里? 120 | https://www.zhihu.com/question/20779304 121 | - Mr. K 122 | - 人有三样东西是无法隐瞒的,咳嗽,穷困和爱,你想隐瞒越欲盖弥彰。 123 | - 人有三样东西是不该挥霍的,身体,金钱和爱,你想挥霍却得不偿失。 124 | - 人有三样东西是无法挽留的,时间,生命和爱,你想挽留却渐行渐远。 125 | - 人有三样东西是不该回忆的,灾难,死亡和爱,你想回忆却苦不堪言。 126 | - ——《洛丽塔》 127 | - Reply By `@oldratlee`: 128 | - 爱 是个 变色龙啊。 129 | - Reply By Mr. L: 130 | - 人有一样的东西人人都有,那是 爱。 131 | 132 | ## 深度/底层优化 - 2020-12-25 133 | 134 | > ScyllaDB 是用 C++ 重写的 Cassandra,每节点每秒处理 100 万 TPS。ScyllaDB 完全兼容 Apache Cassandra,拥有比 Cassandra 多 10x 倍的吞吐量,降低了延迟。 135 | > https://baike.baidu.com/item/ScyllaDB/18705315 136 | > 137 | > - https://github.com/scylladb/scylla 138 | > - https://github.com/scylladb/seastar 139 | 140 | `ScyllaDB`及其团队的深度/底层优化很有影响力 141 | 142 | ## 发展与文化 - 2020-12-24 143 | 144 | > 陆奇最新演讲:2020,被加速的4大趋势 145 | > https://mp.weixin.qq.com/s/d4354YNYQTgA_HqTWFaBwg 146 | 147 | 分享一篇文章,从创业的视角看现在和未来的发展趋势和应对的一些方法论,视角挺宏大的,不创业看了也是有一些帮助。 148 | 149 | ---------------------------------------- 150 | 151 | > 奈飞文化手册 152 | > https://book.douban.com/subject/30356081/ 153 | > 154 | > ![](images/2021-06-29-15-31-26.png) 155 | > 156 | > ![](images/2021-06-29-15-31-45.png) 157 | > 158 | > ![](images/2021-06-29-15-32-00.png) 159 | > 160 | > 人们也会对自己整理的数据持有偏见。我们发现,人们倾向于认为自己的数据优于他人的数据。 161 | > 但其实,数据只是解决问题的一个部分,即便每一个部门的每一个人都拥有同样的数据,你依然需要让大家就业务的各个环节进行辩论,而这些是数据做不到的。 162 | 163 | - HR主题的书,看看这些内容 不HR的样子 164 | - 科学 方法论/方式 再怎么多说 都不为过;虽然 听听觉得老生常谈,想想觉得还是这理。 165 | - 数据 通过人(选择、表达),便不再只是数据(不中立、偏向化了) 166 | 167 | ## 软件工程基本定理(the Fundamental Theorem of Software Engineering/`FTSE`)、间接层 - 2020-12-13 168 | 169 | **软件工程基本定理**(the Fundamental Theorem of Software Engineering/**`FTSE`**)v2: 170 | 171 | > 所有计算机科学问题,都可以通过引入一个新的间接层次来解决,那些已有过多间接层次的问题除外。 172 | > — David J. Wheeler (《C++程序设计语言 第4版》 前言) 173 | > 174 | > 175 | 176 | **`FTSE`** v1: 177 | 178 | > 我们可以通过引入一个额外的间接层来解决任何问题。 179 | > — Butler Lampson(《C++模板元编程》2.1.2) 180 | > 181 | > 182 | 183 | **`FTSE`** v2 = **`FTSE`** v1 ∧ 没有银弹公理(《人月神话》)。 184 | 185 | ---------------------------------------- 186 | 187 | 内容也发到了[微博](https://weibo.com/1836334682/JyhDF4AIQ)上。 188 | 189 | 讨论: 190 | 191 | - 要保有 抽象概念设计/自己独立概念 aka. 间接层 192 | - 如何保有抽象/间接/系统设计弹性,且让其低成本(理解、实现、修改) 是 软件工程的艺术、难点。 193 | - 需求泛化过程(即产品系统化的过程),自己与外部不一致的认知/问题会明显。 194 | - 即 出现一个之前没在意的合理用例/需求时,当前系统 需求不可解 & 要做基础概念(即模型)的调整重构。 195 | 196 | PS: 197 | 198 | - [**算术基本定理**](https://baike.baidu.com/item/%E7%AE%97%E6%9C%AF%E5%9F%BA%E6%9C%AC%E5%AE%9A%E7%90%86/10920095): 199 | - 任何一个大于1的自然数N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积。 200 | - [**代数基本定理**](https://baike.baidu.com/item/%E4%BB%A3%E6%95%B0%E5%9F%BA%E6%9C%AC%E5%AE%9A%E7%90%86/18104): 201 | - 任何复系数一元n次多项式 方程在复数域上至少有一根(n≥1),由此推出,n次复系数多项式方程在复数域内有且只有n个根(重根按重数计算)。 202 | - [**微积分基本定理**](https://zh.wikipedia.org/zh-hans/%E5%BE%AE%E7%A7%AF%E5%88%86%E5%9F%BA%E6%9C%AC%E5%AE%9A%E7%90%86): 203 | - 定理的第一部分,称为微积分第一基本定理,此定理表明: 204 | 给定任一连续函数,可以(利用积分)构造出该函数的反导函数。 205 | 这一部分定理的重要之处在于它保证了连续函数的反导函数的存在性。 206 | - 定理的第二部分,称为微积分第二基本定理或牛顿-莱布尼茨公式,表明: 207 | 某函数的定积分可以用该函数的任意一个反导函数来计算。 208 | 这一部分是微积分或数学分析中相当关键且应用很广的一个定理,因为它大大简化了定积分的计算。 209 | - 对微积分基本定理比较直观的理解是: 210 | 把函数在一段区间的『无穷小变化』全部『加起来』,会等于该函数的净变化,这里『无穷小变化』就是微分,『加起来』就是积分,净变化就是该函数在区间两端点的差。 211 | 212 | ## 数据分析思维 - 2020-12-11 213 | 214 | 《数据分析思维:分析方法和业务知识》 215 | https://book.douban.com/subject/35234331/ 216 | 217 | 看了目录结构 感觉不错,评分9.0。数据分析、业务/产品的洞察 无处无时不在。 218 | 219 | > 目录: 220 | > 221 | > 第1篇 方法 222 | > 第1章 业务指标 223 | > 1.1 如何理解数据? 224 | > 1.2 常用的指标有哪些? 225 | > 1.2 如何选择指标? 226 | > 1.4 指标体系和报表 227 | > 第2章 分析方法 228 | > 2.1 5W2H分析方法 229 | > 2.2 逻辑树分析方法 230 | > 2.3 行业分析方法 231 | > 2.4 多维度拆解分析方法 232 | > 2.5 对比分析方法 233 | > 2.6 假设检验分析方法 234 | > 2.7 相关分析方法 235 | > 2.8 群组分析方法 236 | > 2.9 RFM分析方法 237 | > 2.10 AARRR模型分析方法 238 | > 2.11 漏斗分析方法 239 | > 第3章 用数据分析解决问题 240 | > 3.1 数据分析解决问题的过程 241 | > 3.2 如何明确问题? 242 | > 3.3 如何分析原因? 243 | > 3.4 如何提出建议? 244 | > ………… 245 | 246 | ## 代码是负债,越少越好!解决用户问题的系统才是资产! - 2020-11-20 247 | 248 | > 我今天的观点是,如果我们要对代码统计行数,不应该把代码看成是『作为资产的行』,而应该看成『作为负债的行』:当前的传统认知是如此荒谬以至于账都分错了。 249 | > — [艾兹赫尔·韦伯·戴克斯特拉](https://baike.baidu.com/item/%E8%89%BE%E5%85%B9%E6%A0%BC%C2%B7%E8%BF%AA%E7%A7%91%E6%96%AF%E5%BD%BB/5029407)(荷兰语:Edsger Wybe Dijkstra),计算机先驱、1972年图灵奖获得者、ACM PODC(分布式计算原理)最具影响力论文奖 即『Dijkstra奖』 250 | > 251 | > My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger. 252 | > — Edsger W. Dijkstra 253 | > 254 | > 艾兹赫尔·戴克斯特拉(Edsger Wybe Dijkstra,1930年5月11日-2002年8月6日)曾在1972年获得过素有计算机科学界的诺贝尔奖之称的图灵奖,之后,他还获得过1974年AFIPS Harry Goode Memorial Award、1989年ACM SIGCSE计算机科学教育教学杰出贡献奖。2002年,在他去世前不久,戴克斯特拉获得了ACM PODC(分布式计算原理)最具影响力论文奖,以表彰他在分布式领域中关于程序计算自稳定的贡献。为了纪念他,这个每年一度奖项也在此后被更名为『Dijkstra奖』。他曾经提出『GOTO有害论』信号量和PV原语,解决了有趣的『哲学家就餐问题』。 255 | 256 | - 代码是负债,越少越好! 257 | - 解决用户问题的产品才是资产! 258 | - 不写代码,就能解决用户问题是最牛的! 比如 259 | - 理解和优化需求;发现是个不合理的需求不用做了 260 | - 通过产品功能的组合或配置不用写实现代码 261 | - 复用已有的实现(往往需要更好的设计) 262 | - …… 263 | 264 | 内容也发到了[微博](https://weibo.com/1836334682/JuCn9cmNu)上。 265 | 266 | ## 伟大的库 - 2020-11-05 267 | 268 | > 甲骨文:有史以来最伟大的25个Java应用程序-InfoQ https://www.infoq.cn/article/BtfTSYFwvyzDNf4VWVpp 269 | 270 | - 有些是 曾经辉煌的库/程序 271 | - 有些是 底层基础却默默无闻的库/程序 272 | - 看了这样的库,有些些热泪盈眶,哈哈 273 | 274 | ## 表达与咨询 - 2020-10-30 275 | 276 | - 职场表达,你不能没有的套路 https://www.sohu.com/a/281321246_684517 277 | - 278 | - SCQA模型(归纳总结) https://www.jianshu.com/p/b946e06c9fa9 279 | - 280 | - 这个 栗子太匹配了 :") 281 | - 麦肯锡套路之 MECE 原则 https://www.sohu.com/a/275210270_99950394 282 | 283 | ---------------------------------------- 284 | 285 | > 相信自己没病的病人是没法治的,但咨询第一定律说的就是他们从来不会承认自己有病。 286 | > 287 | > 这下顾问就有大麻烦了。 288 | > 289 | > 一种变通的办法就是赞同客户很能干,然后问问是不是有什么可以改进的地方。没几个人愿意承认自己有病,但大多数人愿意承认能够有所改进,除非这人真的病入膏肓了。 290 | > 291 | > 注意不要由于急切地想要得到工作而表现得太过火。如果你承诺的改进太多,客户根本就不会聘用你,因为这会迫使他们承认自己有问题。 292 | > 293 | > 咨询第一定律的一个*推论*就是百分之十承诺定律: 294 | > 295 | > 永远不要承诺百分之十以上的改进。 296 | > 297 | > 大多数人可以把百分之十的改进归为心理上“没问题”一类。但如果顾问改进得再多,就有点让人难堪了。 298 | > 299 | > *百分之十*的解决方案 300 | > 301 | > 另一个推论是百分之十解决方案定律: 302 | > 303 | > 如果不小心让改进超过了百分之十,要确保没人注意到它。 304 | > 305 | > 确保没人注意到的最好方法,当然就是把它们都归功于客户。不会掩饰自己巨大成功的顾问就像用餐巾擦鞋的客人一样,主人不会再请他们了。 306 | > 307 | > 《咨询的奥秘》 308 | > https://book.douban.com/subject/25785829/ 309 | 310 | 有趣 又 很真实的样子 :") 311 | 312 | ## 单位引起的故障及其应对实践 - 2020-10-29 313 | 314 | > 315 | > 316 | > 阿里巴巴 API单位误解造成的严重故障 林昊 阿里巴巴 2014 317 | > https://myslide.cn/slides/17570 318 | 319 | 可以不同的 实践 解法,如 320 | 321 | 1. 变量名 有带单位`int periodMs` 322 | - 需要更多人力来执行保证 323 | 2. 使用时长类型`Duration` 324 | - 解法本身是 优的,且有类型安全 325 | - 但这个做法 使用上比较重,想想多的`Duration`的构造代码,这点弊端 语言本身(语法糖)可以辅助解决,如`C++ 11/14`、`Scala`有语法糖支持。 326 | 327 | 328 | 329 | ## 你又在滥用继承!继承不是为了复用代码,而为了被复用 - 2020-10-20 330 | 331 | > 332 | > 333 | > OOP - Back2Basics - CppCon 2019 by JonKalb 334 | > 335 | > Public inheritance is substitutability. 336 | > Inherit, not to reuse, but to be reused. 337 | > 338 | > — [C++ Coding Standards](https://www.oreilly.com/library/view/c-coding-standards/0321113586/ch38.html): 101 Rules, Guidelines, and Best Practices 339 | 340 | 翻译: 341 | 342 | - 外部接口是可替换性(`substitutability`)。 343 | - 继承不是为了复用代码(面向实现者),而为了被复用(面向使用者)。 344 | 345 | 个人解读: 346 | 347 | - 继承不是为了复用代码: 348 | - 以实现者/提供者出发的视角,认为『继承手段』会带来后面复用的好结果。 349 | - 至于真的有没有复用起来,没有被关心与回答:将来可能吧?~继承提供复用可能,多COOL! 350 | - 而是继承为了被复用: 351 | - 以使用者/消费者出发的视角,认为要被复用,有了『复用的需求』,通过继承手段组织与实现复用。 352 | - 这样先要求实现者使用继承时,要明确清楚复用的场景,因为『复』用 肯定清楚是『多个』业务场景是如何使用。 353 | - 自然往往进一步要说明:为什么这个场景是有复用基础的,复用部分为什么是抽象相同的;继承的父类名还为这个抽象相同的概念取了个名字。 354 | - 使用继承所带来的成本并不低: 355 | - 概念的增加,理解成本的增加,代码层次与代码量的增加,等等等等 356 | - [脆弱的基类问题](https://zhuanlan.zhihu.com/p/265736406):兼容的成本与问题、实现时的小心翼翼、可能的实现继承的`Bug`、等等等等 357 | 358 | 讨论: 359 | 360 | - 能带来我们期望的代码复用 是 接口所代表概念有可替换性(接口的实现可被替换)、模型设计,不是 继承 这个手段实现替换性的手段。 361 | - 将继承这个手段用于代码复用,结果是一个不能理解的杂乱四不像,不敢改也改不得(如 [脆弱的基类问题](https://zhuanlan.zhihu.com/p/265736406))。 362 | 363 | PS: 364 | 历年CppCon资料的Github Org: https://github.com/CppCon 365 | https://github.com/CppCon/CppCon2019 366 | 367 | ## `ConcurrentMap`/`ConcurrentHashMap`的`computeIfAbsent`只执行一次吗? - 2020-10-12 368 | 369 | 1. `ConcurrentMap`接口的`default`实现,**没有**保证`function`只执行一次: 370 | ![image](images/122046774-e663d400-ce11-11eb-97f7-a261ac338142.png) 371 | - `ConcurrentMap`默认实现是检查`putIfAbsent`后的结果 372 | - 如果返回`null`说明自己`putIfAbsent`成功了 373 | - 如果返回其他,说明是别人成功了,那么就直接返回别人的结果,放弃自己`compute`的结果。 374 | 2. `ConcurrentHashMap`实现类强化,保证`function`只会执行一次: 375 | ![image](images/122045887-d3043900-ce10-11eb-9988-556d714e138c.png) 376 | - `ConcurrentHashMap`里面的`putIfAbsent`根据`key`的`hash`通过分段锁来同步,只有一个人能`put`成功。 377 | 378 | 379 | ## 面向对象/过程化程序设计、依赖策略 - 2020-10-10 380 | 381 | ![](images/122047539-dac4dd00-ce12-11eb-9415-7dc2ddfb3fd9.jpg) 382 | 383 | 使用传统的过程化程序设计所创建出来的依赖关系结构,策略是依赖于细节的。 384 | 这是糟糕的,因为这样会使策略受到细节改变的影响。 385 | 386 | 面向对象的程序设计倒置了依赖关系结构,使得细节和策略都依赖于抽象,并且常常是客户拥有服务接口。 387 | 388 | 事实上,这种依赖关系的倒置正是好的面向对象设计的标志所在。 389 | 使用何种语言来编写程序是无关紧要的。 390 | 391 | 如果程序的依赖关系是倒置的,它就是面向对象的设计。 392 | 如果程序的依赖关系不是倒置的,它就是过程化的设计。 393 | 394 | 依赖倒置原则是实现许多面向对象技术所宣称的好处的基本低层机制。 395 | 396 | 它的正确应用对于创建可重用的框架来说是必须的。 397 | 同时它对于构建在变化面前富有弹性的代码也是非常重要的。 398 | 由于抽象和细节被彼此隔离,所以代码也非常容易维护。 399 | 400 | ## Statistical Thinking - 2020-09-16 401 | 402 | > Statistical Thinking 403 | > https://www.youtube.com/watch?v=OJt-k9h9pmk&list=PLRKtJ4IpxJpBxX2S9wXJUhB1_ha3ADFpF 404 | > 405 | > 统计的视频列表,作者是google决策智能小组的TL 406 | 407 | - 非常赞,几分钟就讲好了统计的很多元问题概念/特征,深入浅出 408 | - 比我之前看N本书收获还大 409 | 410 | 411 | 个人的学习的简单理解: 412 | 413 | - 什么是统计/Statistics? 414 | - Change your mind 415 | - Get your answner *with UNCERTAINTY* 416 | (特征是有 UNCERTAINTY,有不确定性) 417 | - 如果得到的是确定结论,如 418 | - 小鱼缸里有*4*条*金鱼*,数出来,是金鱼,你有100%确定性 419 | - 你是在分析推演(数数、认识是金鱼) 420 | - 什么时候用统计? 421 | - 对于简单结论(Which's Your Best Guess),你的直觉往往就很好使,不需要统计。 422 | - 对于那个结论要好多少(定量)时,就要用统计工具了,直觉不好使了。 423 | - 定量分析,是为了保证你的ROI: 424 | - 不同决策有不同的投入 425 | - 从做的N次决策中积累出更好收益 426 | 427 | PS:个人的对『统计』的简单理解: 428 | 429 | - 大系统复杂性往往不可能了解到足够的信息来做分析推理(因为系统组件太多、因为时间不够……)。 430 | - 复杂系统的理解、处理的方式往往 是 实验验证、归纳, 431 | - 把系统当作黑箱,用实验捅一捅,看看反应结果,归纳系统的反应特征。 432 | - 我们写个测试Case 看看,其实就是实验捅一捅。如果测试能通过,我们对系统信心就增加一些。 433 | - 实验(验证)是科学(方法论)的特征。(*实证*) 434 | 统计(应用学科)是 实验学科是基础,概率论(理论学科)是统计的基础。 435 | - 另一面,我们做系统的模型设计 是 基于 推演的分析 (*心证*,与 实验/归纳/统计 对应) 436 | 437 | ## 近义多个的概念名 - 2020-09-08 438 | 439 | > 当你问代理机制的时候?指的是Agent,Proxy,Broker还是Delegate呢? 440 | > https://mp.weixin.qq.com/s/-YD50VWHXobDm8VqTDOBYg 441 | 442 | 当你问代理机制的时候?指的是`Agent`、`Proxy`、`Broker`还是`Delegate`呢? 443 | 代理,英文有4个词(概念分析),中文用词少区分度 低 :") 444 | 445 | 类似,中文说的 缓存 英文有2个词,`buffer`、`cache`, 446 | 一般2者的区别是什么? 447 | 感觉有时候,英文也在混用。操作系统里,这2个词区分 明显些。 448 | https://stackoverflow.com/questions/6345020/what-is-the-difference-between-buffer-vs-cache-memory-in-linux 449 | 450 | ### 大家的讨论 451 | 452 | - Mr. X: 453 | - buffer 缓冲、cache 缓存 / 缓'从'(视各地口音而定) 454 | - Reply By `@oldratlee`: 455 | - 口音?投资 vs 投机,是吧? O_o 456 | - Mr. Y: 457 | - 简单理解,buffer是写的,cache是读的 458 | - Reply By `@oldratlee`: 459 | - 我可以理解成 buffer 的数据 不能改写? 460 | - Mr. G: 461 | - 强调的特性不同,buffer强调写的时候缓冲写入量的特性,肯定也会被读出,cache是强调读的时候的命中率,肯定也有写入过程,但不是重点 462 | - Reply By `@oldratlee`: 463 | - Cache 和 Buffer 都是缓存,主要区别是什么? - 知乎 464 | https://www.zhihu.com/question/26190832 465 | ![88F5E842-B8C8-4894-AF3E-64F914B24A4D](images/122066128-0cdf3a80-ce25-11eb-8896-0cbb9c7dfb2c.png) 466 | - 如果 按这个理解 , buffer cache 就可以 组合了。 467 | - cache 就用 加速(2份数据,当然就引入 一致性的问题,cache invalidation ,计算机的2大难题 之一) 468 | - buffer (IO)流量整形(自然 一般不能 会改写,除非 切成 Cache模式) 469 | - Buffer 用了不释放, 接着当 Cache用, 这样的使用 就是 Buffer-Cache 了 470 | 注: 顺序是有意义的, 有 Buffer-Cache ,没有 Cache-Buffer ,:") 471 | - 感觉 , 里面的数据 能不能 改写,是一个区分 Buffer/Cache 2者的特征。 472 | - Mr. K: 473 | - 有Buffer-Cache这样的场景吗,一下没想到,这两一起合用挺奇怪的 474 | - Reply By `@oldratlee`: 475 | - os里有的,极致优化的结果 476 | - Mr. S: 477 | - buffer 和 cache 的命名 是从功能特征出发的,从功能职责出发的,区分自然也在功能职责上 478 | - Mr. B: 479 | - 从另一个角度来说,buffer是解决读写速率不一致的产物,所以我说翻译中带了个‘区’ ,也就是buffer zone 。cache主要用来提高读/写速率的产物。 区别还是很大的 480 | - Mr. F: 481 | - 个人理解:buffer是缓冲,逻辑概念,用于减震 ;cache是缓存,物理概念,用于高低速设备之间,提高IO性能 482 | - 理论上慢速设备也可以用来做buffer,比如kafka队列 483 | 484 | ## 整洁的架构/编程范式 - 2020-08-28 485 | 486 | - (纯)函数式编程/FP 约束/限制/规范化/纪律化(discipline) 成 487 | 不变/修改 mutation (或说 赋值 assignment),只用不可变 immutable 488 | - 面向对象 OOP 纪律了 函数指针间接,只有 多态。让 代码依赖 与 执行依赖反转(即 模块化) 489 | - 结构化编程 纪律了 控制跳转,不用goto 只用 条件/循环。 490 | 491 | bob的《整洁的架构》 整个 Part 1 编程范式 讨论上面的内容。 492 | 简介有bob视频 493 | https://youtu.be/P2yr-3F6PQo 494 | 495 | ## 并发 - 2020-08-28 496 | 497 | > Posted by Mr. G 498 | 499 | 刚才和`@oldratlee`讨论并发情况下“原子性”问题,“原子性”代表的是不可分割并整体并付,或者在并发环境中会发生非常奇怪的不可预测的问题。 500 | 501 | 举个上传的例子,我们假设有个功能是上传文件大小和分片大小是可以调整的,通过配置中心发布,处理上传的线程会读取这个配置来修改上传的策略,我们会设计两个全局变量`fileSize`、`chunkSize`,当我们通过配置中心发来更新这两个值时会发生什么呢?: 502 | 503 | - 假设当前的fileSize=10M, chunkSize=5M; 504 | - 这次变更调整的目标是fileSize=4M,chunkSize=2M; 505 | - 由于并发的原因,会出现更新线程修改到fileSize=4M, chunkSize=5M; 506 | - 而上传处理线程读取到4M的临界判断,又同时读到了5M的chunkSize,再这之后变更线程才修改chunkSize=2M;上传处理线程就会用fileSize=4M, chunkSize=5M这样一个古怪的组合处理上传逻辑,造成无法预料的结果。 507 | 508 | 这里的本质是“原子性”是什么,`{fileSize, chunkSize}`应该被一齐交付,我们会设计一个UploadPolicy的类,包括`{fileSize, chunkSize}`两个属性,配置更新时创建一个临时的UploadPolicy对象,完成属性的设置,再一次赋值给全局变量,这样上传线程就会取到一个“原子性”的变更,避免上面的问题。这个问题还可以更深入到一次处理流程的一致性上,是个非常常见的问题。 509 | 510 | 推荐《Java并发编程实战》,经典书籍。值得仔细研究,反复推敲和实践。讲了原子性,可见性,不变性,逸出这些非常本质的问题。还包括了java的内存模型。 511 | 512 | ### 大家的讨论 513 | 514 | - [`@zavakid`](https://github.com/zavakid): 515 | - 作者之一是 Doug Lee 大牛, java 的 内存模型 和 JUC 包 就是他的作品。 (还有在 Java9 引入的 reactive Flow API 也是 Doug Lee) 516 | - Mr. M: 517 | - jdk里面atomicreference是专门解决这类问题,普通的变量直接替换,假设filesize和chuncksize是不同线程检查,还需要volatile保障可见性,要mesi协议来解决硬件跨cpu缓存的问题。 518 | - Mr. D: 519 | - 这个场景用不可变性应该能完全避免race,比如在上传session创建的时候把这种只读配置拉一份副本。 520 | - Reply By Mr. G: 521 | - 本质是更新的原子性,引用时的不可变性 522 | - `@oldratlee`: 523 | - 自己整体的书单:Concurrency/Parallelism/并发/并行 524 | https://www.douban.com/doulist/41916951/ 525 | - 自己整理的简单并发问题的可运行复现的Case工程: 526 | https://github.com/oldratlee/fucking-java-concurrency 527 | - 🎏 Simple show cases of java concurrency problems, seeing is believing. 528 | - 并发程度设计在分析和实现中,复杂度大大增加。 如果不系统理解和充分分析并发逻辑,随意写代码,这样的程序用 『碰巧』 能运行出正确结果 来形容一点都不为过。 529 | 这里的Demo没有给出解释和讨论,并且都是入门级的,更多了解请参见一些并发的问题讨论和资料。 530 | - 通过Java体系地学习并发之后,发现我自己不敢写C/C++的并发代码了, 531 | 自己之前写得都没有经过并发正确性的证明(都是在『碰巧』运行对),因为对C/C++栈下的并发构件的了解不够。 532 | - 体系学习推荐 533 | - 《Java并发编程实战》 534 | 实战与理论并重,第16届Jolt大奖提名图书,Java应用并发编程圣经级图书。 535 | 力荐!力荐!!力荐!!! 536 | 实用实践和不那么逻辑化,体系学习的ROI是最高的。 537 | - 《Java并发编程:设计原则与模式》 538 | Doug Lea大神20多年前的著作(原版第一版1996年出版),思考、方法论和原理是不变的,现在看起来一样有着*恐怖的震慑感*。 539 | - 《多处理器编程的艺术》 540 | 理论硬核的书,两位作者在2004年获得了理论计算机领域最高奖——哥德尔奖 541 | - 并发编程模式的广度了解 542 | - 七周七并发模型 543 | - Java虚拟机并发编程 544 | - Scala并发编程 545 | 546 | ## 软件设计书籍 - 2020-08-19 547 | 548 | - 《整洁的架构》 549 | - SOLID五大经典原则的阐述,可以结合另一本书看《敏捷软件开发 : 原则、模式与实践》, 从原则->模式->实践。经典神作,2002的书,过去快20年了。 550 | 1. 软件设计与(OOP)语言无关 551 | 2. 书名趁当年 赤热『敏捷』话题 552 | 3. 现在要看 副标题 PPP(Principles, Patterns, and Practices,软件开发的原则、模式与实现) ,典型不过时 553 | 554 | ## 模块形状(深/高瘦程度)作为抽象/系统设计/建模的好坏的判断 - 2020-08-07 555 | 556 | 做了[`compileflow`开源项目的代码review](../compiler-flow-code-review/README.md)。 557 | 558 | 其中一部分是[系统设计](../compiler-flow-code-review/README.md#3-系统设计)的内容: 559 | 560 | `exception`、`contants`、`model`、`(error)code`这样的包 司空见惯 的 不好实践,个人觉得…… 561 | 562 | - 面向技术独立包 会导致 563 | 与业务域(要解决的问题)关联不强的孤立技术类。 564 | 这样的代码孤立感来自:与使用它的对应域的类远了,域代码文件没有一目了然地排在一起。 565 | - 『因为按技术划分,看起来包下的类变少了,往往隐藏了 业务域的下拆不足,即影响领域拆分梳理优化。』 566 | 567 | 《软件设计哲学》里的 深模块 的概念非常好: 568 | 抽象/系统设计/建模的好坏 通过 模块形状(深/高瘦程度)来判断。 569 | ![](../compiler-flow-code-review/images/05.png)。 570 | 571 | Review过程中,讨论到了[扩展设计 的实践](../compiler-flow-code-review/README.md#32-扩展设计)(如 是否要 spi包名)。 572 | 573 | > 《A Philosophy of Software Design》 574 | > https://book.douban.com/subject/30218046/ 575 | > 出版年: 2018-4-6 576 | > 577 | > 这本书 看了一些,觉得确实 名符其实。 578 | 579 | ## Unknown is Unknown! - 2020-08-24 580 | 581 | - 平时很多时候有『不知道』的状态,把`Unknown`处理成`False` 或 `not Unknown`处理成True,实现逻辑的问题就来了。 582 | - 这类的Bug在线上系统看得到不少。 :") 583 | - 也可以理解成『其他』情况,说明 自己模块的建模是不完备的: 584 | - 有些情况 *不是* 自己能处理的。 585 | - 要代理 到 系统上层 才能处理,做Fallback。 586 | - Fallback往往处理成:就好像没有这个模块一样。 587 | 588 | > Wikipedia: Three-valued logic, Kleene and Priest logics 589 | > https://en.wikipedia.org/wiki/Three-valued_logic#Kleene_and_Priest_logics 590 | > 591 | > ![](images/2021-06-29-15-52-27.png) 592 | 593 | ## Reactive programming: lessons learned - 2020-06-01 594 | 595 | > JDD 2018: Reactive programming: lessons learned by Tomasz Nurkiewicz 596 | > https://www.youtube.com/watch?v=5TJiTSWktLU 597 | > 598 | > 最近在JVM上,协程已成为反应式编程(Reactive Programming)的一种替代方法。诸如RxJava或Project Reactor之类的框架为客户端提供了一种增量处理传入信息的方式,并且对节流(throttling)和并行(parallelism)提供了广泛的支持。但是,必须围绕反应流(reactive streams)上的函数式操作(functional operations)来重新组织代码,在很多情况下这样做的成本是高过收益的。 599 | > 600 | > ![](images/2021-06-29-20-12-27.png) 601 | > 602 | > PPT: https://nurkiewicz.github.io/talks/2018/reactive-lessons/ 603 | 604 | 提到了好几个 观点与概念: 605 | 606 | 1. Netflix point(高伸缩代码实现相对低实现 的 收益 交叉点) 607 | 2. 软件成本的组成及其变化趋势 ( hardware/software dev/maintenance) 608 | 3. 团队的代码标准 : boring vs. interesting 609 | 610 | 我们 这么业务的做法, 有到 『奈飞点』 了吗? 611 | 612 | - 大象 会 跨过 『奈飞点』 613 | - 一群 *自治*的 蚂蚁,看起来是个 大象,却不是。 614 | 615 | ## 每当我想放弃`Scala`,我就写写`Python`和`Java` - 2020-05-08 616 | 617 | > 每当我想放弃`Scala`,我就写写`Python`和`Java` - InfoQ 618 | > http://m.vlambda.com/wz_7izXvEgXpko.html 619 | > By Li Haoyi 620 | > 621 | > 对我来说,`Scala`语言本身处于一个相对良好的状态。花一整个下午的时间编写现代`Java`代码就足以让我摆脱“其他编程语言已经迎头赶上`Scala`”的想法,花了几天时间尝试(最终并未成功)将`Python`项目打包成一个独立的可执行文件也是如此。 622 | > 623 | > `Scala`未来最大的潜力在于发展新的用户群,以及寻找新的应用场景,到目前为止,这些都完全不在社区的考虑范围内。但在我看来,有两件事很重要。 624 | 625 | 作者说得很理性,同时字里行间也能感受到作者对`Scala`的热情~ 626 | 特别是能感受到给社区的提醒:虽然(前几年)推广造势的不错,但在 易用性 和 增加使用场景 上需要多费心,这才是基础! 627 | (作者在应用层的易用性上可以说做了很多事情) 628 | 629 | 而 易用性(使用成本) + 使用场景多 都是做规模化的思路之二~ 630 | 631 | `Kotlin`也是在这两个方面想做好,特别是易用性方面,能感受到`Kotlin`在 易用性 和 语言特性 上所做的权衡。 632 | (我相信想要做出类似`Scala`或者其他语言的特性,对于`JetBrains`这帮人 基本不是挑战~) 633 | 634 | Posted By [`@zavakid`](https://github.com/zavakid) 635 | 636 | ### 大家的讨论 637 | 638 | - `@oldratlee`: 639 | - 提升易用性、扩宽应用场景,确实是 产品发展和打法的关键 640 | 641 | ## 业务价值体感化的套路模式 - 2020-05-02 642 | 643 | - 录屏,效果变化体感 644 | - 出问题的`App`样子,截屏 645 | - 用户的反馈、舆情 646 | - 将技术指标转化成业务表达、效果提升 647 | - 如转化成活跃用户的规模增长、单位时间成交转化率的提升 648 | 649 | ## 基础设计理念的持续滚动成为代差 - 2020-05-01 650 | 651 | > 关于spring的作者 652 | > 653 | > spring的缔造者Rod Johnson。这位仁兄很牛,出生于澳大利亚,毕业于悉尼大学计算机系。到这还是平平无奇,但是他还有另一个身份,音乐学的博士。因为自己爱好音乐,便攻读了音乐学的博士。果然编程的极致是艺术,而艺术相通的。 654 | > 655 | > 「spring」Spring的前世今生,作者与由来 656 | > https://baijiahao.baidu.com/s?id=1620099105315862154 657 | 658 | - 好的基础设计理念,初看不起眼,坚持持续滚动迭代会出代差。 659 | - 依赖注入(`DI`/`IOC`)和`AOP`,把`EJB`打得满地找牙! 660 | 661 | ## 事实和观点 - 2020-04-30 662 | 663 | > 事实和观点 664 | > https://www.jianshu.com/p/5157faf3a6b5 665 | > https://www.jianshu.com/p/06f4347e94ac 666 | 667 | 在《批判性思维》作者提到培养独立思考的能力的方法,其中之一就是能够甄别观点(opinion)和事实(fact)。 668 | 669 | - 什么是事实? 670 | - 就是在客观世界中可以被证实或者证伪的就是事实,就是能分清真假 671 | - 比如说今天气温30度。 672 | - 什么是观点? 673 | - 就是在一套认知体系中,不违反事实,逻辑自洽,无法证明真假的东西。 674 | - 比如今天很热 675 | - 是否 可证伪 是 科学 和 事实 两者的特征。 676 | - 有了这个特征,想到这句话:『科学尊重事实』 677 | - 其实是个 循环定义,这句话 没信息量。 678 | - 『可证伪』这个特征 是 信息量。 679 | 680 | ## `Lombok`与语法糖 - 2020-04-28 681 | 682 | > `Lombok`是让你代码处于“亚健康”状态的真正元凶 683 | > https://blog.csdn.net/xhmj12/article/details/107053672 684 | 685 | 文章提到的几个点,分开说: 686 | 687 | 1. `Lombok`的简化思路 688 | - 如果`data class`合理的前提下,简化代码&更好的表意 思路是对的。 689 | - 毫无疑问,`Kotlin`这一块 吊打`Lombok`,当然后面提到的评估决策要做得更多。 690 | 2. 升级的问题 691 | - 对于一个库,升级`JDK`不能用了是这个库的一个致命问题;合格上心的库作者应该要做好。 692 | - 对库使用者,关注库的兼容性,并有适度的容忍期限也是应该的。 693 | - 如升级能有些回归;能等待一段时间让库作者修复问题。 694 | 3. 学习&理解成本 695 | - 任何东西都有学习成本。 696 | - 决策者根据情况(如团队成员、项目特点)有个评估判断。 697 | 698 | > 对库使用者,关注库的兼容性,并有适度的容忍期限也是应该的。 699 | 700 | 这句话里我想说的,更积极直白的表述是: 701 | 702 | - 使用者 不去改进贡献也算正常 703 | - 但至少要少一些『得好处忘掉、有了不爽就diss』还觉得这样心安理得的伸手党心态 704 | 705 | ## 《程序员修炼之道》 - 2020-04-16 706 | 707 | 《程序员修炼之道》出[第二版](https://book.douban.com/subject/35006892/)了! 🤘 🚀 708 | 709 | 这本书,在我个人的软件职业专业与水准的书籍中,排名第一。 710 | 711 | 薄薄的300多面,讲了软件专业与职业的N个维度: 712 | 713 | - 文档(以及写作)、测试、编码、系统设计/抽象、编程语言… 714 | - 日常工具:命令行、编辑器、版本控制… 715 | - 交流表达、项目管理/团队管理、认知规律、批判思考… 716 | - 职业态度、知识投资… 717 | - …… 718 | 719 | 奔流着 专业洞见、深度思考,个人无以复加的推荐! 720 | 721 | 『程序员应该一年学一门语言』这个观点出自这本书。 722 | 723 | 记得自己读大学时在图书馆借了看过,当时心里想:讲了些什么玩意儿;几乎没一点收获和共鸣。 724 | 后来工作实践多年,再买了读,惊了。 725 | 726 | 所以个人对这本书评价: 727 | 728 | 这本书是个人软件专业素养的**试金石**。即 729 | 如果看了反应共鸣不多,则自己的专业素养有待提升。 730 | 731 | 当然,要理解别人的洞见是以个人自己积累的实践与思考为前提。 732 | 733 | ## 代码设计 - 2020-04-16 734 | 735 | - 用`boolean`返回值 来做为 操作成功/出错的指示 736 | - 对于永远返回`true`的实现,往往是漏掉了出错汇报、实现有Bug! 737 | - 需要文档(用`JavaDoc`)说明上 这个方法的出错 契约 738 | - 对于 出错汇报,如果可能,一般推荐 用异常,而不是错误码(`Java`的常用最佳实践) 739 | - 命名 几乎是 系统建模的全部体现。 740 | - 即 命名不达意,是 整体设计问题 741 | - 软件实现/设计 最难的2件事: 742 | 1. 命名:背后是 系统建模 743 | 2. 缓存失效:背后是 并发 744 | 3. 偏1误差:背后是 算法/过程的表达 745 | -------------------------------------------------------------------------------- /broken-thoughts/README.md: -------------------------------------------------------------------------------- 1 | # 软件实践碎碎念 - 2021 2 | 3 | > 往年: 4 | > 5 | > [软件实践碎碎念 - 2020](2020.md) 6 | 7 | ---------------------------------------- 8 | 9 | 10 | 11 | 12 | 13 | - [我的能力真的达到了吗? - 2021-07-15](#%E6%88%91%E7%9A%84%E8%83%BD%E5%8A%9B%E7%9C%9F%E7%9A%84%E8%BE%BE%E5%88%B0%E4%BA%86%E5%90%97---2021-07-15) 14 | - [个人讨论](#%E4%B8%AA%E4%BA%BA%E8%AE%A8%E8%AE%BA) 15 | - [一切都应该自顶向下构建,除了第一次 & 不要机械执行 - 2021-06-25](#%E4%B8%80%E5%88%87%E9%83%BD%E5%BA%94%E8%AF%A5%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8B%E6%9E%84%E5%BB%BA%E9%99%A4%E4%BA%86%E7%AC%AC%E4%B8%80%E6%AC%A1--%E4%B8%8D%E8%A6%81%E6%9C%BA%E6%A2%B0%E6%89%A7%E8%A1%8C---2021-06-25) 16 | - [个人讨论](#%E4%B8%AA%E4%BA%BA%E8%AE%A8%E8%AE%BA-1) 17 | - [为什么程序员大多不写测试,`Happy Path Developer`(`HPD`)? - 2021-06-20](#%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A8%8B%E5%BA%8F%E5%91%98%E5%A4%A7%E5%A4%9A%E4%B8%8D%E5%86%99%E6%B5%8B%E8%AF%95happy-path-developerhpd---2021-06-20) 18 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA) 19 | - [PD、产品思维 - 2021-06-20](#pd%E4%BA%A7%E5%93%81%E6%80%9D%E7%BB%B4---2021-06-20) 20 | - [软件架构 + 微积分 - 2021-06-19](#%E8%BD%AF%E4%BB%B6%E6%9E%B6%E6%9E%84--%E5%BE%AE%E7%A7%AF%E5%88%86---2021-06-19) 21 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-1) 22 | - [代码组织与测试 - 2021-06-17](#%E4%BB%A3%E7%A0%81%E7%BB%84%E7%BB%87%E4%B8%8E%E6%B5%8B%E8%AF%95---2021-06-17) 23 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-2) 24 | - [DOOM启世录 - 2021-06-17](#doom%E5%90%AF%E4%B8%96%E5%BD%95---2021-06-17) 25 | - [软件架构定律 - 2021-06-15](#%E8%BD%AF%E4%BB%B6%E6%9E%B6%E6%9E%84%E5%AE%9A%E5%BE%8B---2021-06-15) 26 | - [基于开源的商业模式 - 2021-06-15](#%E5%9F%BA%E4%BA%8E%E5%BC%80%E6%BA%90%E7%9A%84%E5%95%86%E4%B8%9A%E6%A8%A1%E5%BC%8F---2021-06-15) 27 | - [微信背后的产品观 - 2021-06-07](#%E5%BE%AE%E4%BF%A1%E8%83%8C%E5%90%8E%E7%9A%84%E4%BA%A7%E5%93%81%E8%A7%82---2021-06-07) 28 | - [统计 几何平均数 - 2021-05-29](#%E7%BB%9F%E8%AE%A1-%E5%87%A0%E4%BD%95%E5%B9%B3%E5%9D%87%E6%95%B0---2021-05-29) 29 | - [心智负担的游戏 - 2021-05-10](#%E5%BF%83%E6%99%BA%E8%B4%9F%E6%8B%85%E7%9A%84%E6%B8%B8%E6%88%8F---2021-05-10) 30 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-3) 31 | - [如何有效地设置系统报警? - 2021-04-24](#%E5%A6%82%E4%BD%95%E6%9C%89%E6%95%88%E5%9C%B0%E8%AE%BE%E7%BD%AE%E7%B3%BB%E7%BB%9F%E6%8A%A5%E8%AD%A6---2021-04-24) 32 | - [信噪比 - 2021-04-21](#%E4%BF%A1%E5%99%AA%E6%AF%94---2021-04-21) 33 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-4) 34 | - [依赖分析 - 2021-04-16](#%E4%BE%9D%E8%B5%96%E5%88%86%E6%9E%90---2021-04-16) 35 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-5) 36 | - [解题理念关键字/核心方法 - 2021-04-06](#%E8%A7%A3%E9%A2%98%E7%90%86%E5%BF%B5%E5%85%B3%E9%94%AE%E5%AD%97%E6%A0%B8%E5%BF%83%E6%96%B9%E6%B3%95---2021-04-06) 37 | - [多余的『用null初始化』 - 2021-04-02](#%E5%A4%9A%E4%BD%99%E7%9A%84%E3%80%8E%E7%94%A8null%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%8F---2021-04-02) 38 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-6) 39 | - [当你编码时,事物命名 - 2021-03-12](#%E5%BD%93%E4%BD%A0%E7%BC%96%E7%A0%81%E6%97%B6%E4%BA%8B%E7%89%A9%E5%91%BD%E5%90%8D---2021-03-12) 40 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-7) 41 | - [`SICP`作者的新书《面向灵活性的软件设计》 - 2021-03-11](#sicp%E4%BD%9C%E8%80%85%E7%9A%84%E6%96%B0%E4%B9%A6%E9%9D%A2%E5%90%91%E7%81%B5%E6%B4%BB%E6%80%A7%E7%9A%84%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1---2021-03-11) 42 | - [迭代效率之于工程 2021-02-18](#%E8%BF%AD%E4%BB%A3%E6%95%88%E7%8E%87%E4%B9%8B%E4%BA%8E%E5%B7%A5%E7%A8%8B-2021-02-18) 43 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-8) 44 | - [公共知识 与 主动宣导 - 2021-01-29](#%E5%85%AC%E5%85%B1%E7%9F%A5%E8%AF%86-%E4%B8%8E-%E4%B8%BB%E5%8A%A8%E5%AE%A3%E5%AF%BC---2021-01-29) 45 | - [谷歌可靠性工程的设计经验 - 2021-01-21](#%E8%B0%B7%E6%AD%8C%E5%8F%AF%E9%9D%A0%E6%80%A7%E5%B7%A5%E7%A8%8B%E7%9A%84%E8%AE%BE%E8%AE%A1%E7%BB%8F%E9%AA%8C---2021-01-21) 46 | - [Magic Go Lang! - 2021-01-18](#magic-go-lang---2021-01-18) 47 | - [大家的讨论](#%E5%A4%A7%E5%AE%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-9) 48 | 49 | 50 | 51 | ---------------------------------------- 52 | 53 | 54 | ## 我的能力真的达到了吗? - 2021-07-15 55 | 56 | 内容来自 [`@MaJunFeng` 马俊锋(相伯) 老师](https://github.com/MaJunFeng) 57 | 58 | > ## 我的能力真的达到了吗? 59 | > 60 | > 人总是会有自我优越感,或者沾沾自喜,当某些想法或观点被提及时, 61 | > 自己会说:嗯,这个东西我想到过。或者说:这个道理我知道。 62 | > 63 | > 背后的潜台词都是: 64 | > 嗯,不错,我挺优秀的,这些东西我都 get 了。 65 | > 66 | > 但事实上,从人的潜意识里想到,到最终的外显让他人知道和理解,会涉及到一系列的活动: 67 | > 想到、知道、做到、讲到、写到。 68 | > 69 | > 而每一个活动到下一个活动都是一个巨大的漏斗和 gap,都需要不同的认知和能力。 70 | > 71 | > ![](images/2021-07-16-11-34-34.png) 72 | > 73 | > 你想到不代表你知道;你知道不代表你能做到;你做到不代表你葩讲出来;你能讲出来不代表你能写出来。 74 | > 75 | > 说了你又不听,听了你又不懂,懂了你又不做,做了你又做错,错了你又不认,认了你又不改,改了你又不服,不服你又不说! 76 | > 你要我怎么说你呢? 77 | > —— 电影《江湖》 78 | 79 | ### 个人讨论 80 | 81 | 马俊锋(相伯) 老师 给出了 能力 或 对一件事理解程度 的5个等级划分: 82 | 83 | 1. 想到 84 | 1. 知道 85 | 1. 做到 86 | 1. 讲到 87 | 1. 写到 88 | 89 | 你有没有这样的情形: 90 | 一个事自己躲在床上想想时,会觉得这事想通了可以搞起、价值非凡、BlaBla,进入激动不已的亢奋的状态。 91 | 后面和别人讲时,别人并没有生产共鸣与建立共识;在写时,更是漏洞百出发现不能自圆其说,自己又进入低落的状态。 92 | 93 | 经验常常会是这样: 94 | 一个事自己不经历几回亢奋低落的反复震荡,这事很有可能是不靠谱的。 95 | 96 | 对一件事理解程度等级一定要心里注意,想得激动不已 其实只不过是在 Level 1.5(介于想到与知道之间)。 97 | 98 | ## 一切都应该自顶向下构建,除了第一次 & 不要机械执行 - 2021-06-25 99 | 100 | > Everything should be built top-down, except the first time. 101 | > — Alan J. Perlis 102 | > 103 | > 一切都应该自顶向下构建,除了第一次。 104 | > — 艾伦·杰·佩利(程序设计领域的科学家,首届图灵奖的获得者) 105 | > 106 | > 下面的内容摘自《[恰如其分的软件架构 : 风险驱动的设计方法](https://book.douban.com/subject/24872314/)》 - CH11 封闭与分割: 107 | > 108 | > 109 | > 110 | > 好处在于认知(`cognitive`),而不在于技术。 111 | > 组件的划分/结构化、如何交互。 112 | > 113 | > 114 | > 115 | > 116 | > 117 | > - 自顶向下的设计 118 | > - 主分解的专横 119 | 120 | PS:《恰如其分的软件架构 : 风险驱动的设计方法》的内容由 [`beyondyuefei`](https://github.com/beyondyuefei) 提供。 121 | 122 | ### 个人讨论 123 | 124 | 关于『一切都应该自顶向下构建,除了第一次』,个人的换句话的理解: 125 | 126 | - 新主题(第一次设计)的设计实际上是自底向上设计完成的。而在整理成设计文档时,为了方便人脑理解,只是写成自顶向下的形式。 127 | - 如果你一上来就能自顶向下设计,是因为这样系统/领域你做过了,只是在重复一遍而已。相对第一次的而言,这样的重复,对于做的人提升是较少的。 128 | - 但是公司价值是更大的,公司希望的当然是能更快更好的解决问题带来商业价值。这也是公司会积极招有经验的人的原因,哪怕他是在重复地做一遍。 129 | 130 | > 131 | > 132 | > 谈封装过的组件或模块是没什么意义的,或者说我们想表达的是有效的封装(不多不少) 133 | 134 | 在聊抽业务语义化抽到业务对象的函数去,不要机械执行一直抽下去。 135 | 136 | - 新手就是这样,看到别人说好的就用,不知道什么该停止。 137 | - 想想我们新学习设计模式时,是不是会巴不得能用就用上,好高大上、肯定都对、屌。 138 | 139 | 知道『什么时候不用XXX』,是理解了XXX的一个判据。 140 | 141 | PS: 142 | 『不要机械执行』 这句来自像《重构》《敏捷软件开发》这样的书中,现在我还没有找到具体的位置了…… 143 | 后面找到了补上位置。 😓 144 | 145 | ## 为什么程序员大多不写测试,`Happy Path Developer`(`HPD`)? - 2021-06-20 146 | 147 | > 为什么程序员大多不写测试? 148 | > https://mp.weixin.qq.com/s/jzgOuDn2f173dioIalSm_A 149 | > 150 | > ![](images/2021-07-07-21-20-52.png) 151 | 152 | 前天讨论到代码逻辑完备性、软件测试,提到`Happy Path Developer`(`HPD`)。 153 | 可惜了,缩写不是更方便记忆与幽默的`PHD`。 154 | 155 | ### 大家的讨论 156 | 157 | - Mr. G: 158 | - 设计是为了降低复杂度的,当我们在做单元测试的时候,就仿佛作为一个使用者的角度去看,如果你觉得单元测试都写起来极其困难,就可以回头审视你的设计,是不是过度复杂。 159 | - 单测和做好设计往往被认为是影响效率的因素,很多人拿这个作为借口来不写单侧,单侧的好处会随着系统的复杂性不断的提升,对维护一个复杂系统的升级演变起到至关重要的提升效率的作用。 160 | - 单侧不做把验证的功能又一道研发的后段的集成测试上。如果我们当前日常环境的复杂性,整个研发交付的周期就被拉的非常长,更加痛苦。更悲剧的是你做好了单元测试,别人没做你一样被拖着。开发一天,集成7天。不写单测一时爽,痛苦更长时间。于是又变成研发的工作很没成就感,很痛苦。陷入一个流程的等待和协同中。 161 | - 这和,全链路压测的时候引入一大堆单链路就能验证的问题,一个道理。那些单链路就可以验证的问题放到全链路来搞,就会过分低效。全链路原本是验证大家共同作用的交叉系统,在并发访问情况下可能出现的影响。 162 | - `@oldratlee`: 163 | - 整体的事往往有系统性,容易短板效应。 164 | 165 | ## PD、产品思维 - 2021-06-20 166 | 167 | 这周刚拜读完《微信背后的产品观》;天猫原价才买到,否则缺货。 168 | 169 | 最近又补课一系产品的书: 170 | 171 | - 《[微信背后的产品观](https://book.douban.com/subject/35339729/)》 172 | - 《[从点子到产品](https://book.douban.com/subject/26927349/)》 173 | - 《[用户思维+:好产品让用户为自己尖叫](https://book.douban.com/subject/27129563/)》 174 | 175 | PS: PD书单 https://www.douban.com/doulist/41792144/ 176 | 177 | - 产品思维/用户思维 无处不在,有用、发人思考、能更好解决问题就是好猫。 178 | - 《用户思维+:好产品让用户为自己尖叫》个人被冲击太大。好的内容就是容易被人无视但又应该变成习惯的常识。 179 | 180 | ---------------------------------------- 181 | 182 | 微信之父张小龙内部100多页PPT,全面剖析微信背后的产品观: 183 | 184 | - 文字版 https://www.cnblogs.com/end/p/5521138.html 185 | - PPT图片版 https://www.163.com/dy/article/FQ230RUA051998SC.html 186 | - ![](images/122704841-16cec680-d287-11eb-994e-6863eef2e243.png) 187 | 作为可能的注意项看看/想想,挺有意思的 188 | - 今年1月张小龙出书了,《[微信背后的产品观](https://book.douban.com/subject/35339729/)》, 好薄 160面。 189 | 190 | ## 软件架构 + 微积分 - 2021-06-19 191 | 192 | > Posted By [`beyondyuefei`](https://github.com/beyondyuefei) 193 | > 194 | > 《[恰如其分的软件架构 : 风险驱动的设计方法](https://book.douban.com/subject/24872314/)》 - CH6 工程师使用模型: 195 | > 196 | > 我在就读高中时,曾经向父亲请教微积分作业。让我吃惊不已的是,尽管父亲从大学开始就在从工程师的工作,可他的微积分知识却很少被使用,早已生疏了。他还告诉我, 197 | > 198 | > - 他的公司雇佣掌握了微积分知识的工程师,并不是因为工作需要运用微积分, 199 | > - 而是因为他们接受的工程训练,其中包括微积分练习,锻炼了他们运用抽象与模型解决问题的能力。 200 | > 201 | > 202 | 203 | - 《架构整洁之道》讲的比较全面,但对《模型》等说的少,这本讲的多些,作者强调偏实战。 204 | - 《架构整洁之道》我印象深的一句是:『软件系统的核心是业务策略(顶层),其他都是实现细节。』 205 | - 由此我想到,以前`@oldratlee`说过的: 206 | - 做一件事的划分,对每一部分能判断的清楚,而不是一上来就说某个点(不想听)。 207 | - 关键的划分和判断 体现的是你对整体的把控,这个是我想听的,后面某个难点/单点 可以再单独来说。 208 | - 现在我就非常理解了:可以类比Bob大叔说的 顶层业务策略和实现细节。 209 | - [微积分/Calculus/数学分析/Analysis 书单](https://www.douban.com/doulist/119758751/),微积分主题的好书很多。 210 | - 日常工作对逻辑推理、抽象和模型解决问题的能力都经常涉及到,所以既然那书里提到了微积分,那就寻来看看/练练。 211 | - 模型:先明确解决什么问题、抽象层次、细节取舍、增强推理、数学很重要(复杂的问题)。 212 | 213 | ### 大家的讨论 214 | 215 | - Reply By `@oldratlee`: 216 | - 我再学习你的思考的这段话,细品了好几遍。反复直到进入血液成为习惯。 217 | - 微积分 是 宇宙的语言。 218 | - 『一个神秘且不可思议的事实是,我们的宇宙遵循的自然律最终总能用微积分的语言和微分方程的形式表达出来。』 —— [《微积分的力量》](https://book.douban.com/subject/35292688/) 219 | 220 | - 因为工作项目要使用或了解自动控制、机器学习这样的应用数学,自然就引导到这儿了,我们有空看看就好,相信神的语言 一定很美,哈哈 221 | - [数据物理方法/微分方程/傅里叶变换 书单](https://www.douban.com/doulist/140038243/) 222 | - 或许 懂微积分的同学看不懂的同学,和人看猴子是一样的。不可理解的超越,哈哈 223 | - 上面这句纯粹是我这个外行人的**YY** 🤤 😂 224 | 225 | ---------------------------------------- 226 | 227 | - 内容也发到了[微博](https://weibo.com/1836334682/JuCn9cmNu)上。 228 | 229 | ## 代码组织与测试 - 2021-06-17 230 | 231 | > How to organize your code? Organize code by concepts, not layers】http://t.cn/A6VnTnqF 232 | > 如何组织你的代码? 按概念而非层组织代码 233 | 234 | 或者说,按面向业务概念/域组织代码,而非技术特征(技术分层、`exception`、`constants`)。 235 | 236 | [`compileflow`开源项目的代码review 2020-08-02](../compiler-flow-code-review/README.md)的[系统设计](../compiler-flow-code-review/README.md#3-系统设计)一节里, 237 | 我也是重点说明、解释代码组织的问题: 238 | 239 | - 应该怎样做? 240 | - 为什么? 241 | 242 | ---------------------------------------- 243 | 244 | > [`compileflow`开源项目的代码review 2020-08-02](../compiler-flow-code-review/README.md)的[软件测试](../compiler-flow-code-review/README.md#43-软件测试)一节: 245 | > 246 | > ![image](images/122702815-c7869700-d282-11eb-9828-7f00ff271789.png) 247 | 248 | 如何写测试, 程序员专业素养的核心体现(之一)。 249 | 250 | - JUnit in Action, Third Edition 3rd Edition | December 8, 2020 251 | https://www.amazon.com/JUnit-Action-Third-Catalin-Tudose/dp/1617297046 252 | - 经典,去年出第三版了 253 | - 程序员专业素养 测试能力 的力荐之作 254 | - Test Driven Development: By Example by Kent Beck | Nov 18, 2002 255 | https://book.douban.com/subject/1230036/ 256 | - TDD 布道大成之作 257 | 258 | 259 | 260 | ### 大家的讨论 261 | 262 | - Mr. G: 263 | - 书虽然古老,但是技术非常实, 重构+单元测试, TDD 单测先行, 对开发的思路影响非常大。我们不是先写实现,而是设计了接口和方法后,先建立单测来确定每个方法的预期,编码需要通过每个单测。 264 | - 印象中还有个故事,是kent back他们在飞机上聊出来这个理念的。 265 | - 为了完备单测的工程体系,后面产生了JUnit、TestNG这类框架,又出现了JMock、Mockito这类的mock框架 266 | - 建立单侧去保障重构的可行性 267 | - Reply By `@oldratlee`: 268 | - 我个人还一直没实践上到『先写测试再写实现』的Level (还是自己没勤于实践) 269 | - 但背后的一个理念/原因:先想需求梳理接口,有实践一直坚持,并在过程中 持续 思考优化梳理 接口。 270 | - Reply By Mr. G:用单测来驱动强化了使用者的视角,让编码的同学清晰的知道别人会如何使用这个方法这个类;没有单测做为基础,重构就是空中楼阁;另外不要相信大型重构,那是重写,重构一定是小步骤的。 271 | - Reply By [`@zavakid`](https://github.com/zavakid): 272 | - 我也还没有…… 273 | - 但还是可以做到: 274 | 1. 一旦发现了问题或者 bug,可以通过写测试的方式,来杜绝下一次发现类似的问题,通过测试的方式,来确保项目永远不会产生同样的问题; 275 | 2. 在写单元测试碰到卡壳时,会反过来调整优化代码结构,让单元测试更容易编写:写单元测试的方便程度也是在反馈代码使用的难以程度。 276 | - 重写 vs. 重构,有问题要改动时,应该总是优先选择改动小的,也就是重构,小步重构,通过单元测试确保兼容性。 277 | 278 | ## DOOM启世录 - 2021-06-17 279 | 280 | > 《DOOM启世录》 https://mp.weixin.qq.com/s/a_No46xDB-zuZV-OM3plog 281 | > 282 | > 在信息时代,客观障碍已不复存在,所有的障碍都是主观上的。如果你想动手开发什么全新的技术,你不需要几百万美元的资金,你只需要在冰箱里摆满比萨和可乐,再有一台便宜的计算机,和为之献身的决心。我们在地板上睡过,我们从河水中趟过。 283 | > 284 | > —— DOOM启世录 285 | 286 | 《DOOM启世录》豆瓣9.3,相当热血的说。 287 | 288 | ## 软件架构定律 - 2021-06-15 289 | 290 | 《[Fundamentals of Software Architecture](https://book.douban.com/subject/34464806/)》将 trade-off(取舍权衡) 定律化了,还补了个反面重复表述的推论一,有意思: 291 | 292 | - 软件架构的一切都是取舍权衡。 — 软件架构第一定律 293 | - Everything in software architecture is a trade-off. — First Law of Software Architecture 294 | - 如果架构师认为他发现有的事不是取舍权衡,那么更可能是他还没有识别到需要的权衡。(译注:给将来留坑了……) — 推论一 295 | - If an architect thinks they have discovered something that isn’t a trade-off, more likely they just haven’t identified the trade-off yet. — Corollary 1 296 | - WHY 比 HOW 更重要。 — 软件架构第二定律 297 | - Why is more important than how. — Second Law of Software Architecture 298 | 299 | PS: 2021-6-6 刚出了中文版《[软件架构:架构模式、特征及实践指南](https://book.douban.com/subject/35487561/)》 300 | 301 | ---------------------------------------- 302 | 303 | - 内容也发到了[微博](https://weibo.com/1836334682/KkhYdCDo3)上。 304 | - [软件架构/Architecture/架构师 书单](https://www.douban.com/doulist/112308024/) 305 | 306 | ## 基于开源的商业模式 - 2021-06-15 307 | 308 | 如果核心代码开源(为了竞争的垄断、推广), 309 | 310 | 1. 企业版本:好用的辅助功能、高级方案(如易地容灾、运维系统的无缝对接) 311 | 2. 技术服务支持 312 | 3. 云服务 313 | - 有了`SSPL`、`AGPL`协议,限制云厂商 314 | - [`SSPL`](https://zhuanlan.zhihu.com/p/106394073),限制商用,比如云厂商如果拿来商用就必须要去找作者获取授权。 315 | - [`AGPL`](https://baike.baidu.com/item/AGPL/4949728),扩展了`GPL`对“发布”的定义,要求使用者一定要开源自己的修改内容。 316 | - 之前`Redis`就苦于 云厂商用得飞起自己一毛钱关系没有。 317 | 318 | ## 微信背后的产品观 - 2021-06-07 319 | 320 | 微信之父张小龙内部100多页PPT,全面剖析微信背后的产品观 321 | 322 | - 文字版 https://www.cnblogs.com/end/p/5521138.html 323 | - PPT图片版 https://www.163.com/dy/article/FQ230RUA051998SC.html 324 | - 今年1月张小龙出了对应的书《微信背后的产品观》 (好薄, 160面) 325 | 326 | > 文字版 https://www.cnblogs.com/end/p/5521138.html 327 | > 328 | > 避免战略行为替代真实需求: 329 | > 330 | > - 避免“打通”。需要打通,说明不是需求 331 | > - 避免“整合”。需要整合,说明都不行了 332 | > - 避免“拉动”。需要拉动,说明是KPI了 333 | > - 避免“导入”。需要导入,说明没生命力 334 | > - 避免“多平台”。不为平台而平台 335 | > - 避免“全面”。全面的东西是平庸的 336 | 337 | 作为可能的注意项 看看/想想,挺有用有意思的。 338 | 339 | PS: 340 | 个人整理的PD书单: https://www.douban.com/doulist/41792144/ 341 | 342 | ## 统计 几何平均数 - 2021-05-29 343 | 344 | > 《[统计数据会说谎](https://book.douban.com/subject/27612464/)》 CH9 如何操纵统计 345 | > 346 | > PS:[统计学/Statistics 书单](https://www.douban.com/doulist/111461569/) 347 | 348 | - 多个指标 是 独立 349 | - 关心的指标比例放大/缩小(绝对数值本身不重要) 350 | 时,用 几何平均数/指数(乘法再开方的操作,抵消比例变化),而不是算术平均数(加和平均)。 351 | 352 | ## 心智负担的游戏 - 2021-05-10 353 | 354 | 心智负担的游戏 https://youtu.be/UANN2Eu6ZnM 355 | The Mental Game of Python 356 | — Raymond Hettinger(Python core developer) 357 | 358 | 用`Python`(可运行的**伪**代码)来实操讲解。 359 | 360 | 个人简陋的摘要: 361 | 362 | - 人脑能同时有效处理信息/概念个数:[神奇的数字 7±2 - wikipedia.org](https://zh.wikipedia.org/zh-hans/%E7%A5%9E%E5%A5%87%E7%9A%84%E6%95%B0%E5%AD%97%EF%BC%9A7%C2%B12) 363 | - 如何把N个 -> 1个,即概念压缩: **_Chunking_**! 364 | - 在编码中,最简单做法,抽函数。 365 | - [*Chunking* - wikipedia.org](https://en.wikipedia.org/wiki/Chunking_(psychology)) 366 | - 如何把 N个 -> 0个,即概念消除: *Aliasing*! 367 | - 即映射到已有的概念上 368 | - 在编码中,转移到一个大家已经熟悉的库上。 369 | - 用`Python`的`random`模块,直接演示了使用,非常帅气! 370 | - 有看《重构》的感觉:简单招式正确重复使用 带来 系统层设计的变化。 371 | 372 | ---------------------------------------- 373 | 374 | 内容也发到了[微博](https://weibo.com/1836334682/KkhYdCDo3)上。 375 | 376 | ### 大家的讨论 377 | 378 | - [`@zavakid`](https://github.com/zavakid): 379 | - 心智负担降低,换来的也是系统的『信心指数』增加,比如可运维性、需求增加、可推理性等。 380 | - 谁都喜欢一个简单且容易说明白的系统,如何做到?可能有效的方法之一就是 概念压缩(我理解为分解、抽象)和 概念消除(复用)。 381 | 382 | ## 如何有效地设置系统报警? - 2021-04-24 383 | 384 | > 下面是 一个产品Owner同学的反馈: 385 | > 386 | > Mr. X 00:30 387 | > XXX应用由于XXX机房 重传率告警过于频繁(对业务关键业务指标无明显影响), 388 | > 已将其独立配置告警,并提高告警阈值至10。 389 | 390 | 如果是 **短时间** & **集群小比例机器**(如单机) 的重传率高 是不会影响 产品。 391 | 上面是 单台机器的高重传率(10%)报警? 392 | 393 | 上面 对重传率报警超高的配置方式:『单机 10%』,意味着 大比例、长时间的高重传率 (如90%的机器 重传率9%)发现不了,会影响业务指标。 394 | 395 | 即 基于单机高比例的报警配置问题 可能会掩盖了 实际是重传率的问题(集群大比例如10%相对高重传率5%)。 396 | 397 | 监控系统上的(所有)监控指标是不是 支持 联合上 机器比例(空间) 与 时长(时间) 来触发报警? 398 | 比如 像这样监控报警定义: 399 | 400 | - 单机机器 20分钟 重传率 > 10% 401 | - 10%的机器 1分钟 重传率 > 2% 402 | 403 | PS:具体的合适数字设置 要根据实际的情况 来看。 404 | 405 | 更进一步进而更专业化的思考: 406 | 407 | - 在统计方式应该使用更有效的『指数滑动平均』,而在不是使用简陋大于小于的阈值判断。 408 | - 『指数滑动平均』是最入门但有效的过滤噪音提取信息的方式。(**信号处理**、**过滤器**)。 409 | - 当然使用 410 | 411 | 一个成熟的监控系统应该 412 | 413 | - 标配提供 414 | 415 | **TODO** 416 | 417 | ## 信噪比 - 2021-04-21 418 | 419 | 一个表达/实现/编码/设计 是否好用/优秀,可以看噪音是否少,即信噪比(`signal-to-noise ratio`)。 420 | 421 | 关于信噪比,常会提到的例子是:用`Java`语言写的`Hello world`,噪音比较多。 422 | 423 | ```java 424 | // Java 425 | public class Main { 426 | public static void main(String[] args) { 427 | System.out.println("Hello world!"); 428 | } 429 | } 430 | ``` 431 | 432 | ```python 433 | # python 434 | print('Hello world!') 435 | ``` 436 | 437 | ```bash 438 | # shell 439 | echo 'Hello world' 440 | ``` 441 | 442 | 为了完成打印`Hello world`,`Java`的噪音很多,如 443 | 444 | - 概念`class/public/main`…… 445 | - 长方法名`System.out.println` 446 | - 代码行数 447 | 448 | 而`Python/Shell`的信噪比接近极限了。 449 | 450 | 当然`Hello world`只是简单的信噪比的示意例子,背后的关注与思考是不变的。 451 | 452 | 好的抽象/模式(即实现代码,落到了代码实现;一方面也是能弥补一些语言本身的噪音), 453 | 可以让使用代码(即业务代码)的 信噪比尽量接近极限。 454 | 455 | > 哲良 `No Code No Bug`定理:😂 456 | > 457 | > 没有代码就没有`Bug`。 458 | > 459 | > 更谨慎的说法是:就代码,就没有(代码引发的)Bug。 460 | > 461 | > 系统线上运行实际都是由代码来支持的(含配置及其防御与处理)。 462 | 463 | ---------------------------------------- 464 | 465 | 内容也发到了[微博](https://weibo.com/1836334682/KbTY8D8py)上。 466 | 467 | ### 大家的讨论 468 | 469 | - [`@hepin1989`](https://github.com/hepin1989): 470 | - `scala`是`println("hello world")` 471 | - `scala`类方式的完整写法: 472 | 473 | ```scala 474 | object MyApp extends App { 475 | println("hello world!") 476 | } 477 | ``` 478 | 479 | - Mr. G:隐藏信息也是有代价的 480 | - Reply By `@oldratlee`:比如 481 | - 花设计者的时间,了解需求确认可用、梳理设计…… 482 | - 为了用户的友好隐藏,会带来的实现的性能overhead(尤其是系统前期,实现优化程度不会不高) 483 | - 当然 性能问题/成本 多数情况(尤其是系统前期/孵化)是被 高估的 484 | 长远来看,谨慎设计的隐藏 是 优化 留下的自由空间,更好优化 485 | - etc. 486 | - Mr. K: 487 | - `python, shell`都是脚本语言,不需要依赖强大的类型化结构支撑,这方面肯定有优势,`java`也通过`static import`在编码上简化了信息。 488 | - 语法体系上有舍有得吧。就象中文是象形文字和英文是基于字母对人思维的方式产生不同方向的影响一样。 489 | - Reply By `@oldratlee`:比如 490 | - 对于 信噪比 的话题,打印`Hello world`只是一个(过度)简化的信噪比的示意例子,但这个例子方便快速理解 信噪的观察。非语言设计话题(中文象形 vs 英文)、语言使用。另外,库可以兜语言的一些库。库,即是语言的灵活演进。 491 | - 我们系统的设计/实现中噪音观察,是引导好设计的一个务实(即方便&有用)的关注项。 492 | - PS: 关于 语言 与 库:库设计就是语言设计。C++语言社区的一个 观点。 493 | 库设计就是语言设计 https://www.jianshu.com/p/8b2767d8e7b7 494 | 语言设计就是库设计 https://www.jianshu.com/p/21e970c44588 495 | - 代码的噪音量少是为了追求代码的易读性吗?如果是,语言本身的设计会产生影响,同时我们 的代码的编写方式也会影响。 496 | - Mr. K: 497 | - 每种开发语言都有其定位差异,从结构编程、面向对象编程、到函数式编程,`C`、`Java`、`Rust`、`Go`等开发语言,围绕其定位会有面向开发者的维度特性表达 498 | - 就像交通工具,飞机追求快,铁路追求舒适与平稳,其次性价比高短途 499 | 500 | ## 依赖分析 - 2021-04-16 501 | 502 | > Posted By [`@zavakid`](https://github.com/zavakid) 503 | 504 | 使用[`maven dependency:analyze`](https://maven.apache.org/plugins/maven-dependency-plugin/analyze-mojo.html)可以发现`maven`工程中: 505 | 506 | - 直接依赖但没有声明的依赖 以及 不依赖但被声明了的依赖。 507 | - 前者能帮忙找出项目隐患,避免非显性依赖版本不知不觉发生变更; 508 | - 后者能帮助项目精简依赖,减少自身打包大小。 509 | 510 | ### 大家的讨论 511 | 512 | - Reply By `@oldratlee`: 513 | - 自己项目直接使用的依赖 却没有在自己项目声明直接依赖。 514 | - 这个问题 自己人肉的方式解过多次,我却没想到去找找工具 来自动发现来解决。 515 | - Reply By [`@hepin1989`](https://github.com/hepin1989): 516 | - 像`maven helper`工具做了可视化 517 | - 二方包治理可以加上`used undeclared dependency`/`unused declared dependency`的识别 518 | 519 | ## 解题理念关键字/核心方法 - 2021-04-06 520 | 521 | 《具体数学》第一章开篇讲到的解题理念关键字/核心方法 522 | 523 | - 推广 524 | - 极端Case 525 | - 平凡(Trivial)Case,即极端简单的Case 526 | - Trivial Case 其实是 推理/推广/通用化/泛化 的起点与基石 527 | - 记号/记法/表达法 528 | - 软件系统对应就是建模,形成对需求/问题的可推演描述 529 | - 一个有价值的系统肯定一直在演进(加需求),避免改乱了/不堪重负 530 | - 核查 531 | 532 | PS: 533 | 534 | - 附图与上面文字 是《具体数学 : 计算机科学基础》第一章 递归问题 P2 535 | - 《具体数学》计算机数学的经典开山大作!英文原版1994-3出版。好吧,我一直没看完…… 536 | - 另一本我非常喜欢的数学科普大作《#怎样解题#》也一样强调了这些。 537 | 538 | 原文摘引: 539 | 540 | > 解决这样问题的最好方法是对它稍加推广。 541 | > 婆罗贺摩塔有64个圆盘,河内塔有8个圆盘,让我们来考虑一下,如果有n个圆盘将会怎样? 542 | > 543 | > 这样推广的一个好处是,我们可以大大简化问题。 544 | > 事实上,在本书中我们将反复看到,先研究小的情形是大有神益的。 545 | > 移动只有一两个圆盘的塔十分容易。再通过少量的尝试就能看出如何移动有3个圆盘的塔。 546 | > 547 | > 求解问题的下一步是引人适当的记号:命名并求解。 548 | > 我们称T[n],是根据卢卡斯的规则将n个圆盘从一根桩柱移动到另一根桩柱所需要的最少移动次数。那么,T[1]显然是1,而T[2] = 3。 549 | > 550 | > 考虑所有情形中最小的情形还可以轻松得到另一条信息,即显然有T[0] = 0,因为一个有 n=0 个圆盘的塔根本无需做任何挪动! 551 | > 552 | > 聪明的数学家们不会羞于考虑小问题,因为当极端情形(即便它们是平凡的情形)弄得明明白白时,一般的形式就容易理解了。 553 | > 554 | > 关于小的情形的经验不仅能帮助我们发现一般的公式,而且还提供了一种便利的核查方法,看看我们是否犯下愚蠢的错误。 555 | > 在以后各章涉及更为复杂的操作策略时,这样的核查尤为重要。 556 | > 557 | 558 | ---------------------------------------- 559 | 560 | 内容也发到了[微博](https://weibo.com/1836334682/K9FRSE7Sm)上。 561 | 562 | ## 多余的『用null初始化』 - 2021-04-02 563 | 564 | ```java 565 | import java.util.concurrent.ThreadLocalRandom; 566 | 567 | public class RedundantInitializerDemo { 568 | public static void main(String[] args) { 569 | String s = null; 570 | 571 | if (ThreadLocalRandom.current().nextBoolean()) { 572 | s = "true"; 573 | } else { 574 | s = "false"; 575 | } 576 | 577 | System.out.println(s); 578 | } 579 | } 580 | ``` 581 | 582 | 583 | 584 | - 为什么这个『用`null`初始化』是多余的, 585 | - 即 为什么删除这个 『用`null`初始化』是安全的? 586 | \# 所以`IntelliJ IDEA`提示 警告,并 直接给出 删除的`AutoFix`操作。 587 | 588 | ### 大家的讨论 589 | 590 | - [`@hepin1989`](https://github.com/hepin1989): 591 | - 因为下面在所有的执行路径上都进行了赋值。 592 | - Reply By `@oldratlee`: 593 | - 还可以进一步回答,比如 为什么 删除 这个赋值 可以更安全? 594 | 比如 这样 编译器 就可以保证 『所有的执行路径上都赋值了』? 595 | - 这个不赋值,就像`final`变量修饰符保证了 变量不会再被赋值。 596 | - 编译器节省了人肉检查(人肉就会出错)。 597 | - 也是提供了进一步的文档性信息。 598 | - Reply By `@zavakid`: 599 | - 不加赋值,就能确保后续会被一定会被复制。 600 | - 如果后面 因为 bug 遗漏了赋值,编译器就能帮忙检查出来。 601 | - 去掉`null`,加个`final`,是最安全的。 602 | - `@oldratlee` 603 | - 严格的讲,对于 上面删除 的是 初始化,不是一般的赋值。 604 | - 所以 可以声明成 final 变量,分别在`if-else`的2条路径初始化。 605 | - \# 虽然我们 平时一般不关心 初始化 与 赋值的区别。 606 | - `Java`及相关语言编译器 记录了 变量是否初始化的状态,以做路径分析,不允许读 未初始化的变量(编译报错)。 607 | 608 | ## 当你编码时,事物命名 - 2021-03-12 609 | 610 | 611 | 612 | —— 《程序员修炼之道》第7章 当你编码时 条款44 事物命名 P245 613 | 614 | ### 大家的讨论 615 | 616 | - [`@zavakid`](https://github.com/zavakid): 617 | - 所以命名也是最难的事情之一。但还是值得,需要去想 618 | - 如何给程序中的变量起个好名字? https://www.infoq.cn/article/t3bgkxio1reigqrw7tgk 619 | 1. 起的名字有意义,可以表达一个概念 620 | 2. 要考虑名字的长度,名称中只有必要信息 621 | 3. 符合“编码规范”,有助于理解 622 | 4. 一个概念不要多个名字混用 623 | 5. 使用在背景领域和上下文中都有意义的名字 624 | 625 | 626 | ## `SICP`作者的新书《面向灵活性的软件设计》 - 2021-03-11 627 | 628 | > 《Software Design for Flexibility: How to Avoid Programming Yourself into a Corner》 629 | > 书名直译《面向灵活性的软件设计:如何避免自己被编排到死角》 630 | > 631 | > ![](images/2021-07-05-15-34-11.png) 632 | > https://www.amazon.com/Software-Design-Flexibility-Programming-Yourself/dp/0262045494 633 | 634 | - `SICP`作者的书;封面也用的是`SICP`的图;瑟瑟发抖! 635 | - 3月9号刚出版的,已经是『best seller』了。 636 | 637 | ## 迭代效率之于工程 2021-02-18 638 | 639 | > 最近我需要自己修改 Linux kernel 里的一些代码(不是 Linux 内核模块),因为我们的内核工程师一直没搞定,只好亲自出马了。于是我首先琢磨了一下如何实现内核开发的 TDD 测试驱动。 640 | > 641 | > 这里最大的挑战是从修改代码到看到效果中间的延时。最初这里的延时长达几分钟,即使已经使用了 KVM 虚机方式。 642 | > 643 | > 于是我优化了一下 .config 文件和内核的 Makefile(有些更动不能通过 CONFIG_XXX 选项来控制),同时使用 supermin 这样的神器,还有用上了 make localmodconfig 命令,最终把从修改代码到看到测试结果的 turnaround time 缩减到了只有 10 秒多一点(其中编译内核只需 9 秒,启动内核和跑测试只要一两秒)。 644 | > 645 | > 有了这么快的内核开发的迭代速度。我一个晚上就搞定了我们内核工程师一个月也没搞定的内核补丁。开心。 646 | > 647 | > by agentzh 2-16 10:32 https://m.weibo.cn/status/4605174922613334 648 | > 649 | > 有了这么快的内核开发的迭代速度。我一个晚上就搞定了我们内核工程师一个月也没搞定的内核补丁。 650 | 651 | 或许有夸张的成分;但迭代效率,是工程最重要的事(可能没有之一)。 652 | 653 | 只要有快的迭代再加上持续改进,一个naive的想法或实现会演变成 有效、极致、稳定的解决方案。 654 | 655 | ### 大家的讨论 656 | 657 | - [`@zavakid`](https://github.com/zavakid): 658 | - 迭代加快,试错成本就低,就能尝试更多的想法,有更多的试错机会。 659 | 660 | ## 公共知识 与 主动宣导 - 2021-01-29 661 | 662 | > - 一个关于数学归纳法的悖论问题:到底是第 N 天有 N 个红眼睛自杀,还是什么都不会发生? - 知乎 https://www.zhihu.com/question/21262930 663 | > - 红眼睛问题——数学归纳法(基础篇) https://zhuanlan.zhihu.com/p/53029086 664 | > - 李永乐老师:《皇帝的新装》 https://v.youku.com/v_show/id_XNDUzNjExNTYzMg== 665 | 666 | 涉及的经典概念: 667 | 668 | - 共有知识(每个人 自己知道的知识,共有) 669 | - 公共知识(共用 & 知道别人知道) 670 | - 即使大家都知道的事,站出来宣导仍然是 至关重要的 671 | 672 | PS: 673 | 674 | - 这个『红眼睛、蓝眼睛』问题最早据说是澳大利亚的华裔数学神童陶哲轩在网上贴出来让大家思考。 675 | - 《陶哲轩 实分析 第3版》 https://book.douban.com/subject/30227556/ 676 | 677 | ## 谷歌可靠性工程的设计经验 - 2021-01-21 678 | 679 | > [谷歌可靠性工程的设计经验](https://mp.weixin.qq.com/s?__biz=MzIzNzU4MTg5NQ==&mid=2247485167&idx=1&sn=84e8688eacca0732cf3d6679f08e1165&chksm=e8c725c7dfb0acd1c9a6c497028e1a6be8757a3f25d77e45418171aa23f7bf1e9c6ccaf421a6&mpshare=1&srcid=0930v6FU0ARo4lXcD9y7cLIl&sharer_sharetime=1569801545094&sharer_shareid=5d48c3632036332790a62e50d19f3dd9&from=timeline&scene=2&subscene=2&clicktime=1611242327&enterid=1611242327&ascene=2&devicetype=android-29&version=2700163b&nettype=WIFI&abtest_cookie=AAACAA%3D%3D&lang=zh_CN&exportkey=ASjgNHEbqMTJxE9q7Kb%2F9bk%3D&pass_ticket=4NHvAqJRB%2BX95iPCw8k8BGV%2FFZ6XnNUcltGK7K%2FfVV7ISzV%2Bsk%2Fj6INL14b83TaY&wx_header=1) 680 | > 681 | > ![](images/2021-06-29-19-49-25.png) 682 | 683 | - 给了个经验值/估算: 684 | - 100M用户,100K QPS(3量级差),200K高峰QPS(这个我国应该不合) 685 | - 从qps的角度跨天的用户总量和qps几乎没有相关性 686 | - QPS ~ DAU ~ MAU(xD AU) 687 | - 或者说 MAU、DAU 比值是个变量 反映 一个用户使用频度(粘性) 688 | 689 | ## Magic Go Lang! - 2021-01-18 690 | 691 | > Why we moved from Kotlin & Spring Boot to Go 692 | > https://blog.astradot.com/why-we-moved-from-kotlin-spring-boot-to-go/ 693 | > 694 | > ![](images/2021-06-29-14-46-29.png) 695 | 696 | 按这样`magic`式的大众鼓吹风下去,`Java`要死: 697 | 698 | > The latency graph almost feels like it disappears after the switch. 699 | > 700 | > Memory usage went from 3.1GB to 125MB! 701 | > 702 | > continued converting each microservice from Kotlin/Spring Boot to Go and its magical each time watching those graphs drop. 703 | > 704 | > …… 705 | 706 | 707 | ### 大家的讨论 708 | 709 | - [`@hepin1989`](https://github.com/hepin1989): 710 | - 等:https://openjdk.java.net/projects/valhalla/ 来拯救我们 711 | - 然后kotlin也加入了:https://kotlinlang.org/docs/reference/inline-classes.html ,类似scala的value class,这样抽象的时候也不至于浪费太多内存。 712 | - https://quarkus.io 713 | 714 | - Reply By `@oldratlee`: 715 | - 这个5倍的差别,上面magic 40倍的差别 716 | - comments: 717 | 1. Instant compile times and program startup for faster development 718 | - 这个暂时无解 ,可能bazel 719 | 2. Virtual threads for dealing with high concurrency workloads 720 | - Loom 还在开发中,或则Akka actor、Kotlin的协程 721 | 3. Value types to better control memory usage 722 | - Project valhalla 723 | - 当然还有更夸张的Rust粉呢,Rust粉还说Golang也还有GC不行呢 724 | -------------------------------------------------------------------------------- /broken-thoughts/images/122038467-3473da00-ce08-11eb-884e-68d4b2a9eff9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122038467-3473da00-ce08-11eb-884e-68d4b2a9eff9.png -------------------------------------------------------------------------------- /broken-thoughts/images/122039611-6e91ab80-ce09-11eb-8ed8-33b84c2a4724.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122039611-6e91ab80-ce09-11eb-8ed8-33b84c2a4724.JPG -------------------------------------------------------------------------------- /broken-thoughts/images/122039863-b1538380-ce09-11eb-9978-0cd3de349267.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122039863-b1538380-ce09-11eb-9978-0cd3de349267.JPG -------------------------------------------------------------------------------- /broken-thoughts/images/122043335-d0541480-ce0d-11eb-8fb1-38b561b4de47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122043335-d0541480-ce0d-11eb-8fb1-38b561b4de47.png -------------------------------------------------------------------------------- /broken-thoughts/images/122043467-efeb3d00-ce0d-11eb-853e-8a02879c6e1f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122043467-efeb3d00-ce0d-11eb-853e-8a02879c6e1f.png -------------------------------------------------------------------------------- /broken-thoughts/images/122043943-80298200-ce0e-11eb-9aad-7734902a29ba.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122043943-80298200-ce0e-11eb-9aad-7734902a29ba.jpg -------------------------------------------------------------------------------- /broken-thoughts/images/122045887-d3043900-ce10-11eb-9988-556d714e138c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122045887-d3043900-ce10-11eb-9988-556d714e138c.png -------------------------------------------------------------------------------- /broken-thoughts/images/122046774-e663d400-ce11-11eb-97f7-a261ac338142.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122046774-e663d400-ce11-11eb-97f7-a261ac338142.png -------------------------------------------------------------------------------- /broken-thoughts/images/122047539-dac4dd00-ce12-11eb-9415-7dc2ddfb3fd9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122047539-dac4dd00-ce12-11eb-9415-7dc2ddfb3fd9.jpg -------------------------------------------------------------------------------- /broken-thoughts/images/122066128-0cdf3a80-ce25-11eb-8896-0cbb9c7dfb2c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122066128-0cdf3a80-ce25-11eb-8896-0cbb9c7dfb2c.png -------------------------------------------------------------------------------- /broken-thoughts/images/122679418-58c32280-d21d-11eb-9a74-6717fdf5a9cd.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122679418-58c32280-d21d-11eb-9a74-6717fdf5a9cd.JPG -------------------------------------------------------------------------------- /broken-thoughts/images/122679671-60cf9200-d21e-11eb-8213-aaa78aa8291d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122679671-60cf9200-d21e-11eb-8213-aaa78aa8291d.jpg -------------------------------------------------------------------------------- /broken-thoughts/images/122702626-5f37b580-d282-11eb-9b37-f77332d6b91d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122702626-5f37b580-d282-11eb-9b37-f77332d6b91d.png -------------------------------------------------------------------------------- /broken-thoughts/images/122702815-c7869700-d282-11eb-9828-7f00ff271789.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122702815-c7869700-d282-11eb-9828-7f00ff271789.png -------------------------------------------------------------------------------- /broken-thoughts/images/122704841-16cec680-d287-11eb-994e-6863eef2e243.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/122704841-16cec680-d287-11eb-994e-6863eef2e243.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-14-42-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-14-42-38.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-14-46-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-14-46-29.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-15-04-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-15-04-10.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-15-31-26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-15-31-26.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-15-31-45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-15-31-45.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-15-32-00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-15-32-00.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-15-47-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-15-47-17.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-15-48-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-15-48-18.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-15-52-27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-15-52-27.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-19-49-25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-19-49-25.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-06-29-20-12-27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-06-29-20-12-27.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-05-15-34-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-05-15-34-11.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-07-13-42-45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-07-13-42-45.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-07-13-43-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-07-13-43-38.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-07-21-20-52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-07-21-20-52.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-16-11-34-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-16-11-34-34.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-16-14-59-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-16-14-59-30.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-16-15-01-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-16-15-01-29.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-16-15-02-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-16-15-02-18.png -------------------------------------------------------------------------------- /broken-thoughts/images/2021-07-16-15-03-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/2021-07-16-15-03-32.png -------------------------------------------------------------------------------- /broken-thoughts/images/IMG_20210406_180932.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/broken-thoughts/images/IMG_20210406_180932.jpg -------------------------------------------------------------------------------- /cache-practice/README.md: -------------------------------------------------------------------------------- 1 | # Java Cache Practice 2 | 3 | :point_right: 应用开发中,`Cache`毫无疑问是很重要的一块:提升应用性能的关键,降低像`DB`这样关键资源的负荷;但`Cache`的使用有很多要注意的问题与陷阱。 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | - [关于`Cache`的问题/陷阱](#%E5%85%B3%E4%BA%8Ecache%E7%9A%84%E9%97%AE%E9%A2%98%E9%99%B7%E9%98%B1) 12 | - [使用库 vs. 自己实现?](#%E4%BD%BF%E7%94%A8%E5%BA%93-vs-%E8%87%AA%E5%B7%B1%E5%AE%9E%E7%8E%B0) 13 | - [Java Cache Frameworks/Libs](#java-cache-frameworkslibs) 14 | - [Cache Middleware](#cache-middleware) 15 | - [相关资料](#%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99) 16 | 17 | 18 | 19 | ## 关于`Cache`的问题/陷阱 20 | 21 | 在应用开发通过`Cache`来性能优化时,要注意或了解下面的问题/陷阱: 22 | 23 | 1. **_多级_** `Cache`支持 24 | - 应用开发时往往会考虑加上内存`Cache`,因为内存`Cache`性能高很多于`Cache`中间件(如`Memcached`) 25 | - 当然要特别注意的是 **_内存`Cache`数据条目上限_** 的设置,避免内存消耗过多导致应用瘫痪。 26 | - 由于内存中`Cache`数据条目,如何决定哪些数据要`Cache`,移出策略的设置变得要好好思考。 27 | - 如果`Cache`涉及数据条目很多、很分散没有时间局部性,那么内存`Cache`可能是浪费内存且增加了操作性能更低。 28 | - 这样数据访问路径就成了:内存`Cache` -> 远程`Cache` -> 实际数据(如`DB`) 29 | 1. 无实际数据时的 **_防击穿_** 30 | 导致没有数据时,一直会访问`DB`。 31 | (**_自己实现时,容易忽略这点_**) 32 | 1. `Cache`中没有数据时,即首次加载时,并发的`Cache`请求的 **_防击穿_** 33 | 期望在这种情况下,并发请求只会触发一次实际数据请求,数据请求完成后,所有并发`Cache`请求都返回数据。 34 | (**_自己实现时,容易忽略这点_**) 35 | 1. 使用`Cache`请求时,**_透明_** 数据的加载,即 36 | - 业务实现不需要自己写这样的逻辑: 37 | - 如果`Cache`中没有数据读实际数据,设置好`Cache`; 38 | - 如果`Cache`中有数据返回`Cache`数据。 39 | - 这样逻辑繁琐易漏易错。 40 | - `Cache`会持有加载实际数据的`Loader`,参见`Guava`的[`CacheLoader`模式](https://github.com/google/guava/wiki/CachesExplained#population)。 41 | 42 | 如果有『击穿』的情况,系统性能压力上来时会雪崩,而你想依赖的之前性能压测的性能数据已经没有意义了。 43 | 44 | ## 使用库 vs. 自己实现? 45 | 46 | 总得来说,应该使用`Cache`框架而不应该自己去实现: 47 | 48 | 1. `Cache`要解决好的问题与业务无关很稳定,所以一定有好的`Cache`框架,并解决好上面这些问题。 49 | 1. `Cache`的并发控制/线程安全的问题,对于一般应用开发者来说,可能没有概念,即使是面向自己场景的简单实现也可能漏洞百出。 50 | 1. 完整的`Cache`实现以应对不同场景的需求,要考虑很多方面: 51 | 1. 条目的逐出(`Eviction`)/过期策略,如 52 | - 最简单常用的基于固定数目上限的`LRU` 53 | - 基于时间的逐出 54 | - 基于引用,以加速内存`GC` 55 | 1. 逐出条目的回调,方便应用可以集成条目的生命周期,如添加监控 56 | 1. `Cache`的命中率,方便了解系统的情况 57 | 1. …… 58 | 59 | ## Java Cache Frameworks/Libs 60 | 61 | - [Java Caching System](https://github.com/apache/commons-jcs) - Apache Commons 62 | - https://commons.apache.org/proper/commons-jcs/index.html 63 | - [Guava](https://github.com/google/guava) Cache 64 | - https://github.com/google/guava/wiki/CachesExplained 65 | - [Caffeine](https://github.com/ben-manes/caffeine) is a high performance, near optimal caching library based on Java 8. 66 | - [Ehcache](https://github.com/ehcache/ehcache3) 67 | - http://www.ehcache.org/ 68 | - [J2Cache](https://git.oschina.net/ld/J2Cache) 69 | - 更多参见 [Java开源缓存框架](http://www.open-open.com/13.htm) 70 | 71 | ## Cache Middleware 72 | 73 | - [Redis](https://github.com/antirez/redis) 74 | - https://redis.io/ 75 | - [Memcached](https://github.com/memcached/memcached) 76 | - https://memcached.org/ 77 | - [Tair](https://github.com/alibaba/tair) 78 | - http://code.taobao.org/p/tair/wiki/intro/ 79 | - 更多参见 http://www.oschina.net/project/tag/109/cacheserver 80 | 81 | ## 相关资料 82 | 83 | - [Cache 框架乱炖](https://juejin.im/entry/5741d07c49830c00614a0319) 84 | - [Ehcache详细解读](http://raychase.iteye.com/blog/1545906) 85 | - [Java Cache系列之Cache概述和Simple Cache](https://yq.aliyun.com/articles/46897) 86 | - [5个强大的Java分布式缓存框架推荐](http://www.codeceo.com/article/5-java-distribute-cache.html) 87 | -------------------------------------------------------------------------------- /cache-practice/cache-stock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/cache-practice/cache-stock.jpg -------------------------------------------------------------------------------- /cache-practice/cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/cache-practice/cache.png -------------------------------------------------------------------------------- /cache-practice/cache1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/cache-practice/cache1.png -------------------------------------------------------------------------------- /compiler-flow-code-review/README.md: -------------------------------------------------------------------------------- 1 | # `compileflow`开源项目的Code Review 2 | 3 | ## 🍎 序 4 | 5 | 有幸受邀[`@voff12`](https://github.com/voff12) Review `compileflow`,写于 2020-08-02。 6 | 7 | - Review与交流讨论的过程 是自己整理学习的过程。 8 | - 大部分的整理内容 其实是独立于具体的一个开源项目。 9 | 10 | 所以觉得值得整理出来。 11 | 12 | 下面是Review的内容记录。 13 | 14 | ------------------------------------------------- 15 | 16 | 17 | 18 | 19 | 20 | - [0. Review内容说明](#0-review%E5%86%85%E5%AE%B9%E8%AF%B4%E6%98%8E) 21 | - [1. 产品开源的用户体验](#1-%E4%BA%A7%E5%93%81%E5%BC%80%E6%BA%90%E7%9A%84%E7%94%A8%E6%88%B7%E4%BD%93%E9%AA%8C) 22 | - [2. 代码实现](#2-%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0) 23 | - [2.0 文档](#20-%E6%96%87%E6%A1%A3) 24 | - [2.1 代码可靠性](#21-%E4%BB%A3%E7%A0%81%E5%8F%AF%E9%9D%A0%E6%80%A7) 25 | - [2.3 专业性(命名/拼写、Warning etc)](#23-%E4%B8%93%E4%B8%9A%E6%80%A7%E5%91%BD%E5%90%8D%E6%8B%BC%E5%86%99warning-etc) 26 | - [3. 系统设计](#3-%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1) 27 | - [3.1 按系统(子)领域/模型拆分](#31-%E6%8C%89%E7%B3%BB%E7%BB%9F%E5%AD%90%E9%A2%86%E5%9F%9F%E6%A8%A1%E5%9E%8B%E6%8B%86%E5%88%86) 28 | - [3.1.0 拆分原则说明](#310-%E6%8B%86%E5%88%86%E5%8E%9F%E5%88%99%E8%AF%B4%E6%98%8E) 29 | - [3.1.1 实践推论](#311-%E5%AE%9E%E8%B7%B5%E6%8E%A8%E8%AE%BA) 30 | - [3.1.2 可能涉及的问题](#312-%E5%8F%AF%E8%83%BD%E6%B6%89%E5%8F%8A%E7%9A%84%E9%97%AE%E9%A2%98) 31 | - [3.1.3 涉及的Action](#313-%E6%B6%89%E5%8F%8A%E7%9A%84action) 32 | - [3.1.∞. 关于API](#31%E2%88%9E-%E5%85%B3%E4%BA%8Eapi) 33 | - [3.2 扩展设计](#32-%E6%89%A9%E5%B1%95%E8%AE%BE%E8%AE%A1) 34 | - [3.2.0 关于 SPI(扩展)vs API](#320-%E5%85%B3%E4%BA%8E-spi%E6%89%A9%E5%B1%95vs-api) 35 | - [3.2.1 关于扩展的包设计](#321-%E5%85%B3%E4%BA%8E%E6%89%A9%E5%B1%95%E7%9A%84%E5%8C%85%E8%AE%BE%E8%AE%A1) 36 | - [3.2.2 关于扩展的依赖管理](#322-%E5%85%B3%E4%BA%8E%E6%89%A9%E5%B1%95%E7%9A%84%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86) 37 | - [4. 工程实践](#4-%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5) 38 | - [4.1 通用工程实践](#41-%E9%80%9A%E7%94%A8%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5) 39 | - [4.1.1 发布版本管理](#411-%E5%8F%91%E5%B8%83%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86) 40 | - [4.1.2 VCS](#412-vcs) 41 | - [4.1.3 构建](#413-%E6%9E%84%E5%BB%BA) 42 | - [4.2 Java相关的工程实践](#42-java%E7%9B%B8%E5%85%B3%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5) 43 | - [4.3 软件测试](#43-%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95) 44 | - [单元测试(UT)不用做Try-Catch-Fail来断言出异常](#%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95ut%E4%B8%8D%E7%94%A8%E5%81%9Atry-catch-fail%E6%9D%A5%E6%96%AD%E8%A8%80%E5%87%BA%E5%BC%82%E5%B8%B8) 45 | 46 | 47 | 48 | ------------------------------------------------- 49 | 50 | ## 0. Review内容说明 51 | 52 | > Open Source Projects: 53 | > 54 | > - [`git@github.com:alibaba/compileflow.git`](https://github.com/alibaba/compileflow) 55 | > - [`git@github.com:alibaba/compileflow-idea-designer.git`](https://github.com/alibaba/compileflow-idea-designer) 56 | > 57 | > 注意:**下面这些整理的是我想到的内容,未必高优先级;根据项目紧急与重要性的实际情况跟进  :")** 58 | > 59 | > 相关资料,个人做的分享整理: 60 | > 61 | > - 分享PPT:[开源漫游者指南:开源的工作内容与要点](../hitchhikers-guide-to-open-source/开源漫游者指南-v0.9.1.pptx) 62 | > - 分享PPT:[Git/VCS 使用与原则 简介](../git/git-usage-and-principle-v0.3.1.pptx) 63 | > - 分享PPT:[软件可靠性设计的实践](../practice-of-software-reliability-design/软件可靠性设计的实践-v0.9.2.pptx) 64 | 65 | ## 1. 产品开源的用户体验 66 | 67 | - 提供一个Quick Start的极简Demo 68 | - 如果工程足够简单,可以放在 对应工程模块的**test目录的demo包**下 69 | - 目前`compileflow`就只有 单工程模块,挺好的 :") 70 | - 并在 README文档 中引导用户对查看 这个Demo,方便用户快速运行与上手理解 71 | - 示例,参见`TransmittableThreadLocal`的 72 | - 提供的Quick Start的[极简Demo](https://github.com/alibaba/transmittable-thread-local/tree/2.x/src/test/java/com/alibaba/demo/ttl) 73 | - 文档引导:[完整可运行的Demo代码参见SimpleDemo.kt](https://github.com/alibaba/transmittable-thread-local/tree/2.x#1-%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8) 74 | 75 | ## 2. 代码实现 76 | 77 | 如 代码的可读性/简洁性、可靠性、专业性、etc 78 | 79 | ### 2.0 文档 80 | 81 | 1. (核心)**接口要有完整ApiDoc**(如`ProcessEngine`)。尤其不要漏了下面的这些内容: 82 | - 通过JavaDoc的`@throws` 说明好:什么情况出什么异常? 83 | - 输入输出的要求。如参数/返回值 是否为null? 84 | - 推荐使用 [`spotbugs-annotations`依赖](https://github.com/alibaba/transmittable-thread-local/blob/2fa0cdb3dfed6de0048a0a3f78e8efda7423b96e/pom.xml#L108-L119) 与 [`spotbugs-maven-plugin`](https://github.com/alibaba/transmittable-thread-local/blob/2fa0cdb3dfed6de0048a0a3f78e8efda7423b96e/pom.xml#L539-L554),提供编译时的自动检查能力。 85 | - 配置方式 参见上行的链接。PS: `spotbugs`能做的检查远不止 像`@NonNull`空值检查。 86 | - 通过JavaDoc的`@since` 说明好:这个类/方法从哪个版本开始支持? 87 | - 支持版本信息 对基础`SDK`/服务 至关重要,因为涉及功能的新增与兼容性。 88 | - 像接口/方法的基本功能解释 往往不会漏了 :") 89 | 90 | ### 2.1 代码可靠性 91 | 92 | 1. **对于分情况的处理逻辑(`if-else if-ELSE`/`switch-case-DEFAULT`),要遍历尽所有情况。** 93 | - 对于不可能出现的情况,需要报错Fast-Fail(如 抛异常) (By @WuXiang ) 94 | - 避免掩盖问题,带病运行。 95 | - 及时报错(如抛异常) 可以提供 显式的错误说明。 96 | 而带病运行的出错往往已经不知道什么直接业务原因了(答非所问了),排查困难。 97 | - 如果有**充分理由**不『遍历尽所有情况』, 98 | - 则在`else/default`位置上,注释代码以解释好理由。 99 | - 避免看代码人的可靠性疑虑(是真不需要`else`,还是没有去考虑而逻辑有缺失)。 100 | - 示例,如下: 101 | ![image.png](images/01.png) 102 | 2. **不要 默默吃掉异常,不做任何操作(如Wrap异常重抛出、日志汇报、恢复)。** 103 | - 如果有**充分理由**『吃掉异常不做任何操作』, 104 | - 则catch位置上,注释代码 以解释好理由。 105 | - 避免看代码人的可靠性疑虑(是异常真可以忽略,还是没有去考虑而逻辑有缺失)。 106 | - 示例,如下: 107 | ![image.png](images/02.png) 108 | 1. 这条没有发现明显的问题。 109 | 3. **能使用`final`的情况下,尽量加上`final`。** 无论字段还是局部变量。(这条优先级/重要性低 :")。原因: 110 | 1. `final`有保证不会改变的语义:减少出错(意外修改);方便逻辑推理,提升代码可读性。 111 | 1. `final`字段有**并发**语义,可以提升程序并发的安全性。(并发是个大主题,这里不展开:") 112 | ![image.png](images/03.png) 113 | 114 | ### 2.3 专业性(命名/拼写、Warning etc) 115 | 116 | 1. **命名**。如大小写/拼写 etc。 117 | - Inword(连单词) 118 | - 如 **`Compile*f*lowException -> Compile*F*lowException`** 119 | - 不要缩写。可读性优先;并且现代化`IDE`的自动补全能力让不用缩写的编码键入几乎没有额外成本。 120 | - 如,`EncodingConsts` -> `EncodingConstants` 121 | 2. **代码Warning**。期望**0 Warning**。如泛型、转型操作的代码Warning。 122 | - 泛型类/接口 缺失了 泛型参数 123 | - **主接口** `interface ProcessEngine>` 缺失了 124 | - 还有很多接口/方法 :") 125 | - 转型操作 126 | - 转型操作Warning,在 确定是安全且不得不的情况下, 使用 `@SuppressWarnings("unchecked")` 127 | ![image.png](images/04.png) 128 | 3. **拼写错误** 129 | - 如,`DEF*UA*LT_JAVA_SOURCE_VERSION` -> `DEF*AU*LT_JAVA_SOURCE_VERSION` 130 | 131 | ## 3. 系统设计 132 | 133 | 如系统领域/模型、模型对应的分包等等。自然也是提升系统实现/代码实现的 可读性/简洁性、可理解性 etc。 134 | 135 | ### 3.1 按系统(子)领域/模型拆分 136 | 137 | #### 3.1.0 拆分原则说明 138 | 139 | - **设计原则**:按系统(子)领域/模型拆分,各个 **(子)领域** 自包含(self-contained)。 140 | - 与之对应的**实现原则**:从设计对应到代码上,(子)领域的API的**Java包**自包含(self-contained)。 141 | 142 | 一个领域涉及的概念(如`POJO`、异常类、错误码、常量)应该不多的;尽量分拆进入其对应子领域。 143 | 144 | **人脑认知在一个抽象层次 能玩转的概念个数 很有限(<=7个,最好<=5)。** 145 | 146 | 概念个数的经验法则, 147 | 148 | - 适用于一个域自身透露的概念个数(对外的展现) 149 | - 也适用于 **一个域下涉及的子域个数**(对内的分解) 150 | 151 | 在效果上的结果/要求,就是尽量下拆职责,以期望形成 [**窄接口 深模块**](https://macsalvation.net/a-intensive-reading-of-a-philosophy-of-software-design/): 152 | 153 | - **窄接口:** 上层域(是下层支撑的接口)内容尽量少,不要涉及 下层的(细节)内容 154 | - **深模块:** 下层支撑域个数限制,层次可以多 155 | 156 | [**窄接口 深模块**](https://macsalvation.net/a-intensive-reading-of-a-philosophy-of-software-design/)的收益是 使用、理解的成本低,得到期望的 **高ROI抽象**。 157 | 158 | 可以看到,**抽象/系统设计/建模**的**优秀程度** 通过 **模块形状**的**窄深程度** 来判断。 159 | 160 | 可能被无视/反直觉的常识 值得单拎出来强调: 161 | 162 | 接口是成本! 163 | 用户调用接口是成本!! 164 | 用户调用接口是使用成本!!! 165 | (没有接口无需调用就能解决问题,那是最好的了。Woo~ 🤥 😂 ) 166 | 167 | PS: 深模块 一词来自书《[A Philosophy of Software Design](https://book.douban.com/subject/30218046/)》: 168 | ![image.png](images/05.png) 169 | 170 | #### 3.1.1 实践推论 171 | 172 | 原则『按系统(子)领域/模型拆分,各个 **(子)领域**自包含』的**推论**: 173 | 174 | - **不要** 面向**技术方式/特征**来划分包,而是面向**业务域**的方式拆分。 175 | - 如`exception`、`contants`、`model`、`(error)code`这样的包名 176 | 像是不是异常、常量,这些是技术特征。应该**尽量分拆入其对应(子)领域。** 177 | - 面向技术独立包 会导致 178 | - 与业务域(要解决的问题)关联不强的**孤立技术类**。这样的代码孤立感来自: 179 | - 与使用它的对应域的类远了 180 | - 域代码文件没有一目了然地排在一起。 181 | - 因为按技术划分,只是看起来包下的类变少了,实际上是 182 | - **掩盖**了 业务域下拆不足的问题 183 | - **阻碍**了 领域拆分梳理优化的持续演进 184 | - 以 异常 为例,说明 一下按业务域下拆: 185 | - 子异常 `CompileFlow*Parse*Exception` 则属于子域(即子包 `compileflow.engine.transformer.converter.*parser*`)。 186 | - 根异常 **`CompileFlowException`** 属于 根域(即根包 `com.alibaba.compileflow`)。 187 | - 在根域(即根包 `compileflow`)只关心 `CompileFlowException` 188 | - 概念上(即根域API)并 不需要/不应该 关心其子域异常(如更具体的子类异常 `CompileFlowParseException`)。 189 | - **一个域包下类**太多 或 **一个域包下的子域包**太多,则需要做 **领域拆分**梳理优化。 190 | - 如果一个域包下类太多了(如`Model`、异常、常量类), 191 | 则应该思考一下 **自己本身的领域拆分** 是不是梳理优化了? 192 | - 如果一个包下的子包太多了, 193 | 则应该思考一下 **子领域的领域拆分** 是不是要梳理优化了? 194 | - 因为分形下拆,一个包下的子包不会/不应该太多,而一个包/业务域的支撑域不会/不应该太多。 195 | 196 | #### 3.1.2 可能涉及的问题 197 | 198 | - 太厚的包(领域拆分不足?) 199 | - **com.alibaba.compileflow.common** 200 | - 包含了 面向技术的分包,如 201 | - com.alibaba.compileflow.common.**exception** 202 | - com.alibaba.compileflow.common.**code** 203 | - com.alibaba.compileflow.common.**consts** 204 | - …… 205 | - 是不是可以按拆解到对应的子域? 206 | - **com.alibaba.compileflow.engine.transformer.model.bpmn** 207 | - 是不是可以进一步抽象拆解领域? 208 | - `compileflow`**内部/自己的**使用的包推荐放到`internal`包下。如 209 | - com.alibaba.**compileflow.common**.script -> com.alibaba.**compileflow.internal.common**.script 210 | - com.alibaba.**compileflow.common**.cache -> com.alibaba.**compileflow.internal.common**.cache 211 | - 业务使用 **`internal`**包来 表义/声明: 212 | - 内部使用的内容,自己会改,没有使用的兼容性保证。 213 | - 用户使用不要依赖。用户使用产品时,也并不需要理解这些内容。 214 | - compileflow.common.utils.`VarUtils` 是不是可以放到 肯定只有engine应该使用的 compileflow.engine 包下?(按域下拆) 215 | - 看到了common包 依赖了 业务包: 216 | VarUtils -> com.alibaba.compileflow.`engine.transformer.model.bpmn`.FlowElement; 217 | 218 | #### 3.1.3 涉及的Action 219 | 220 | - `CompileFlow*Exception`,放到`compileflow`根包(业务领域)下。 221 | - `compileflow.engine.transformer.consts.ActionType` 放到其使用根包(业务领域)下。 222 | - 使用的类是compileflow.engine.transformer.converter.parser.bpmn.ServiceTaskParser 223 | - 而 transformer.consts.ActionType 在概念上 是 224 | 属于 **上层的子域** compileflow.engine.transformer.converter.**parser**? 225 | 还是 **更下层的细子域** compileflow.engine.transformer.converter.**parser.bpmn**? 226 | 227 | #### 3.1.∞. 关于API 228 | 229 | - 从API的特征来说(即API的定义): 230 | **只要能被用户使用观察的、改变了会Break用户代码的部分**,即属于API。 231 | - API包含哪些内容(即 都放在**自己域的根包**下的内容): 232 | - API的(`Java`) **接口/方法** 233 | - (Java)接口方法涉及的 **`POJO`类**,表达了这个域输入输出的数据(正常情况)。 234 | - 对应目前的实践是 放在了 model 子包下。多了一次远跳的代码查看/理解的成本。 235 | - **如果一个域根包下类太多了(如Model类),则应该思考一下领域拆分是不是要优化了?** 236 | - (`Java`)接口方法涉及的 **异常类**,表达这个域的出错情况。 237 | 正常(`POJO`)/出错(异常)情况的输入输出类 等同重要。 238 | - 涉及的这些实现类的序列化形式。 239 | - 因为用户使用关注这些实现类序列化所引发的兼容性问题。 240 | - 这条 现在可能相对被关注得少了 😂 241 | - 这个API包含条目 来自 《[Effective Java](https://book.douban.com/subject/30412517/)》 242 | - 《Effective Java》简直是`Java`专业开发的百科全书。 243 | 244 | ### 3.2 扩展设计 245 | 246 | #### 3.2.0 关于 SPI(扩展)vs API 247 | 248 | **SPI**(`Service Provider Interface`,即扩展)与 **API**(`Application Programming Interface`)对应。 249 | 250 | - SPI 与 API 都是 Interface。 251 | - **SPI**:用于,在不修改框架/库的情况下,替换/追加 框架/库内部组件的实现。 252 | - 面向角色、用户是 框架的(三方)开发者。 253 | 三方开发者,是指非框架的开发者,即不能或没有权限 去修改 框架/库本身的代码。 254 | - **API**:用于暴露框架/库 的业务功能。 255 | - 面向角色、用户是 框架外部的业务用户、使用者。 256 | - 广义上讲,SPI 是 API的一种。 257 | - **API 与 SPI的区别**: 258 | - SPI 用户是 内部(框架开发者);API 是外部的(框架使用者)。 259 | - 如果内部的接口,且能 (在运行时、编译打包时)**替换/追加 组件实现**,就称之为**扩展**。 260 | 261 | #### 3.2.1 关于扩展的包设计 262 | 263 | **一般扩展/SPI 在包名 不需要 特殊对待。** 264 | 265 | - 因为 扩展/SPI 是框架的内部组件,即就是『3.1』节说的 子域/包拆分。 266 | - 即 扩展/SPI 在包名上 一般情况并不需要在包名上特殊对待,按域拆分即可。 267 | 268 | **什么情况下,扩展/SPI 需要显式的`spi`包名?** 269 | 270 | - 有一些内部开发者对象: 271 | - 需要加到 **API的对象**上(业务用户使用的对象) 272 | - 且 与API在同一个域(即这些对象 不能有 有不同的自己域包) 273 | - 对于这些对象(暂称为 **_SPI隐藏对象_**),为了 274 | - 尽量减少 业务用户的理解/使用干扰;如避免在API域包被业务用户过于方便地翻到/自动补全出来。 275 | - 表义 是内部对象,业务用户 在使用时 可以不用关心。 276 | - 这时,可以使用一个显式的`spi`包名。 277 | - **注意**:对于比较复杂的框架/库,上面 **_SPI隐藏对象_** 往往没有理由出现,因为可以有丰富的子域结构。 278 | 279 | **示例**: 280 | 281 | - `Dubbo`框架:有大量的扩展(80+个),并没有使用显式的`spi`包。 282 | - 显式 `spi`包的示例:[alibaba/transmittable-thread-local - spi包](https://github.com/alibaba/transmittable-thread-local/blob/master/src/main/java/com/alibaba/ttl/spi/) 283 | 里面就是 用于加到API对象的一些类,但只有 框架开发者 才关心的类。 284 | 285 | #### 3.2.2 关于扩展的依赖管理 286 | 287 | 比如`compileflow`中的 `compiler扩展(EC/JdkCompiler)`: 288 | 289 | - 依赖极简 290 | - **核心/基础库 依赖 要极简** 291 | - 如果可能,选一个扩展作为缺省,对于缺省扩展要求能 开箱即用。 292 | - 即缺省扩展 依赖要带好,compile非Provided,其它的compiler选成Provided。 293 | - 缺省扩展的选择原则:各个关注点的优先级如下: 294 | - **使用方便、可开箱即用**。即用户方便地不需要额外加依赖。(JDK实现因为自带依赖会有优势) 295 | - **稳定性**好 296 | - **性能**好 297 | 性能,这个关注点对于缺省扩展来看,优先级往往是最低的;高级用户 有能力为性能自己定制。 298 | 299 | ## 4. 工程实践 300 | 301 | ### 4.1 通用工程实践 302 | 303 | 如软件版本发布管理、构建、VCS,etc。 304 | 305 | #### 4.1.1 发布版本管理 306 | 307 | - 使用业界的3位语义化版本:compileflow-process 1.0 -> 1.0.0 308 | - 1位升级 表示 不兼容的大版本,2位升级 表示 新功能新增,3位升级表示 BugFix之类。 309 | - 后缀 `RC` 表示 **非稳定版本**,一般用于1位、2位版本, 如 `1.3.0-RC1` 310 | - 详见 [语义化版本 2.0.0 | Semantic Versioning](https://semver.org/lang/zh-CN/) 311 | - PS: 看到`pom.xml`已经用的是三位版本号 `1.1.1-SNAPSHOT`,只是在`README.md`还有二位版本的示例。 312 | - 第一对外发布的版本推荐使用 `1.0.0`,甚至更低的`0.9.x`版本,这样比较有正式感 & 仪式感。 313 | - 原因: 314 | - `1.0.0`版本,表示专门为开源做的首个正式可用的版本; 315 | - 而`0.9.x`版本,表示为开源版本是准备要上心打磨的。 316 | - PS:看到 开源工程`compileflow`中,还有没有打过的 发版的Tag,但开源代码中的版本已经是 `1.1.1-SNAPSHOT`,非`1.0.0`。 317 | 318 | #### 4.1.2 VCS 319 | 320 | - **不要** 源码Git工程中 包含 二进制大文件,如`compileflow.idea-3.0.zip` 321 | - 可以通过 下面的方式 来保存 构建的衍生物/发布物 322 | - **Github的Release页**。在Release页可以上传(构建)文件。 323 | 示例: [https://github.com/lihaoyi/Ammonite/releases/tag/2.2.0](https://github.com/lihaoyi/Ammonite/releases/tag/2.2.0) 324 | - **Maven 的 Deploy**。Maven的发布可以随带部署构建的二进制发布物。 325 | 示例:[https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3](https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3) `/apache-maven-3.6.3-bin.zip` 326 | - **改正方式**: 327 | - 通过使用`git-filter-repo`工具来修正仓库历史。 328 | - 原因,代码库/VCS 是 329 | - 大家频繁修改、更新的地方,要快;大文件让`clone`、查看等操作 都变慢了 330 | - 是追踪变更的源文件的地方。构建的衍生物(如上面的二进制大文件) 不值得在 VCS/代码库中 浪费这样更珍贵的资源。 331 | - **一个上百兆的代码库 是 实践反模式。** 332 | 333 | #### 4.1.3 构建 334 | 335 | - 工程自带 构建工具的`Wrapper`,对于 Maven即是 `mvnw` 336 | - 这样做的**好处**: 337 | - 用户 使用方便 & 确定性: 338 | - 确保 **用户**使用正确版本的构建工具 **成功**完成构建。 339 | - 用户 不再需要 自己手动安装 Maven。 340 | - 持续集成(`CI`)确定性: 341 | - 保证 的 基线 也包含了 构建工具(的版本)。过老版本的构建工具往往构建可能失败。 342 | - `Maven Wrapper`的**生成方法**: 343 | - `mvn -N io.takari:maven:0.7.7:wrapper -Dmaven=3.6.3` 344 | - 示例: [`alibaba/transmittable-thread-local`](https://github.com/alibaba/transmittable-thread-local)/`{mvnw, mvnw.cmd, .mvn}` 345 | 346 | ### 4.2 `Java`相关的工程实践 347 | 348 | 如 Java生态的Maven,etc。 349 | 350 | - 不要使用 父`POM`:`com.taobao:parent` 351 | - 这样做的**好处**: 352 | - 减少依赖,让自己极简 353 | - 作为一个独立项目,也不需要 这个`taobao`父`POM`中的约定 354 | - 生产代码依赖了测试库。是不是 不应该? 355 | - 生成代码 编译依赖了测试库 356 | - `junit:junit`(虽然scope是provided) 357 | - `org.springframework:spring-test` 358 | - 即生产代码依赖了。 359 | 360 | ### 4.3 软件测试 361 | 362 | #### 单元测试(UT)不用做`Try-Catch-Fail`来断言出异常 363 | 364 | 原因: 365 | 366 | 1. 出异常的测试Case,`JUnit`会打出异常信息,并且 是 失败的。 367 | 即 自然是合要求的 368 | 2. 这样的`Try-Catch`是 代码噪音(影响测试逻辑的一目了然)。 369 | ![image.png](images/06.png) 370 | 371 | 更多关于 UT/JUnit 的最佳实践,可以看看比如 《[JUnit实战 : 第2版](https://book.douban.com/subject/10561424/)》 372 | -------------------------------------------------------------------------------- /compiler-flow-code-review/images/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/compiler-flow-code-review/images/01.png -------------------------------------------------------------------------------- /compiler-flow-code-review/images/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/compiler-flow-code-review/images/02.png -------------------------------------------------------------------------------- /compiler-flow-code-review/images/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/compiler-flow-code-review/images/03.png -------------------------------------------------------------------------------- /compiler-flow-code-review/images/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/compiler-flow-code-review/images/04.png -------------------------------------------------------------------------------- /compiler-flow-code-review/images/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/compiler-flow-code-review/images/05.png -------------------------------------------------------------------------------- /compiler-flow-code-review/images/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/compiler-flow-code-review/images/06.png -------------------------------------------------------------------------------- /git/README.md: -------------------------------------------------------------------------------- 1 | Why `Git` 2 | ========================= 3 | 4 | ![](images/why-git.png) 5 | 6 | :point_right: Why I love to use git rather than svn! 7 | 自己在使用`git`过程中相对`svn`的感受强烈的变化。 8 | 9 | :beer: 合并对提交过程的保留 10 | ------------------- 11 | 12 | - `git`:合并操作保留原有的提交过程(即保留了合并来源的作者、提交次数、分离提交的内容)。 13 | - `svn`:合并操作把来源多个提交合并成了一个合并提交,即在提交历史中Crash了自然的提交过程。 14 | 15 | 保留原有的提交过程,可以无需繁琐追踪历史就方便的 16 | 17 | 1. 跟踪修改过程。 18 | 1. 直接从提交中就可以看到原提交的作者信息,体现了对作者的尊重。 19 | 1. 自然的提交过程。这极大方便了代码细节演进过程的查看。 20 | 1. 极大方便查出那行提交是什么时间、谁做出的。 21 | `svn`因为合并Crash了自然的提交过程,要追踪很痛苦。 22 | 23 | :beer: 修正提交 24 | ------------------- 25 | 26 | - `git`:可以修正提交。 27 | 使用功能分支工作流,在自己的分支可以方便修正提交而不会影响大家。 28 | - `svn`:一旦提交就到服务器上,实际使用中就是不能修改。 29 | (`svn`可以在服务器上修改,因为过程复杂需要权限实际上从不会这样做。) 30 | 31 | 实际使用中会有误提交的情况(如提交了一个不该提交的日志文件),对于`svn`来说,就是让大家一遍又一遍看到这个垃圾文件。 32 | 33 | 没有干净的提交,严重影响了`Code Review`,增加成本。 34 | 35 | 另外对于想了解演进过程的同学,垃圾提交影响了了解效果。 36 | 37 | :beer: 廉价好用的本地分支 38 | ------------------- 39 | 40 | - `git`:有本地分支 41 | - `svn`:无本地分支 42 | 43 | `git`可以方便创建本地分支,且创建分支的时间是`O(1)`,即瞬间就创建好了。由于分支可以是本地的,也就不存在`svn`目录权限的问题。 44 | 45 | 可以从想要工作点闪电般创建本地分支,本地实验不确定的修改,创建分支如此之廉价,`git`推荐创建分支来隔离修改。 46 | 47 | :beer: 更强大智能的合并能力 48 | ---------------- 49 | 50 | - `git`:重命名(无论文件还有目录)提交 可以合并上 文件重命名前的这些文件的提交。 51 | - `svn`:重命名(无论文件还有目录)提交后,你本地/或是分支上 有文件重命名前的这些文件的修改或提交,在做合并操作时,恭喜:see_no_evil:,你会碰上传说中难搞的 ***树冲突***! 52 | 53 | 因为惧怕`svn`***树冲突***,在包名调整(重命名目录)或类名调整(重命名文件)前,我不得不先向一起开发的组员广播: 54 | 55 | 1. 提交你的修改 56 | 1. 暂停相关类的修改 57 | 1. 我开始做调整 58 | 1. 等我修改好后:scream:,你再开始修改 59 | 60 | OMG~ :confounded:~~ 61 | 62 | 因为这个过程烦琐,结果就是影响了大家去做这样重构操作的积极性,进而影响项目的代码质量改进! 63 | 64 | 别忘了,如果你的项目是开源的,全球的人可以给你提交,可没有办法向全球的同学广播 :kissing: 65 | 66 | :beer: 一等公民支持`tag` 67 | ------------------- 68 | 69 | - `svn`在模型上是没有分支和`tag`的。`tag`是通过目录权限限制(对开发只读)来保证不变。 70 | - `git`模型上一等公民支持`tag`,保证只读。 71 | 72 | 内心是不是有强烈的安全感? :sparkles: 73 | 74 | :beer: 完整配套的开发过程设施 75 | ------------------- 76 | 77 | 与`git`配套的`github`、`gitlab`(我们公司搭建了)提供了: 78 | 79 | - `Markdown`:高效的文档编写和查看。 80 | - `Issue` & `Milestone`:问题记录&跟踪,任务分配,版本规划&管理 81 | - `Wiki`系统:体系的文档 82 | - 评论:可以对代码提交(即是Code Review)& Issue做评论。 83 | 这个有记录交流的过程。 84 | 85 | 记住,上面的一切和代码一起集中管理,是以代码为中心的,可以方便的工程中的代码。 86 | 87 | 可运行并完成功能的代码(且叫目标代码) 才是整体项目真正生效的产出。 88 | 89 | 一切不为 目标代码 服务 的东东都是 **流氓**! 90 | \# 是不是想到很多东西(比如下压式的排期计划)会觉得自己是生效的产出,好像剩下的事就是 码农搬砖一样把代码码好。 91 | 92 | :beer: 热操作有闪电般的速度 93 | ------------------- 94 | 95 | ### 提交 96 | 97 | - `git`提交是个本地操作,相对`svn`闪电一般。 98 | - `git`提供了暂存区,可以方便指定提交内容,而不是全部。 99 | PS: `git`可以只提交一个文件修改的一部分而非全部(`git add –p`),使用相对繁琐些。(实际上开发中我很少这么做 :grin:) 100 | 101 | 这让开发者更愿意整理提交,让每个提交更内聚自包含。进而有利于 102 | 103 | - `Code Review` 104 | - 线上`Bug`的快速准确的回滚式修复 105 | 106 | ### 查看日志 107 | 108 | 查看日志是个频繁的操作。 109 | 110 | - `git`:本地包含了完整的日志,闪电的速度(并且无需网络)。 111 | - `svn`:需要从服务拉取。 112 | 113 | 一旦用了`git`后,等待`svn`日志(包括查看2个版本间的`diff`)过程简直让我发狂。 114 | -------------------------------------------------------------------------------- /git/git-gitlab-usage.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/git/git-gitlab-usage.pptx -------------------------------------------------------------------------------- /git/git-usage-and-principle-v0.3.1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/git/git-usage-and-principle-v0.3.1.pptx -------------------------------------------------------------------------------- /git/github-git-cheat-sheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/git/github-git-cheat-sheet.pdf -------------------------------------------------------------------------------- /git/images/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/git/images/git.png -------------------------------------------------------------------------------- /git/images/github.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/git/images/github.jpg -------------------------------------------------------------------------------- /git/images/gitlab.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/git/images/gitlab.jpg -------------------------------------------------------------------------------- /git/images/why-git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/git/images/why-git.png -------------------------------------------------------------------------------- /git/study-material.md: -------------------------------------------------------------------------------- 1 | `Git`学习资料 2 | ================================= 3 | 4 | 入门和理解 5 | ---------------- 6 | 7 | 8 | - [`git` - 简明指南](http://rogerdudler.github.io/git-guide/index.zh.html "助你入门 git 的简明指南,木有高深内容 ;)") 9 | - [图解`Git`](http://marklodato.github.io/visual-git-guide/index-zh-cn.html "图解Git") 10 | - [think-like-a-git.net](http://think-like-a-git.net/) 11 | - [`Github` Help](https://help.github.com/) 12 | - [`Atlassian` `git` tutorials](https://www.atlassian.com/git/tutorials/) 13 | - 特别提一下其中的[workflow](https://www.atlassian.com/git/workflows)部分,对工作流有体系的讲解。 14 | 这部分的中文翻译在 [`Git`工作流指南](https://github.com/oldratlee/translations/tree/master/git-workflows-and-tutorials)。 15 | - [蒋鑫 - Why `Git` is better than `SVN`](http://www.worldhello.net/2012/04/12/why-git-is-better-than-svn.html "蒋鑫:为什么 Git 比 SVN 好") 16 | - `Github`的[git cheat sheet](https://training.github.com/kit/downloads/github-git-cheat-sheet.pdf)。【[本地文件](github-git-cheat-sheet.pdf)】 17 | 18 | PS,自己写的一点内容,放在最后,算是敝帚自珍了 :joy: 19 | 20 | - [Why Git - 自己在使用git过程中相对svn的感受强烈的变化](README.md) 21 | - PPT: [git/gitlab使用](git-gitlab-usage.pptx) 22 | 23 | 系统学习 24 | ---------------- 25 | 26 | - [***Pro Git*** 第一版,中文](http://git-scm.com/book/zh/v1) 27 | - [***Pro Git*** 2nd Edition](http://git-scm.com/book/en/v2) 28 | - [我的`git`豆瓣书列](http://www.douban.com/doulist/1686793/) 29 | - 这里特别提一下***git internal***(这本书已经开源在`Github` [git-internals-pdf](https://github.com/pluralsight/git-internals-pdf),作者太牛逼了!) 30 | 这本书涉及Git的底层模型,比如存储结构、目录结构等等。深入的风格可以满足你比使用更底层的好奇,反过来让你在使用上庖丁解牛般无往不厉! 31 | - [`Amazon` `git`书籍搜索结果页](http://www.amazon.com/s/ref=nb_sb_noss?url=node%3D5&field-keywords=git) 32 | 33 | **PS**: 34 | 在中国的地面上,这些书都实际上都可以直接下载到`PDF`(这话一说,我的表情已不自然了 :grin:),不再多说了! 35 | -------------------------------------------------------------------------------- /hitchhikers-guide-to-open-source/开源漫游者指南-v0.9.1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/hitchhikers-guide-to-open-source/开源漫游者指南-v0.9.1.pptx -------------------------------------------------------------------------------- /how-to-write-a-issue.md: -------------------------------------------------------------------------------- 1 | 如何写一个`issue` 2 | ========================= 3 | 4 | `issue`是重要目的是问题的记录,也可以作为 ***非正式的*** 文档(可以包含讨论)。 5 | 6 | 所以`issue`要包含内容: 7 | 8 | - 问题复现场景的完整说明 9 | 如何认为是“完整”的?任何人只要照着说明可以问题即可。 10 | - 问题原因的分析 11 | - 可能的解决方案 12 | - 大家的讨论 13 | 14 | `issue`还可以做: 15 | 16 | - 问题指派给谁 17 | - 指定在哪个版本实现 18 | - 加上标签(`tag`),方便标识 19 | -------------------------------------------------------------------------------- /images/LICENSE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/images/LICENSE.png -------------------------------------------------------------------------------- /images/miscellany-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/images/miscellany-icon.png -------------------------------------------------------------------------------- /lb-distribution-uniformity-analysis/README.md: -------------------------------------------------------------------------------- 1 | > 写于 2019-10-01。 2 | 3 | # 任务分发均匀性的模型量化分析 4 | 5 | - 任务分发在软件系统的很多地方会出现,如 6 | - 服务调用,服务调用方给服务提供方的调用请求 7 | - 网关,向后端服务器路由请求 8 | - …… 9 | - 对于上面情况,(抽象的)任务即是请求。 10 | - 因为一般都是集群,`LB`会涉及 多个任务分发方 来多个任务接收方。 11 | - 对于上面的分布式场景下请求分发,一般请求分发出去了,不会再对请求进行重新分配(任务分发后接收者就确定不变了)。 12 | - 在软件系统中,这个分发功能常称为`Load-Balance`(简称`LB`)。 13 | 14 | 任务分发/`LB`的均匀性是一个需要考虑的问题,如果不均匀: 15 | 16 | - 有些任务接收者,导致不必要的过载甚至宕机。 17 | - 如果对`LB`后的`QPS`做限流(即任务分发时作限流,常常称为**前置限流**),以保护系统不过载: 18 | - 对于收到的任务更多机器,会开始限流; 19 | - 对于收到的任务更少机器,不会限流; 20 | - 限流功能 对于用户看来,总的限流`QPS`就不准确,整体的限流`QPS`是有偏差的。 21 | - 即整体配置的限流`QPS`1万,但来1万`QPS`(甚至不到1万`QPS`),就已经出现限流了。 22 | - 这样的情况,常常称为『提前限流』。 23 | 24 | 下面的内容,量化分析: 25 | 26 | - `LB`(即任务分发)的不均匀性 27 | - 前置限流`QPS`偏差(下面分析的目标内容) 28 | - 面向业务效果和为业务能提供的能力进行量化分析。 29 | - 有这个量化分析,前置限流由『**提供技术功能的方式**』向『**提供面向业务的解决方案方式**』演进。 30 | 31 | ---------------------------------------- 32 | 33 | 34 | 35 | 36 | 37 | - [1. 目标](#1-%E7%9B%AE%E6%A0%87) 38 | - [1.1 什么是『面向业务的解决方案方式』](#11-%E4%BB%80%E4%B9%88%E6%98%AF%E3%80%8E%E9%9D%A2%E5%90%91%E4%B8%9A%E5%8A%A1%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E6%96%B9%E5%BC%8F%E3%80%8F) 39 | - [1.2 网关前置限流的『面向业务的解决方案方式』](#12-%E7%BD%91%E5%85%B3%E5%89%8D%E7%BD%AE%E9%99%90%E6%B5%81%E7%9A%84%E3%80%8E%E9%9D%A2%E5%90%91%E4%B8%9A%E5%8A%A1%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E6%96%B9%E5%BC%8F%E3%80%8F) 40 | - [1.2.1 解决业务问题的效果与承诺](#121-%E8%A7%A3%E5%86%B3%E4%B8%9A%E5%8A%A1%E9%97%AE%E9%A2%98%E7%9A%84%E6%95%88%E6%9E%9C%E4%B8%8E%E6%89%BF%E8%AF%BA) 41 | - [1.2.1.1 对于提前限流比例](#1211-%E5%AF%B9%E4%BA%8E%E6%8F%90%E5%89%8D%E9%99%90%E6%B5%81%E6%AF%94%E4%BE%8B) 42 | - [1.2.1.2 对于最大通过`QPS`](#1212-%E5%AF%B9%E4%BA%8E%E6%9C%80%E5%A4%A7%E9%80%9A%E8%BF%87qps) 43 | - [1.2.1.3 提前限流比例 与 最大通过`QPS` 2者的关系](#1213-%E6%8F%90%E5%89%8D%E9%99%90%E6%B5%81%E6%AF%94%E4%BE%8B-%E4%B8%8E-%E6%9C%80%E5%A4%A7%E9%80%9A%E8%BF%87qps-2%E8%80%85%E7%9A%84%E5%85%B3%E7%B3%BB) 44 | - [1.2.1.4 提前限流比例 与 最大通过`QPS` 2者的平衡调节,即『网关前置限流』用户配置使用方式](#1214-%E6%8F%90%E5%89%8D%E9%99%90%E6%B5%81%E6%AF%94%E4%BE%8B-%E4%B8%8E-%E6%9C%80%E5%A4%A7%E9%80%9A%E8%BF%87qps-2%E8%80%85%E7%9A%84%E5%B9%B3%E8%A1%A1%E8%B0%83%E8%8A%82%E5%8D%B3%E3%80%8E%E7%BD%91%E5%85%B3%E5%89%8D%E7%BD%AE%E9%99%90%E6%B5%81%E3%80%8F%E7%94%A8%E6%88%B7%E9%85%8D%E7%BD%AE%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F) 45 | - [1.2.2 技术系统的内部实现细节](#122-%E6%8A%80%E6%9C%AF%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%86%85%E9%83%A8%E5%AE%9E%E7%8E%B0%E7%BB%86%E8%8A%82) 46 | - [1.3 为什么要作量化分析](#13-%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%9C%E9%87%8F%E5%8C%96%E5%88%86%E6%9E%90) 47 | - [2. 网关前置限流给业务方的一般常见表达方式](#2-%E7%BD%91%E5%85%B3%E5%89%8D%E7%BD%AE%E9%99%90%E6%B5%81%E7%BB%99%E4%B8%9A%E5%8A%A1%E6%96%B9%E7%9A%84%E4%B8%80%E8%88%AC%E5%B8%B8%E8%A7%81%E8%A1%A8%E8%BE%BE%E6%96%B9%E5%BC%8F) 48 | - [3. 量化分析报告](#3-%E9%87%8F%E5%8C%96%E5%88%86%E6%9E%90%E6%8A%A5%E5%91%8A) 49 | 50 | 51 | 52 | ---------------------------------------- 53 | 54 | # 1. 目标 55 | 56 | 前置限流由『**提供技术功能的方式**』向『**提供面向业务的解决方案方式**』演进。目标是 57 | 58 | - 对于整体系统: 59 | - 提升的整体系统(含网关、各个业务应用)的稳定性 与 确定性。 60 | - 对于网关产品: 61 | - 尽可能地拓展网关(前置限流)的 **业务** 范围。 62 | - 提升网关的 **业务** 能力心智。 63 | 64 | ## 1.1 什么是『面向业务的解决方案方式』 65 | 66 | 这里解释一下什么是『面向业务的解决方案方式』。 67 | 68 | - **深入理解业务场景与问题,提供解决业务问题的效果与承诺。** 69 | - **业务方无需关注技术系统的内部实现细节。** 70 | 71 | ## 1.2 网关前置限流的『面向业务的解决方案方式』 72 | 73 | ### 1.2.1 解决业务问题的效果与承诺 74 | 75 | 下面其实就是 对业务领域/问题的本身的理解(问题域),期望不涉及实现方案(实现域)。 76 | 77 | 业务关注的是,对于业务方评估出来的业务`QPS`: 78 | 79 | - 网关提前限流比例 是多少? 80 | - **影响** 业务目标达成;是业务使用『网关前置限流能力』带来负面影响。 81 | - 即业务期望 提前限流比例越低越好。 82 | - 网关最大通过`QPS` 是多少? 83 | - **提供** 业务系统稳定性保障;是业务期望从『网关前置限流能力』获得的正面收益。 84 | - 业务期望 最大通过`QPS`超出业务`QPS`越少越好。 85 | - 如果 最大通过`QPS` 过大,前置限流 实际上没有起到 前置限流的保护效果。 86 | - 面向业务的关注点可以简化 业务方的理解与使用。 87 | 88 | 那么 解决业务问题的效果与承诺 就是,对于业务方给的业务`QPS`: 89 | 90 | - (提前限流比例, 最大通过`QPS`) 可以取哪些值? 91 | - 如何选择/平衡 (提前限流比例, 最大通过`QPS`) 两者的值? 92 | 93 | #### 1.2.1.1 对于提前限流比例 94 | 95 | - 业务影响可以接受的提前限流比例 是有 经验值 或 典型值的。 96 | - 比如 千分之3 或 万分之1 这样的一个提前限流比例,往往都可以接受(相比上,下面前置限流带来的稳定性受益)。 97 | - 想想,万分之1的提前限流比例 的话, 98 | - 从系统整体上看,50万的QPS 只有50个让前置限流了,影响不大。 99 | - 从用户微观上看,因为概率低,用户心理也不会有反应。 100 | - 目前『提前限流比例』获取方式: 101 | - 通过压测时发起来一个业务`QPS`的流量来获取。 102 | - 其实这个过程很粗糙。 103 | - 当然因为用户验证方式『粗糙』,对解决方案的要求程度实际上不高。 104 | 105 | #### 1.2.1.2 对于最大通过`QPS` 106 | 107 | 最大通过`QPS` 这点很直接,大家都很明白,无需再多说明。 108 | 109 | #### 1.2.1.3 提前限流比例 与 最大通过`QPS` 2者的关系 110 | 111 | 提前限流比例、最大通过`QPS` 两者关联影响(即成为一个元组),这是由限流器原理/规律决定。 112 | 113 | - 对于一个给定的业务`QPS`, 114 | - 『提前限流比例』 与 『最大通过`QPS`超出业务`QPS`』 不能都低。 115 | - 如果一者调低了,另一者就变高了。 116 | - 对于小的业务`QPS`,要把『提前限流比例』调成一个较低值,则『上限通过`QPS`』会非常大。 117 | - 这样情况下,为了满足业务要求(低『提前限流比例』),网关前置限流对业务没有收益了。 118 | - 即网关前置限流对这样的场景**不适用**。 119 | - 比如,要保证300 `QPS`要高成功率,推导出 『上限通过`QPS`』是3百万。 120 | 这就是说 没有稳定性保障的效果了。 121 | - 上面只是**定性**地简单说明,2者的关联影响 在单独的**量化分析文档**中详细展开说明。 122 | 123 | #### 1.2.1.4 提前限流比例 与 最大通过`QPS` 2者的平衡调节,即『网关前置限流』用户配置使用方式 124 | 125 | 了解『提前限流比例 与 最大通过`QPS` 2者的关系』之后,关键的问题就变成了: 126 | 127 | 不同的业务场景下,如何选择/平衡 (提前限流比例, 最大通过`QPS`) 两者的值? 128 | 129 | 既然如此,期望的『网关前置限流能力』使用/配置方式就是: 130 | 131 | 1. 用户给出Ta的业务`QPS` 132 | 1. 根据网关情况,『网关前置限流配置界面』给出 (提前限流比例, 最大通过`QPS`) 可以取的值对(即确定性的参考数字)。 133 | - 『根据网关情况』就指涉及 现实细节的部分。 134 | 1. 业务根据自己场景,挑出合适自己业务的 (提前限流比例, 最大通过`QPS`) 值对。 135 | - 上面是让用户自己权衡 136 | - 可以更进一步,我们收集 典型的业务场景,给出合适典型场景的『提前限流比例』。 137 | - 有了参照之后,用户常常就可能复用这些判断,而不用各个应用都做详细的业务适用分析。 138 | 139 | ### 1.2.2 技术系统的内部实现细节 140 | 141 | - 放大比例 是 多少?(放大比例 是 操作/实现细节,非业务需求) 142 | - 放大比例 是指,比如 业务目标是限流到1万`QPS`,为了避免出现提前限流,配置成1.2万`QPS`,这里放大比例是 1.2。 143 | - 网关集群的大小 144 | - 网关在不同单元/机房的流量是不是独立的? 145 | - 如果有互相的影响,还涉及单元/机房这一层面的分析。 146 | - 单元/机房这一层面这一层面的难度不高,下面的分析这个层面,以保持分析的聚焦简单。 147 | - …… 148 | 149 | ## 1.3 为什么要作量化分析 150 | 151 | 1. 通过量化分析,可以给已经使用的**业务方**提供确定性的能力承诺。 152 | - 无需业务自己来反复测试来能力效果的确定性。 153 | 1. 整理与总结出,不同典型业务场景 154 | - 业务使用/配置的具体数值 155 | - 面向业务场景的整理与总结,可以进一步方便/简化业务方理解与使用 156 | 1. 通过确定的量化数据,给出面向业务的合适/不合适的可解释的原因(确定性的能力),确定、发现与扩展产品在业务上的适应范围。 157 | 158 | # 2. 网关前置限流给业务方的一般常见表达方式 159 | 160 | 透出的用户的是 161 | 162 | - 业务`QPS` 163 | - 放大比率,比如`1.2`。 164 | - 如上文所说,放大比例是实现细节;期望不向用户透出『放大比率』。 165 | - 期望表达成(提前限流比例, 最大通过`QPS`)2个效果数值的平衡选择。 166 | - 但这样的作为一个业务方没有确定性的业务效果说明: 167 | - `1.2`会减少提前限流的情况,但预期会减少多少? 168 | - 这个业务最关心的效果,并没有说明。 169 | 170 | 结果会是: 171 | 172 | - 因为没有量化的参考指标,业务要自己去做反复去验证。 173 | - 增加业务的操作成本。 174 | - 弱化网关作为产品的能力,用的是一个网关有的一个限流功能。 175 | - 而对于业务方,往往没有时间/资料去做量化分析,往往量化分析意识也会更差些。 176 | - 进一步的结果会是 177 | - 前置限流的业务效果/稳定性保障的确定性不能有效提升。 178 | 179 | # 3. 量化分析报告 180 | 181 | 报告是`Jupyter Notebook`,使用`Python`完成量化数据分析。 182 | 183 | - 网关前置限流的量化分析,参见[Notebook 基于泊松分布量化分析网关前置限流的限流`QPS`偏差比例](legacy/gateway_flow_limiter_analysis_base_poisson.ipynb) 184 | - 概念展开、计算公式推导与代码实现,参见 [Notebook 基于泊松分布量化分析网关前置限流所需要的公式推导与代码实现](legacy/gateway_flow_limiter_formula_base_poisson.ipynb) 185 | - 关于泊松分布,参见 [Notebook 泊松分布的简介、代码实现与概率分布图像](poisson_intro.ipynb) 186 | 187 | 有了基于模型的量化分析,需要与线上实际的测试数据验证匹配程度,需要继续分析。 188 | 189 | ---------------------------------------- 190 | 191 | > **_NOTE_**: 192 | > 193 | > 快速安装`Jupyter Notebook`/`Python`的数据分析运行环境,可以参见: 194 | > [数据分析实践/开发环境搭建 - github.com/data-science-practice](https://github.com/oldratlee/data-science-practice#1-%E5%AE%9E%E8%B7%B5%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA) 195 | > 196 | > `Python`已经成为数据分析/机器学习的首选实践/开发环境。 197 | -------------------------------------------------------------------------------- /lb-distribution-uniformity-analysis/prepare-study/hello_numpy.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "pycharm": { 7 | "name": "#%% md\n" 8 | } 9 | }, 10 | "source": [ 11 | "# 下面是些`numpy`的使用Demo,以获得一些体感" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "metadata": { 18 | "pycharm": { 19 | "is_executing": false, 20 | "name": "#%%\n" 21 | } 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "import numpy as np\n", 26 | "import math\n", 27 | "import scipy as sp\n", 28 | "import scipy.special as sc" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "metadata": { 35 | "pycharm": { 36 | "is_executing": false 37 | } 38 | }, 39 | "outputs": [ 40 | { 41 | "data": { 42 | "text/plain": "array([ 6, 24])" 43 | }, 44 | "metadata": {}, 45 | "output_type": "execute_result", 46 | "execution_count": 2 47 | } 48 | ], 49 | "source": [ 50 | "sc.factorial([3, 4], exact=True)" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 3, 56 | "metadata": { 57 | "pycharm": { 58 | "is_executing": false 59 | } 60 | }, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/plain": "array([ 6., 24.])" 65 | }, 66 | "metadata": {}, 67 | "output_type": "execute_result", 68 | "execution_count": 3 69 | } 70 | ], 71 | "source": [ 72 | "sc.factorial([3, 4])" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 4, 78 | "metadata": { 79 | "pycharm": { 80 | "is_executing": false 81 | } 82 | }, 83 | "outputs": [ 84 | { 85 | "data": { 86 | "text/plain": "array([ 6, 84, 1512])" 87 | }, 88 | "metadata": {}, 89 | "output_type": "execute_result", 90 | "execution_count": 4 91 | } 92 | ], 93 | "source": [ 94 | "sc.factorial([3, 3.5, 4], exact=True)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 5, 100 | "metadata": { 101 | "pycharm": { 102 | "is_executing": false 103 | } 104 | }, 105 | "outputs": [ 106 | { 107 | "data": { 108 | "text/plain": "array([ 6. , 11.6317284, 24. ])" 109 | }, 110 | "metadata": {}, 111 | "output_type": "execute_result", 112 | "execution_count": 5 113 | } 114 | ], 115 | "source": [ 116 | "sc.factorial([3, 3.5, 4])" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 6, 122 | "metadata": { 123 | "pycharm": { 124 | "is_executing": false, 125 | "name": "#%%\n" 126 | } 127 | }, 128 | "outputs": [ 129 | { 130 | "data": { 131 | "text/plain": "array([ 2.71828183, 7.3890561 , 20.08553692])" 132 | }, 133 | "metadata": {}, 134 | "output_type": "execute_result", 135 | "execution_count": 6 136 | } 137 | ], 138 | "source": [ 139 | "np.exp([1, 2, 3])" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 7, 145 | "metadata": { 146 | "pycharm": { 147 | "is_executing": false, 148 | "name": "#%%\n" 149 | } 150 | }, 151 | "outputs": [ 152 | { 153 | "data": { 154 | "text/plain": "array([0.0000000e+00, 1.0000000e+00, 1.2246468e-16])" 155 | }, 156 | "metadata": {}, 157 | "output_type": "execute_result", 158 | "execution_count": 7 159 | } 160 | ], 161 | "source": [ 162 | "np.sin([0, math.pi/2, math.pi])" 163 | ] 164 | } 165 | ], 166 | "metadata": { 167 | "kernelspec": { 168 | "display_name": "Python 3", 169 | "language": "python", 170 | "name": "python3" 171 | }, 172 | "language_info": { 173 | "codemirror_mode": { 174 | "name": "ipython", 175 | "version": 3 176 | }, 177 | "file_extension": ".py", 178 | "mimetype": "text/x-python", 179 | "name": "python", 180 | "nbconvert_exporter": "python", 181 | "pygments_lexer": "ipython3", 182 | "version": "3.7.4" 183 | }, 184 | "pycharm": { 185 | "stem_cell": { 186 | "cell_type": "raw", 187 | "metadata": { 188 | "collapsed": false 189 | }, 190 | "source": [] 191 | } 192 | } 193 | }, 194 | "nbformat": 4, 195 | "nbformat_minor": 1 196 | } -------------------------------------------------------------------------------- /lisp-practice/README.md: -------------------------------------------------------------------------------- 1 | `Lisp` Practice 2 | ======================= 3 | 4 | 5 | 6 | 对于大多数程序员来说,`Lisp`是编程语言中的一个神。 7 | 8 | ---------------------------------------- 9 | 10 | 11 | 12 | 13 | 14 | - [Quick Start](#quick-start) 15 | - [`lisp`安装](#lisp%E5%AE%89%E8%A3%85) 16 | - [`Steel Bank Common Lisp`](#steel-bank-common-lisp) 17 | - [`CLISP`](#clisp) 18 | - [`lisp`运行时介绍](#lisp%E8%BF%90%E8%A1%8C%E6%97%B6%E4%BB%8B%E7%BB%8D) 19 | - [web application quick start](#web-application-quick-start) 20 | - [相关资料](#%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99) 21 | - [`lisp`文章](#lisp%E6%96%87%E7%AB%A0) 22 | - [`lisp`书籍](#lisp%E4%B9%A6%E7%B1%8D) 23 | - [已有的资料汇编](#%E5%B7%B2%E6%9C%89%E7%9A%84%E8%B5%84%E6%96%99%E6%B1%87%E7%BC%96) 24 | - [个人整理资料](#%E4%B8%AA%E4%BA%BA%E6%95%B4%E7%90%86%E8%B5%84%E6%96%99) 25 | 26 | 27 | 28 | ---------------------------------------- 29 | 30 | Quick Start 31 | --------------- 32 | 33 | ### `lisp`安装 34 | 35 | 我偷懒了 :smile: ,只说明了`Mac`下的安装方式,如果是`Linux`下通过包管理器有类似简单安装方法。 36 | 37 | #### `Steel Bank Common Lisp` 38 | 39 | `Mac`下安装 40 | 41 | ```bash 42 | brew install sbcl 43 | ``` 44 | 45 | [`sbcl`的官网](http://www.sbcl.org/) 46 | 47 | #### `CLISP` 48 | 49 | `Mac`下安装 50 | 51 | ```bash 52 | brew install clisp 53 | ``` 54 | 55 | [`clisp`的官网](http://www.clisp.org/) 56 | 57 | #### `lisp`运行时介绍 58 | 59 | 有哪些`lisp`运行时可以看看下面的这个链接,简单了解一下: 60 | 61 | - [Free Common Lisp Compilers, Interpreters, Development Systems](http://www.thefreecountry.com/compilers/commonlisp.shtml) 62 | 63 | ### web application quick start 64 | 65 | 参见 [从零开始,给出完整运行起一个`Lisp` `web`框架`clack`的`Hello World`应用](lisp-web-app-quick-start.md)。 66 | 67 | 相关资料 68 | ------------------- 69 | 70 | ### `lisp`文章 71 | 72 | - [`lisp`学习之路](http://daiyuwen.freeshell.org/gb/lisp.html) 73 | - [`Lisp`之根源](http://daiyuwen.freeshell.org/gb/rol/roots_of_lisp.html) 74 | - [创造者的鉴赏力](http://daiyuwen.freeshell.org/gb/taste/taste.html) 75 | - [`Lisp`的永恒之道](http://coolshell.cn/articles/7526.html) 76 | - [为什么`Lisp`语言如此先进?(译文)](http://www.ruanyifeng.com/blog/2010/10/why_lisp_is_superior.html) 77 | - [`Google Common Lisp`风格指南](http://lisp.es/Google-Common-Lisp-Style-Guide/GoogleCLSG-zhCN.xml) / [Google Common Lisp Style Guide](http://google-styleguide.googlecode.com/svn/trunk/lispguide.xml) 78 | 模式意味着“我的语言不够用了。” ── *Rich Hickey* 79 | `Common Lisp`是一个强大的多范式程序语言。能力越强,责任越大。 80 | - 来自[Style guides for Google-originated open-source projects](https://code.google.com/p/google-styleguide/) 81 | `Google`各种语言的代码风格指南。 82 | - [`LISP` - 维基百科](http://zh.wikipedia.org/wiki/LISP) 83 | - [`Common Lisp` - 维基百科](http://zh.wikipedia.org/wiki/Common_Lisp) 84 | 85 | ### `lisp`书籍 86 | 87 | - [`ANSI Common Lisp`中文版](http://acl.readthedocs.org/en/latest/zhCN/index.html) 88 | - [`The Common Lisp Cookbook`](http://cl-cookbook.sourceforge.net/index.html) 89 | - [通向`Lisp`之路 - 书籍豆列](http://book.douban.com/doulist/1128439/) 90 | - [想要学习`Lisp`,应该看哪些书、上哪些论坛呢? - 知乎](http://www.zhihu.com/question/19621539) 91 | - [学习 `LISP` 有哪些网站或书籍推荐? - 知乎](http://www.zhihu.com/question/19711404) 92 | 93 | ### 已有的资料汇编 94 | 95 | - [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl) 96 | 97 | ### 个人整理资料 98 | 99 | - [`Lisp`书籍推荐和点评](https://github.com/oldratlee/translations/blob/master/recommend-lisp-books/README.md) 100 | - 特别提一下[学习`lisp`的书籍推荐](https://github.com/oldratlee/translations/blob/master/recommend-lisp-books/recommend-lisp-books.md)。这篇文章难能可贵地点评了几本书的风格和优劣。 101 | 让我知道**_Successful Lisp: How to Understand and Use Common Lisp_**这本入门的好书。[在线版](http://psg.com/~dlamkins/sl/contents.html) / [`PDF`版](http://ebixio.com/online_docs/SuccessfulLisp.pdf) 102 | 由于`LISP`与其它语言从**基本概念**就开始的差异,已有的语言经验反而是个学习阻碍,深入浅出的巧妙讲解对入门太重要了。 103 | -------------------------------------------------------------------------------- /lisp-practice/lisp-web-app-quick-start.md: -------------------------------------------------------------------------------- 1 | Lisp Web App Quick Start 2 | ============================== 3 | 4 | 从零开始,给出完整运行起一个`Lisp` `web`框架`clack`的`Hello World`应用的步骤。 5 | 6 | 安装`Lisp`环境 7 | ------------------------ 8 | 9 | ```bash 10 | brew install sbcl 11 | ``` 12 | 13 | 这里安装的是`sbcl`([Steel Bank Common Lisp](http://www.sbcl.org/))。 14 | 15 | 安装`Quicklisp`库管理器 16 | ------------------------ 17 | 18 | ### 下载`Quicklisp` 19 | 20 | ```bash 21 | curl -O http://beta.quicklisp.org/quicklisp.lisp 22 | ``` 23 | 24 | ### 加载`Quicklisp`运行`sbcl` 25 | 26 | ```bash 27 | sbcl --load quicklisp.lisp 28 | ``` 29 | 30 | ### 在`sbcl`中完成安装`Quicklisp` 31 | 32 | ```lisp 33 | (quicklisp-quickstart:install :path "/Users/jerry/.quicklisp/") 34 | ``` 35 | 36 | > 注意1: 37 | 缺省是安装在`$HOME/quicklisp/`,如果安装到`$HOME/.quicklisp/` 38 | ```lisp 39 | (quicklisp-quickstart:install :path "/Users/jerry/.quicklisp/") 40 | ``` 41 | 注意把`/Users/jerry/.quicklisp/`换成你的`HOME`目录的路径。 42 | 43 | > 注意2: 44 | 如果已经安装过了并有了`Quicklisp`的目录,则执行 45 | ```lisp 46 | (load #P"/Users/jerry/quicklisp/setup.lisp") 47 | ``` 48 | 后面是字符串是`/setup.lisp`。 49 | 50 | ### 缺省加载`Quicklisp` 51 | 52 | ```lisp 53 | (ql:add-to-init-file) 54 | ``` 55 | 这样退出了`sbcl`再进入会自动加载`Quicklisp`,省得手动重复加载过程。 56 | 57 | > 注意1: 58 | 退出`sbcl`可以用: 59 | ```lisp 60 | (quit) 61 | ``` 62 | 63 | 运行`clack`框架的`Hello World`应用 64 | ------------------------ 65 | 66 | ### 导入`clack`库 67 | 68 | ```lisp 69 | (ql:quickload :clack) 70 | ``` 71 | 72 | 第一次会触发下载`clack`,需要一些时间。 73 | 74 | ### 启动`Hello World`应用 75 | 76 | ```lisp 77 | (clack:clackup 78 | (lambda (env) 79 | (declare (ignore env)) 80 | '(200 (:content-type "text/plain") ("Hello, Clack!")))) 81 | ``` 82 | 83 | 访问,可以看到`Hello, Clack!`。 84 | 85 | ### 关闭`HTTP`服务 86 | 87 | ```lisp 88 | (clack:stop *) 89 | ``` 90 | 91 | 参考资料 92 | ------------------------ 93 | 94 | - [Quicklisp](http://www.quicklisp.org/beta/) 95 | - [Making a small Lisp project with quickproject and Quicklisp](http://xach.livejournal.com/278047.html) 96 | - [Getting Clack](http://clacklisp.org/tutorial/02-getting-clack.html) 97 | - [Clack](http://clacklisp.org/) 98 | -------------------------------------------------------------------------------- /lisp-practice/lisp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/lisp-practice/lisp.png -------------------------------------------------------------------------------- /machine-learning-knowledge-points/those-machine-learning-knowledge-points-that-tormented-newbies-v0.1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/machine-learning-knowledge-points/those-machine-learning-knowledge-points-that-tormented-newbies-v0.1.pptx -------------------------------------------------------------------------------- /multi-response-async-request-pattern-analysis-model/README.md: -------------------------------------------------------------------------------- 1 | > 写于 2021-04-13。 2 | 3 | # 多响应异步请求模式下需求满足的分析模型 4 | 5 | # 〇、多响应异步请求模式下请求过程的描述方式 6 | 7 | 先说明一下请求过程的描述方式。请求过程可以描述成: 8 | 9 | 10 | 11 | > 本文用图的[源文件](graphs.graffle) 12 | 13 | 对于多个请求,依序类推编号: 14 | 15 | - **`Request2`**:第2个请求 16 | - **`M2Local`**:第2个请求的本地主响应;**`M2Remote`**:第2个请求的远程主响应 17 | - **`A21`**:第2个请求的第1个副响应;**`A22`**:第2个请求的第2个副响应 18 | 19 | # 多响应请求模式的分析模型 20 | 21 | ## 1.1 请求的3个关注维度:`CRC` 22 | 23 | - **完整性**(**`Completeness`**) 24 | - 指 获取到的数据 是否与 实际的**数据条目数**一致,是不是完整的。 25 | 比如,总共有10条数据,10条全取到?只取到9条?一条数据取到了所有字段? 26 | - 注:在思考交流过程中,完整性 也会想到/说成『一致性(`consistency`)』。这里不使用『一致性』这个用语的原因是:『一致性』也常指 数据是否正确性,会与后面的『正确性』形成歧义。 27 | - **响应性**(**`Responsiveness`**) 28 | - 指 **用户等待时长** / **返回时延**(`RT`)。 29 | - 关于**跳变**:多响应异步请求模式下,在用户体验上,大家会提到的 一个关键关注问题。 30 | - 视觉跳变/`UI`跳变,即 开始时没有显示一个UI组件,过会儿数据来了又显示了(如特价飘条、相关商品推荐随手加购的`UI`控件)。 31 | - 跳变 可以理解成:全部的数据中,有一部分的数据获取/展示出来的时间更长。 32 | 即 跳变 可以统一化归为 (局部)数据的`RT`问题。 33 | - 注:在思考交流过程中,响应性 也会想到/说成『用户体验(`user experience`)』。这里不使用『用户体验』这个用语的原因是: 34 | - 体验是个综合的感受,不只是一些数据定性定量的逻辑。 35 | - **体验满意度 = 期望体验 — 实际体验。** 36 | 比如 期望(1秒打开、价格直观、界面优雅……) **—** 实际(3秒打开、价格复杂、界面土气……)。 37 | - 体验作为用户与产品接触的综合的感受,其中包含的**用户期望部分**的管理往往独立于技术的分析与实现。 38 | - 除了响应性,完整性、正确性的好坏也一样会影响用户体验,即体验用语可以理解成一个最终结果,其实可以包含影响产品好坏的一切! 🤣 39 | - **正确性**(**`Correctness`**) 40 | - 指 **数据的值** 是否正确,比如是不是过时的。 41 | - 注:在思考交流过程中,正确性 也会想到/说成『错误容忍(`fault tolerant`)』。这里不使用『错误容忍』这个用语的原因是:『错误容忍』常用于表达系统稳定性/可用性,而不是数据的正确性。 42 | 43 | ## 1.2 `CRC`也是请求的平衡维度 44 | 45 | 所谓平衡是指:当不可兼得时,可互相置换。 46 | 47 | 48 | 49 | **请求所关注与平衡的`CRC`维度模型 也一样适用于 同步请求模式,并不耦合 多响应异步请求模式。** 50 | 51 | 只是多响应异步请求模式下的复杂性,在分析上对请求维度模型的需要变得迫切了。 52 | 53 | 我们可以用请求维度`CRC`模型作为 引入多响应异步请求模式后对产品/用户体验的优化程度 的一种度量方式。 54 | 55 | 多响应/异步的模式下,相对于传统的同步模式,可以为业务提供了更灵活方便的策略,如 56 | 57 | - 放弃一些数据完整性:对非顶级功能的数据,可以引入一定的等待时间(体验),等待超时后不则展示。 58 | 即可以用一些`RT`(体验损失) 和 完整性 来换 无跳变的体验提升。 59 | - TODO etc. 60 | 61 | ## 1.3 为什么`CRC`是关于请求完备的关注与平衡维度 62 | 63 | 从外部观察来请求响应的数据获取: 64 | 65 | - 首先是,**数据有没有获取到**,完整性问题 66 | - 在多响应异步请求模式下,可以更方便地选择获取部分数据,其中顶级功能的数据是最必需的。 67 | - 对于获取到的数据: 68 | - 数据是不是正确的(比如过时了),正确性问题 69 | - 数据的获取花了多长时间/用户等待了多久,响应性问题。 70 | 71 | 至此,数据获取的观察过程结束。 72 | 73 | # 二、问题 74 | 75 | ## 2.1 请求多返回/异步化模式带来的`UI`跳变问题 76 | 77 | 因为异步化返回副响应,可能在主响应之后返回。业务会表现出 视觉跳变/`UI`跳变。 78 | 79 | **视觉跳变/`UI`跳变**,即 开始时没有显示一个UI组件,过会儿又显示了(如特价飘条、随手加购`UI`控件)。 80 | 81 | 由上面说明可以看出,出现跳变,与是否多个请求无关。 82 | 一个请求时也一样会出现跳变;当请求的副响应是主响应之后返回时,就会出现跳变。 83 | 84 | 对于**一个请求**,说明 跳变过程如下: 85 | 86 | 1. 请求的主响应返回,展示上屏,不包含特价飘条的数据,不显示 特价飘条 87 | 1. 副响应返回(包含如特价飘条的数据),上屏展示 特价飘条 88 | 89 | 跳变(开始时**不显示**过会儿**又显示**了)是个 体验不好的点。 90 | 作为一个 响应性问题(见上文请求维度分析),解决的策略有: 91 | 92 | - **通过正确性来置换;如可以通过 打底数据 来 解决跳变的问题。** 打底数据 比如用上次请求的返回的数据。 93 | - 打底数据 是 过时数据(当前请求返回的响应数据才是最新的正确),带来了正确性问题。 94 | - **通过完整性来置换;如放弃这个数据/组件的显示可以**。 95 | - 实际实现上可以更细腻一些:可以引入一定的等待时间(体验),等待超时后不则展示。 96 | 97 | 关于 **通过正确性来置换**:展示 过时不正确的数据,业务上可能有严重问题与影响。 98 | 99 | 比如 副响应展示的优惠券: 100 | 101 | - 前一次请求的响应,优惠是100元 102 | - 调整选购的商品列表后,优惠是30元。 103 | - 如果显示了 优惠100元(避免跳变),一段时间内不正确,用户下单了,就会带来舆论问题。 104 | - 考虑到副响应是可能丢的(即正确的『优惠是30元』不会返回以更新展示正确), 105 | 可能一直显示的是错误的『优惠100元』。 106 | 107 | ## 2.2 多个请求的响应时序引发的相关问题 108 | 109 | `Request`模块 解决了是一个请求的主副响应之间的时序问题。 110 | 仍需要解决下面的多个请求之间的问题。 111 | 112 | ### 2.2.1 多个请求之间副响应时序不可控引起的冲突问题 113 | 114 | 目前的需求,多个请求的主响应一定不存在数据冲突的问题: 115 | 116 | - 要么,操作是独立的,即请求的响应(主响应&副响应)是无关数据 117 | - 要么,在业务侧通过请求阻塞的方式,保证了2个请求的主响应之间是有序的 118 | 119 | **不同请求的副响应之间的返回时序是无法保证的**。 120 | 121 | 当 前一个请求的副响应 可以在 后一个请求的副响应 之后返回时,会需要带来下面问题: 122 | (按上面请求流程描述方式,即是 **`A1x`** 在 **`A2x`** 之后返回。) 123 | 124 | 对应的多个请求及其响应的时序如下: 125 | 126 | 127 | 128 | > 因为不涉及多个主响应引起的问题,上面的示意图中,主响应简化成一个;副响应简化成一个。 129 | 130 | 如果2个请求的副响应的数据之间是冲突的,前一个请求的副响应(过时响应)生效了导致冲突。 131 | 132 | - 后一个请求来了后,前一个请求的副响应是过时的不能再用(如上屏)。 133 | 134 | 带来业务问题/Bug。 135 | **需要丢弃过时响应(之前请求的副响应)以避免上面的问题。** 136 | 137 | ### 2.2.2 主响应数据覆盖上一个请求副响应时显示跳变的问题 138 | 139 | 例:奥创回收场景(购物车勾选)场景,上一个请求的副响应(过时响应,如特价飘条的副响应、`A11`)在当前请求(`R2`)或它的响应(`M2`、`A21`)之后到达,有数据冲突(不正确性)与 跳变问题。 140 | 141 | 1. 展示第二个请求的主响应(`M2`),不包含特价飘条的数据,不显示特价飘条 142 | 1. 上屏上一个请求的副响应(`A11`,包含特价飘条的数据),显示特价飘条 143 | - 不是当前上屏了的主数据对应的副响应,数据不正确 144 | - 跳变(开始时**不显示**过会儿**又显示**了特价飘条);注意跳变问题,一个请求时也会发生。 145 | 3. 上屏当前一个请求的副响应(`A21`,包含特价飘条的数据),显示特价飘条: 146 | - 变化,因为2份副响应数据不相同 147 | 148 | 对应的多个请求及其响应的时序如下: 149 | 150 | 151 | 152 | > 因为不涉及多个主响应引起的问题,上面的示意图中,主响应简化成一个;副响应简化成一个。 153 | 154 | 对于过时响应(`A11`)是否上屏 **只有**2种选择:上屏 or 不上屏。 155 | 156 | - 如果上屏 157 | - 减少了特价飘条的空窗时间。 158 | - 上屏了一份不正确的数据。 159 | - 为保证数据正确性,用当前请求的响应肯定要覆盖是合理的,主响应的业务组件数据必须再次下发数据对前序副数据做替换。 160 | - 如果不上屏: 161 | - 数据保证一直是正确的。 162 | - 特价飘条的空窗时间变长。 163 | 164 | ### 2.2.3 多个请求的响应时序的问题总结 165 | 166 | 可以看到上面的2个问题,都是过时响应(之前请求的副响应)引起问题的2种情况。 167 | 168 | > 其实**只有**上面的2种情况: 169 | > 170 | > - 过时响应,在当前请求对应副响应(`A21`)之后返回(问题1)。 171 | > - 过时响应,在当前请求的副响应(`A21`)之前 & 当前请求(`Request2`)发起之后返回(问题2)。 172 | 173 | 总结:之前请求返回的辅响应,都属于过时响应。 174 | -------------------------------------------------------------------------------- /multi-response-async-request-pattern-analysis-model/graphs.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/multi-response-async-request-pattern-analysis-model/graphs.graffle -------------------------------------------------------------------------------- /multi-response-async-request-pattern-analysis-model/images/1618292665069-9fc78672-1655-43ea-842e-6b210f4c8a73.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/multi-response-async-request-pattern-analysis-model/images/1618292665069-9fc78672-1655-43ea-842e-6b210f4c8a73.jpeg -------------------------------------------------------------------------------- /multi-response-async-request-pattern-analysis-model/images/1618293290350-ce2483ac-9a28-4995-9024-37f5747519e4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/multi-response-async-request-pattern-analysis-model/images/1618293290350-ce2483ac-9a28-4995-9024-37f5747519e4.jpeg -------------------------------------------------------------------------------- /multi-response-async-request-pattern-analysis-model/images/1618379271816-ae9bdff5-9990-44c3-8983-023ca4841f04.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/multi-response-async-request-pattern-analysis-model/images/1618379271816-ae9bdff5-9990-44c3-8983-023ca4841f04.jpeg -------------------------------------------------------------------------------- /multi-response-async-request-pattern-analysis-model/images/1620446578486-1114da0f-c3c7-4996-bbee-e34345c5bbfe.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/multi-response-async-request-pattern-analysis-model/images/1620446578486-1114da0f-c3c7-4996-bbee-e34345c5bbfe.jpeg -------------------------------------------------------------------------------- /practice-of-software-reliability-design/服务框架的可靠性设计与实践-2017-08-12.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/practice-of-software-reliability-design/服务框架的可靠性设计与实践-2017-08-12.pptx -------------------------------------------------------------------------------- /practice-of-software-reliability-design/软件可靠性设计的实践-v0.9.2.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/practice-of-software-reliability-design/软件可靠性设计的实践-v0.9.2.pptx -------------------------------------------------------------------------------- /product-logic-for-platform-product/README.md: -------------------------------------------------------------------------------- 1 | > 写于 2021-06-07。 2 | 3 | # 平台产品逻辑与执行 4 | 5 | 本文要讨论与说明的是: 6 | 7 | - 整理:平台产品的基本逻辑与注意点。即**平台产品逻辑、常识**。 如目标、产品关键。 8 | - 避免:忽视平台产品基本逻辑而带来平台产品推动的困境。即**平台产品的执行推动方式**。如对业务的支撑与协同的要求。 9 | 10 | > 平台产品 指 如公共设施、移动基础服务。 11 | > 12 | > 从产品视角,产品/功能 会包含下面几个关注方面: 13 | > 14 | > 1. **产品模型:设计合理性** 15 | > - **即回答 用户为什么要用产品/功能?** 16 | > - **是不是** 需求?业务需求的合理性。(这部分本文档暂不讨论) 17 | > - **能不能 满足需求,可行性下的功能实现程度 是不是够的?** 18 | > 2. **合作模式:收益合理性** 19 | > - **涉及几方角色;各方的收益、投入/风险是什么,各方能不能配合运作起来(各方的ROI足够)?** 20 | > - PS:这条本来叫 『商业模式:盈利合理性』;这里讨论平台产品,改写成了『合作模式:收益合理性』 21 | > 3. 环境:拓展合理性(这部分本文档不讨论) 22 | > - 市场状况拓展性:市场竞争、技术变化、政策影响 23 | > - 产品逻辑拓展性:能支撑衍生什么功能? 24 | > 4. 团队:实施合理性(这部分本文档不讨论) 25 | > - 如 执行能力匹配? 26 | > 27 | > PS: 上面的产品关注方面 摘自《[从点子到产品](https://book.douban.com/subject/26927349/)》 CH1 点子到方案 28 | 29 | ---------------------------------------- 30 | 31 | 32 | 33 | 34 | 35 | - [一、关于 业务产品 vs. 平台产品](#%E4%B8%80%E5%85%B3%E4%BA%8E-%E4%B8%9A%E5%8A%A1%E4%BA%A7%E5%93%81-vs-%E5%B9%B3%E5%8F%B0%E4%BA%A7%E5%93%81) 36 | - [1.1 业务方引入平台产品的变化](#11-%E4%B8%9A%E5%8A%A1%E6%96%B9%E5%BC%95%E5%85%A5%E5%B9%B3%E5%8F%B0%E4%BA%A7%E5%93%81%E7%9A%84%E5%8F%98%E5%8C%96) 37 | - [平台产品要担责的约定/范围/条件](#%E5%B9%B3%E5%8F%B0%E4%BA%A7%E5%93%81%E8%A6%81%E6%8B%85%E8%B4%A3%E7%9A%84%E7%BA%A6%E5%AE%9A%E8%8C%83%E5%9B%B4%E6%9D%A1%E4%BB%B6) 38 | - [1.2 平台应该做什么?](#12-%E5%B9%B3%E5%8F%B0%E5%BA%94%E8%AF%A5%E5%81%9A%E4%BB%80%E4%B9%88) 39 | - [为什么用 全接管/透明的平台功能来作为平台目标?](#%E4%B8%BA%E4%BB%80%E4%B9%88%E7%94%A8-%E5%85%A8%E6%8E%A5%E7%AE%A1%E9%80%8F%E6%98%8E%E7%9A%84%E5%B9%B3%E5%8F%B0%E5%8A%9F%E8%83%BD%E6%9D%A5%E4%BD%9C%E4%B8%BA%E5%B9%B3%E5%8F%B0%E7%9B%AE%E6%A0%87) 40 | - [二、平台产品对业务的支撑与协同的要求](#%E4%BA%8C%E5%B9%B3%E5%8F%B0%E4%BA%A7%E5%93%81%E5%AF%B9%E4%B8%9A%E5%8A%A1%E7%9A%84%E6%94%AF%E6%92%91%E4%B8%8E%E5%8D%8F%E5%90%8C%E7%9A%84%E8%A6%81%E6%B1%82) 41 | - [三、FaaS透明化运行时升级为例的一些具体讨论](#%E4%B8%89faas%E9%80%8F%E6%98%8E%E5%8C%96%E8%BF%90%E8%A1%8C%E6%97%B6%E5%8D%87%E7%BA%A7%E4%B8%BA%E4%BE%8B%E7%9A%84%E4%B8%80%E4%BA%9B%E5%85%B7%E4%BD%93%E8%AE%A8%E8%AE%BA) 42 | - [运行时升级 是不是 全接管平台功能(透明的)?](#%E8%BF%90%E8%A1%8C%E6%97%B6%E5%8D%87%E7%BA%A7-%E6%98%AF%E4%B8%8D%E6%98%AF-%E5%85%A8%E6%8E%A5%E7%AE%A1%E5%B9%B3%E5%8F%B0%E5%8A%9F%E8%83%BD%E9%80%8F%E6%98%8E%E7%9A%84) 43 | - [关于 无人值守的运行时升级](#%E5%85%B3%E4%BA%8E-%E6%97%A0%E4%BA%BA%E5%80%BC%E5%AE%88%E7%9A%84%E8%BF%90%E8%A1%8C%E6%97%B6%E5%8D%87%E7%BA%A7) 44 | - [关于升级问题的一些业界典型思路与做法](#%E5%85%B3%E4%BA%8E%E5%8D%87%E7%BA%A7%E9%97%AE%E9%A2%98%E7%9A%84%E4%B8%80%E4%BA%9B%E4%B8%9A%E7%95%8C%E5%85%B8%E5%9E%8B%E6%80%9D%E8%B7%AF%E4%B8%8E%E5%81%9A%E6%B3%95) 45 | - [三、产品主题相关资料](#%E4%B8%89%E4%BA%A7%E5%93%81%E4%B8%BB%E9%A2%98%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99) 46 | - [PS:一些补充讨论](#ps%E4%B8%80%E4%BA%9B%E8%A1%A5%E5%85%85%E8%AE%A8%E8%AE%BA) 47 | 48 | 49 | 50 | ---------------------------------------- 51 | 52 | # 一、关于 业务产品 vs. 平台产品 53 | 54 | - **平台产品** 55 | - 作为业务的支撑角色,完成业务产品中的一部分**通用功能**(即**平台化的功能**)。 56 | - 与业务产品/同学一起 才能 完成业务价值的交付。 57 | - **业务产品** 58 | - 对于这部分被平台化的功能,在没有平台产品介入之前,完全由业务自己来支撑,即只有一个负责方。 59 | - 对于(平台化的)功能所解决的问题,要解决到什么程度 及 问题后果的承担,可以根据业务当前的实际情况阶段,由业务产品/同学自己来动作决策与职责承担。 60 | - 决策的动作:如 是否升级XXX。 61 | - 承担的职责:如 升级出了的故障由谁如何承担。 62 | - 由于动作与担责 是主体是同一个,产品出了问题时 不会出现 模糊不清的跟进与如何担责的扯皮。 63 | - **担责的扯皮 会极度影响平台产品的用户口碑、发展与落地。** 64 | - 背后的关键 是 65 | - **业务对平台产品/功能的要求、产品的SLA 是什么?** 66 | - **为什么要达到这样的要求?** 67 | - 值得整理说明清楚,让做平台产品的成员都理解并达成共识,以保证平台产品有效的执行、落地与推动。 68 | 69 | ## 1.1 业务方引入平台产品的变化 70 | 71 | 当一个功能 由业务产品自己来承担 迁移到 由平台产品时,会发生一系列的变化。 72 | 73 | ![image.png](product-arch.png) 74 | 75 | 业务引入一个平台产品后: 76 | 77 | - 分离 原来业务自己管理的一部分**功能**到 平台产品中。 78 | - 引入一个新角色 平台方,是一个新的**担责主体**。 79 | - 当出问题时,业务方就会想:是不是由平台方来担责? 80 | 81 | PS: 平台产品的职责还可以进一步分离成 产品实现方 和 产品运维方,本文不再展开。 82 | 83 | ### 平台产品要担责的约定/范围/条件 84 | 85 | 平台产品要担责的约定/范围/条件是什么呢? 86 | 87 | 当符合下面的条件,出的问题由平台产品方来担责: 88 | 89 | - 涉及 平台提供/接管的功能 90 | - 平台主动的 平台功能变更/操作 引起 91 | 即不通知业务、不是业务方触发的,会说成 对于业务的透明的变更/操作。 92 | 93 | > 上面的只是 确定由平台担责的那一部分。 94 | > 当条件不这么强时,往往需要Case-By-Case与业务方聊。 95 | > 96 | > TODO 上面条件的描述 需要逐步细化、优化。 97 | 98 | 上面只是初步的陈述,大家可以来优化这个上面的整理说明。 99 | 100 | ## 1.2 平台应该做什么? 101 | 102 | **长期需要Case-By-Case与业务聊担责的功能,即不能业务透明接管的功能,不合适由平台产品来实现。** 103 | 104 | > 这里的**长期**是指: 105 | > 106 | > - 不是 受限于平台的短期节奏/投入,当下还没有去做好的功能; 107 | > - 而是 平台产品解好不可行的功能,比如因为技术不可行等等有核心复杂性,往往业界没有案例无进展。 108 | 109 | 原因是 110 | 111 | - 规模化是平台产品的价值体现的必然路径。 112 | - 而 不业务透明的平台功能 会锁死 平台产品的发展: 113 | - 人力支撑的一定比例投入,当规模大了,Case-By-Case的支撑 线性消耗了 团队的投入,不具备扩展性。 114 | - 有一定比例风险,当规模大了,风险量会超出一个平台产品能承担的上限。 115 | 116 | 接管业务的平台功能做到透明 是指: 117 | 118 | - **无需业务团队成员的成本投入** 119 | - **无需业务方承担操作风险** 120 | 121 | 即 **全接管业务的功能**: 122 | 123 | - 是平台的目标;直接体现了平台的核心竞争力。 124 | - 全接管业务的平台功能的多少/比例 可以用来度量 平台的成熟程度。 125 | 126 | ### 为什么用 全接管/透明的平台功能来作为平台目标? 127 | 128 | 上面直接关注 **全接管平台功能(透明的)** 的说法 听起来过硬了啊!**部分接管的平台功能(不透明)**,不也能提效业务、也能让平台能有竞争力(相对业务方自己承担)吗? 129 | 130 | 嗯,上面的思考方式听起来是很自然的;多数人在开始做产品时肯定也是这么想的,并会这样去指导做平台产品的展开。 131 | 132 | 之所以用**更严格**的『**全接管的平台功能**』来作为平台目标,原因是: 133 | 134 | - 用更严格的『全接管/透明的平台功能』,对于产品,表达力可以是一样的。表达转换的方式如下: 135 | - 对于一个『**部分接管的平台功能**』可以进一步拆解小功能。 136 | - 其中会包含**全接管的小功能**,就是大功能能提效业务的原因。 137 | - 结合上面『不能业务透明的功能,不合适由平台产品来实现』,实际上 138 | - 对于『**部分接管的平台功能**』,平台做的是**整合工作**而不是**接管**,并没有规模化的平台产品价值; 139 | - 平台产品会做这样的整合工作,是为了透出『**全接管的平台功能**』的平台价值,吸引用户来用。 140 | - 且 这样更严格的方式 能 141 | - 能简单有效地判断 产品的成熟程度/竞争力。 142 | - 也能更好引导 每个做产品的同学积极发现 平台产品发展的关键点。 143 | 144 | > 上面关于『**平台功能的全接管**』回答了上面的『担责扯皮』背后的关键: 145 | > 146 | > - **业务对平台产品/功能的要求、产品的SLA 是什么?** 147 | > - **为什么要达到这样的要求?** 148 | 149 | 总结上面所说的成一句话: 150 | 在平台产品功能中,要区分 哪些是接管的功能,哪些是整合的功能。 151 | 152 | # 二、平台产品对业务的支撑与协同的要求 153 | 154 | - 在平台产品功能中,要区分 哪些是接管的功能,哪些是整合的功能。 155 | - **对于一个平台功能的实现程度 是可以分级;一个平台功能可以再分拆来看。** 156 | - 比如 FaaS平台的运行时升级: 157 | - 如果FaaS运行时升级 不是 接管透明(不能可靠保证升级后业务没有问题)。 158 | - 但其中 升级的执行过程/步骤 这个子功能 平台可以做到接管透明,可以提效业务。 159 | - 对于平台关键的『**全接管透明功能**』: 160 | - **无需业务团队成员的成本投入、无需业务方承担操作风险;引发的问题由平台担责。** 161 | - **对于全接管的功能,要承担风险,也获得对应的KPI。平台方不能有给予者心态。** 162 | - 比如 FaaS平台的运行时升级 不能要求 业务先保证提供完备的业务测试Case。 163 | - 平台产品并不是救人危难的给予者,只不过是业务使用一个组件,也收获了平台自己的KPI。 164 | - 像平台触发的变更,但要求业务有完整Case,背后隐含了给予心态,对业务提非分要求(业务监控要完整 )。假想一下: 165 | - 你是业务,业务监控/回归Case多点少点,我自己兜风险、看投入与节奏、看团队成员水平,不能保证完备。 166 | - FaaS自己的监控敢说完整不? k8s 变更 对FaaS提监控/回归Case要完备的要求? 167 | - 对于平台上部分接管的整合功能: 168 | - **明确说明 业务要关注的事项,哪些问题平台不能担责,避免担责扯皮。** 169 | 170 | # 三、FaaS透明化运行时升级为例的一些具体讨论 171 | 172 | > TODO 173 | > 174 | > 下面具体『透明化运行时升级』Case的讨论,与 上面泛化的平台产品的思考 175 | > 还要互相对照 的 梳理整理…… 176 | 177 | ## 运行时升级 是不是 全接管平台功能(透明的)? 178 | 179 | 上面一节提到的是 功能能否 全接管/透明 是平台产品发展与竞争力的关键,是关于平台产品功能的前提关键问题。 180 | 181 | **不能做到 透明化运行时升级。** 这个判断,原因如下: 182 | 183 | 1. 如果 依赖了 涉及业务同学的功能回归,才能保证升级稳定性,则不是透明的(不是一个平台化功能): 184 | - 涉及业务功能的回归,而 回归业务是个业界难题,判断**长期不可能透明解决**。 185 | - 业务的 回归Case 与 监控指标,一定不能 保证回归就是安全的。 186 | - 因为故障原因 五花八门,回归Case、业务指标再多,也不能保证发现问题。 187 | - **像 软件无bug、监控无死角,都只是理想。** 188 | - 业务自己回归的执行方式: 189 | - 功能回归会有人肉业务测试;(自动化)业务回归case往往不多、更不能说完整。 190 | - 业务同学 Case-By-Case结合业务当下的实际情况,来确定 回归的执行程度。 191 | - 即 回归业务 需要业务方参与,不能透明。 192 | 2. FaaS平台的运行时升级 不能要求 业务先保证提供完备的业务测试Case。 193 | - 接了活 就要承担风险,平台并不是救人危难的给予者,只不过是业务 使用一个组件,也收获了平台自己的KPI。 194 | - 像平台触发的变更,但要求业务有完整Case,背后隐含了给予心态,对业务提非分要求(业务监控要完整 )。 195 | - 假想一下: 196 | - 你是业务,业务监控/回归Case多点少点,我自己兜风险、看投入与节奏、看团队成员水平,不能保证完备。 197 | - FaaS自己的监控敢说完整不? k8s 变更 对FaaS提监控/回归Case要完备的要求? 198 | - 不管是为了平台、还是为了业务,动了都是变更。 199 | - 只要是平台的变更引起的,故障是平台的。 200 | - Noah变更/升级有问题,业务故障算Noah的。 201 | - FaaS运行时透明升级有问题,业务故障算FaaS的。 202 | - FaaS不能对业务的监控完备提要求。平台的变更是平台的锅,别问业务指标够不够。 203 | - 这是业务方的自然心态;也是对平台方的要求。 204 | - 否则出了故障,就会出现下面的局面: 205 | - 平台方觉得,业务同学不体量 206 | - 业务方觉得,平台同学想的太简单、不厚道 207 | 208 | ### 关于 无人值守的运行时升级 209 | 210 | - 是否『无人值守』是在说明提效方式,没有说明『为什么 升级的回归是可靠的?』。 211 | - 说明提效/无人前,先要说明是否可靠/稳,不是 过渡不过渡方案的问题。 212 | 213 | ## 关于升级问题的一些业界典型思路与做法 214 | 215 | - 应用的依赖升级 是 业务应用变更,不是平台变更。 216 | - 大家有了共识,边界清楚 217 | - 可执行:业务自己来执行回归;避开了『业务方来做业务回归/保证稳』这个不可能完成的任务 218 | - 运行时有多个版本又会怎样? 真是问题吗? 219 | - 不要简单过快回答。 220 | - 上面的讨论说明,另一面的路(由业务保证回归 & 统一升级 的方式),在产品逻辑上不可行。 221 | - 问题:业务没有升级,出了平台老bug。如何解决定责? 222 | - 对 长时间组件老版本/有问题的组件版本 223 | - 发出升级公告、邮件群发 224 | - 说明 组件问题、平台免责。强调风险和后果要自负。 225 | - 这就是像`FastJson`这样基础组件平时的做法。 226 | - 上面是关于平台组件升级,业界的典型做法与出路;一般称为『夕阳条款』。 227 | - 平台不可能无限期支持老组件与组件老版本,所以有『夕阳条款』是合理的。 228 | 229 | # 三、产品主题相关资料 230 | 231 | - 微信之父张小龙内部100多页PPT,全面剖析微信背后的产品观 232 | - 文字版 [https://www.cnblogs.com/end/p/5521138.html](https://www.cnblogs.com/end/p/5521138.html) 、[文字版2](https://www.vshouce.com/wechat-ppt.html);[PPT图片版](https://www.163.com/dy/article/FQ230RUA051998SC.html) 233 | - ![image.png](zxl.png) 234 | 作为可能的注意项 看看/想想,挺有用有意思的 235 | 236 | # PS:一些补充讨论 237 | 238 | 业务回归测试也是一种手段,更原始的需求或许是:发布期间的异常检测。 239 | 240 | 从『透明化运行时升级』功能/需求的涉及的『业务回归测试』 到 『发布异常检测』功能/需求, 241 | **是对于用户/业务需求、产品功能的一次思考、演进与变化:更加确定 实现功能及其程度是业务需要的。** 242 | 243 | 下面展开一些的具体讨论: 244 | 245 | > 展开讨论 是想再次表达本文档目标,即 246 | > 247 | > - 关键前提的产品逻辑 值得先想清楚、反复思辨深入 (虽然是分析的事都只是像在纸上谈兵、 沙盘推演)。 248 | > - 避免投入后回头才发现因产品逻辑不对不能期望地透出产品价值,成本相比就高得去了。 249 | 250 | 像『发布异常检测』这样的功能 251 | 252 | - 可以逐步提升的检测宽度与有效性 253 | - 对用户/业务是 好的加分项 254 | - 如果接入成本低,业务会积极用上 255 | - 比较没 故障的担责风险(具体还要看这个功能的做的程度与SLA) 256 | 257 | 初步看起来,做这个功能必要&可能。也相信这个功能做精,本身就可以很有竞争力。 258 | 259 | 像『发布异常检测』这样的技术建设会有很多,可能比较分散,可能可以有机的结合起来。整合也不是个简单的事: 260 | 261 | - 相信心底里大家不喜欢用『整合』这个词,总是个二等公民。😬 262 | - 对一个『整合』的理解/探索到位了,『整合』 263 | - 会变成一个新能力 264 | - 或 孵化出/发现 一个被忽视的关键的新能力 265 | - 这个新能力 会成为 产品的Core。 266 | 267 | **我们能不能清楚表达描述 这个现在还不存在的新能力,或许可以用来判断 我们的产品逻辑/理解 是不是清楚了。** 268 | 269 | 但如果要执行投入,还可以要问下面的问题: 270 | 271 | - 这个功能做了业务用户喜欢/主动要来用,功能实现程度的拐点是什么? 272 | 即产品功能的爆点 觉得 会在哪儿? 273 | - 这么明显的诉求,相信大家(无论是业务团队/还是平台团队)不难想到。那么 274 | - 这个能力 业界做的如何? 275 | - 旁边可以用的对应产品是哪些?做如何?用户用的如何? 276 | - 为什么对于这个明显诉求的能力,平时好像没有听到过? 277 | - 是因为已有的做得不好?这个功能做到有用程度不可行? 278 | - 还是做的太好了?(应该并不是这个原因 :")我们做 是不是没什么空间了? 279 | - …… 280 | 281 | 大家在论证产品逻辑时,会出现这样的逻辑: 282 | 283 | > - 退化为:运行时升级(通知)工具。我们或许短期需要这样的“工具”,但长期一定不是的。 284 | > - 这样的工具,其实解决问题提很有限,因为真正耗费「开发者」精力的部分是观察和测试。 285 | > - 而且规模化之后统一升级的负面影响更大: 286 | > - 规模化之后平台产品团队很快会成为资源瓶颈,到时候如果没有真正的科技进步,就必须开倒车:把控制权再次交还给「业务开发人员」。 287 | 288 | 上面的『长期一定不是的』这样的结论/观点,像是在表达是在表达『愿望』,而不逻辑。😄 289 | 说明了『运行时升级(通知)工具』的做法会有发展限制问题,但并没有说明 与对工具对应的平台做法 可行。 290 | 291 | 『A不行』并不能推出『在A对面的B就可行是方向』。 292 | 即 排除法 对于不确定的规划的事 是不适用的,因为 事情是不是有解/整体组合功能是不是能发展出来 还是未知的。 293 | 294 | 产品逻辑 推演要包含给出 如何『做成』一个产品(可行性),而不仅是给出 为什么要『要做』一个产品(有需求)。 295 | 296 | 像下面这样的逻辑说明: 297 | 298 | > - 运行时升级工具(集中式)是需要耗费FaaS产品的人力进行对齐的(平台方式是必要的)…… 299 | > - 如果没有真正的科技进步,就必须开倒车。…… 300 | 301 | 说明的是工具做法的问题,逻辑是在说明 平台必要性,即论证的是 为什么我们要平台做法。 302 | 对于产品逻辑的目标 平台做法能『做成』并没有说明。 303 | 304 | 值得被充分展开说明,做产品的同学们能有传达思考与理解。 305 | 306 | > 的确是这样的,bug出其不意、错误五花八门,指标再多也会漏,但人同样不能保证。 307 | > 308 | > 同时人能保证的那部分一定可以转化为规则或标准,通过自动化执行规则大概率比人执行的好。 309 | 310 | 会越来越规则化/标准化 、 比人肉好更有效 、提效,我也是赞成的。 311 | 312 | 当然,平台+规范可以让测试更全面。一定程度上也是倒逼更好的编码风格。 313 | 314 | 『倒逼更好的编码风格』这样的事想想了意思一下就好~ 🤤 对于做一个产品就别当真了。 315 | (即不能是做成的产品的前提,也不要让产品多个无助成功但分散投入的目标。) 316 | -------------------------------------------------------------------------------- /product-logic-for-platform-product/product-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/product-logic-for-platform-product/product-arch.png -------------------------------------------------------------------------------- /product-logic-for-platform-product/zxl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/product-logic-for-platform-product/zxl.png -------------------------------------------------------------------------------- /rpc-intro/rpc-intro-v0.3.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/rpc-intro/rpc-intro-v0.3.pptx -------------------------------------------------------------------------------- /software-engeering.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/software-engeering.pptx -------------------------------------------------------------------------------- /system-load-calculation-and-looks/README.md: -------------------------------------------------------------------------------- 1 | # 🚦How to calculate system load, and what it looks like 2 | 3 | 4 | 5 | - What system load looks like? 6 | see [**_`what-system-load-look-like.ipynb`_**](what-system-load-look-like.ipynb) 7 | - How to calculate system load? 8 | see [**_`load.py`_**](load.py) 9 | 10 | ![What system load looks like?](https://user-images.githubusercontent.com/1063891/77147814-229e6c80-6ac9-11ea-931a-b198395c52a9.png) 11 | -------------------------------------------------------------------------------- /system-load-calculation-and-looks/load.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from numpy import exp 4 | import numpy as np 5 | 6 | 7 | def _update_load(load, task_counts, load_period, update_period=5): 8 | """ 9 | Formula from article 10 | Load和CPU利用率是如何算出来的 11 | http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html 12 | 13 | load1 = load1 * exp(-5 / 60) + n * (1 - exp(-5 / 60)) 14 | load5 = load5 * exp(-5 / 300) + n * (1 - exp(-5 / 300)) 15 | load15 = load15 * exp(-5 / 900) + n * (1 - exp(-5 / 900)) 16 | 17 | :param load_period seconds 18 | :param update_period seconds, default 5 secs 19 | """ 20 | beta = exp(-update_period / load_period) 21 | # Exponential moving average 22 | # https://en.wikipedia.org/wiki/Moving_average 23 | alpha = 1 - beta 24 | return task_counts * alpha + load * (1 - alpha) 25 | 26 | 27 | def loads(task_count, load_period, update_period=5): 28 | load = 0 29 | ret = np.zeros(len(task_count)) 30 | 31 | for idx, n in enumerate(task_count[:-1]): 32 | load = _update_load(load, task_count[idx], load_period, update_period) 33 | ret[idx + 1] = load 34 | 35 | return ret 36 | 37 | 38 | def load1s(task_count): 39 | return loads(task_count, 60) 40 | 41 | 42 | def load5s(task_count): 43 | return loads(task_count, 60 * 5) 44 | 45 | 46 | def load15s(task_count): 47 | return loads(task_count, 60 * 15) 48 | -------------------------------------------------------------------------------- /system-load-calculation-and-looks/system-load-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldratlee/software-practice-thoughts/837d3a0e60f48a8efc088228aafedf08f106fdae/system-load-calculation-and-looks/system-load-icon.png -------------------------------------------------------------------------------- /what-is-my-wanted-blog-system/README.md: -------------------------------------------------------------------------------- 1 | 我要的Blog系统 2 | ========================== 3 | 4 | `Markdown`集成友好 5 | ---------------------- 6 | 7 | `Markdown`对于写作来说,几乎是公认的简单高效、友好。所以保留`Markdown`的使用方式是一等公民。 8 | 9 | 这里列到使用方式,主要来自在`Github`的`Markdown`使用过程中觉得舒服的。 10 | 11 | 1. 支持相对路径的图片、附件。 12 | 2. `Markdown`的文件路径 自动映射到 `URL`上。 13 | 即支持完整的URL自定义。 14 | 15 | 上面说的就是方便自然的文件管理。 16 | 17 | Blog的标准功能 18 | --------------------- 19 | 20 | 1. 支持RSS 21 | 2. 支持评论 22 | 23 | 24 | 高级功能 25 | -------------------- 26 | 27 | - 发布时,支持把图片加速转换。 28 | 如上传到图床(如七牛),并用图床中的图片URL。 29 | 30 | 参考资料 31 | ---------------- 32 | 33 | - [hexo你的博客](http://ibruce.info/2013/11/22/hexo-your-blog/) 34 | --------------------------------------------------------------------------------