**Title: **學(xué)習(xí)C++:實(shí)踐者的方法(Beta1)
**Reference: **http://blog.csdn.net/pongba/article/details/1930150
**Keynote: **
- 重讀此文
- 有些業(yè)界的有身份的專家還是在一本接一本的出語(yǔ)言孔乙己的書(shū)(寫(xiě)一些普通程序員八輩子用不著的技巧和碰不著的角落)
- 每個(gè)人都喜歡戴著腳鐐跳舞。
- 目前大多數(shù)C++學(xué)習(xí)者的態(tài)度和方法是什么呢?——在真正用C++之前看上一摞語(yǔ)言書(shū)(日常編程八輩子都未必用得到)。而為什么會(huì)存在這樣的學(xué)習(xí)態(tài)度呢?這就是真正需要解釋的問(wèn)題。
- CSAPP &TCPL& AC++&TC++PL
- 重復(fù)第一點(diǎn)
**Title: **你應(yīng)當(dāng)如何學(xué)習(xí)C++(以及編程)(rev#1)
**Reference: **http://blog.csdn.net/pongba/article/details/1611593
**Keynote: **
- 一是C++語(yǔ)言的細(xì)節(jié)太多。二是一些著名的C++書(shū)籍總在(不管有意還是無(wú)意)暗示語(yǔ)言細(xì)節(jié)的重要性和有趣。三是現(xiàn)代C++庫(kù)的開(kāi)發(fā)哲學(xué)必須用到一些犄角旮旯的語(yǔ)言細(xì)節(jié)(但注意,是庫(kù)設(shè)計(jì),不是日常編程)
- C++中眾多的細(xì)節(jié)雖然在庫(kù)設(shè)計(jì)者手里面有其用武之地,但普通程序員則根本無(wú)需過(guò)多關(guān)注,尤其是沒(méi)有實(shí)際動(dòng)機(jī)的關(guān)注。
- C++的書(shū),Bjarne的圣經(jīng)《The C++ Programming Language》是高屋建瓴的?!洞笠?guī)模C++程序設(shè)計(jì)》是挺務(wù)實(shí)的。《Accelerated C++》是最佳入門(mén)的。《C++ Templates》是僅作參考的?!禖++ Template Metaprogramming》是精力過(guò)剩者可以玩一玩的,普通程序員碰都別碰的。避免去過(guò)問(wèn)任何語(yǔ)言細(xì)節(jié),除非必要。
- 至于這種摳語(yǔ)言細(xì)節(jié)的哲學(xué)為何能在社群里面呈野火燎原之勢(shì),就是一個(gè)心理學(xué)的問(wèn)題了。想像人們?cè)谡搲嫌懻搯?wèn)題時(shí),一個(gè)對(duì)語(yǔ)言把握很細(xì)致的人肯定能夠得到更多的佩服,而由于論壇上的問(wèn)題大多是小問(wèn)題,所以解決實(shí)際問(wèn)題的真正能力并不能得到顯現(xiàn),也就是說(shuō),知識(shí)型的人能夠得到更多佩服,后者便成為動(dòng)力和仿效的砝碼?!赌愕臒暨€亮著嗎?》一書(shū)中有講到人們沉迷于解決問(wèn)題的過(guò)程中的樂(lè)趣,而不是結(jié)果。
- 重要的是這個(gè)磨練過(guò)程,而不是結(jié)果,要的是你粗壯的腿,而不是你身上背的那袋鹽巴。
- Obviously, C++ is very complex. Obviously, people get lost. However, most peple get lost when they get diverted into becoming language lawyers rather than getting lost when they have a clear idea of what they want to express and simply look at C++ language features to see how to express it. Once you know data absreaction, class hierarchies (object-oriented programming), and parameterization with types (generic programming) in a fairly general way, the C++ language features fall in place.
- 重讀此文。
**Title: **The Law of Leaky Abstractions
**Reference: **http://www.joelonsoftware.com/articles/LeakyAbstractions.html
**Keynote: **TCP attempts to provide a complete abstraction of an underlying unreliable network, but sometimes, the network leaks through the abstraction and you feel the things that the abstraction can't quite protect you from. This is but one example of what I've dubbed the Law of Leaky Abstractions.
**Title: **What is Application Binary Interface (ABI)?
**Reference: **http://stackoverflow.com/questions/2171177/what-is-application-binary-interface-abi
**Keynote: **
- When you write source code, you access the library though an API. Once the code is compiled, your application accesses the binary data in the library through the ABI. The ABI defines the structures and methods that your compiled application will use to access the external library (just like the API did), only on a lower level.
- Two versions of a library that have the same ABI are sometimes called "binary-compatible" since they have the same low-level interface (you should be able to replace the old version with the new one and not have any major problems).
**Related Resources: **《4 二進(jìn)制兼容》 CppPractice.pdf 陳碩.
**Title: **The C++ Style Sweet Spot
**Reference: **http://www.artima.com/intv/goldilocks.html
**Keynote: **
-
Climbing Above C-Level.
Writing C-style code is one way to get into C++, but it's not using C++ really well. -
Object-Orientaphilia
Don't be too low-level or too enamored with object-orientation. I particularly dislike classes with a lot of get and set functions. That is often an indication that it shouldn't have been a class in the first place. It's just a data structure. -
Classes Should Enforce Invariants
When you start breaking it down like that, you get into the possibilities of different representations. You can start deciding, does it really add to have private data, to have a hierarchy? Do you want a plain class with one representation to deal with, or do you want to provide an abstract interface so you can represent things in different ways? But you have to make those design decisions. You don't just randomly spew classes and functions around. And you have to have some semantics that you are defending before you start having private data. -
Designing Simple Interfaces
Then you get these five or ten operations, and you can build the other 50 in a supporting library. That way of thinking is fairly well accepted these days. Even in Java, you have the containers and then the supporting library of static methods.
**Title: **Modern C++ Style
**Reference: **http://www.artima.com/intv/modern3.html
**Keynote: **
- Multiple Inheritance and Pure Abstract Classes
- Multi-Paradigm Programming
- Resource Acquisition is Initialization
**Title: **Abstraction and Efficiency
**Reference: **http://www.artima.com/intv/abstreffi.html
**Keynote: **
- Raising the Level of Abstraction
You get this beautiful case where your code gets clearer, shorter, and faster. It doesn't happen all the time, of course, but it is so beautiful when it does. - Programming is Understanding
If you don't understand something, you can't code it, and you gain understading trying to code it. - Premature or Prudent Optimization
You also try to have higher abstractions so you can measure something concrete.
There's not a fixed set of operations you use to manipulate it, sometimes data is access directly from user code "for efficiency". In that case, your profiler won't show you where the bottleneck is, because you have scattered the code across the program.
**Title: **Elegance and Other Design Ideals
**Reference: **http://www.artima.com/intv/elegance.html
**Keynote: **
- Thinking Before You Code
- Thinking in Libraries
- What to Leave In, What to Leave Out
In C++, I have tended to build into in the language facilities that are abstraction mechanisms. So contrary to some languages, I have not put in an advanced vector, because I could do that in a library with the facilities provided by the language. I didn't provide a string with special facilities for string manipulation. Instead, I put in general mechanisms that allow you to write a string class. I didn't put in properties because you can write a properties class. - Protecting People From Themselves
C was designed with the principle that you should be able to write its standard library in the language itself. That same principle guided the design of C++. - Design Beyond Imagination
- Premature Generalization
- Ugly Syntax for Ugly Operations
static_cast... - Elegance and Other Design Ideals
**Title: **The Perils of Duck Typing
**Reference: **http://beust.com/weblog/2005/04/15/the-perils-of-duck-typing/
**Keynote: **Another danger in the Duck Typing approach is that it makes it really hard to see what the contract is between callers and callees. Use Duck Typing for prototyping, but program to interfaces for anything else.
**Title: **Generic Programming - What are you, anyway?
**Reference: **http://blog.csdn.net/pongba/article/details/1715263
**Keynote: **
- The gist of generic programming is finding commonality, and abstracting (or, lifting), such that one implementation can fit them all.
- Nominal Subtyping vs. Structural Subtyping
- The problem was: is GP an essentially new abstraction mechanism? Well, it depends on the way you look at it. If you look at it as a naturally perfect way to abstract procedural code (algorithms), as opposed to the fact that OO is the natural way to abstract entitative code (data structures), then yes, it is a new abstraction mechanism. However, if you look at it as a supplemental way of archiving efficiency, loose-coupling, and type-safety, which OO doesn’t get, in reusable algorithm development, then it is no new thing.
- Abstraction Penalty.
**Title: **銀彈和我們的職業(yè)
**Reference: **http://blog.csdn.net/g9yuayon/article/details/1437195
**Keynote: **我們得把時(shí)間用于學(xué)習(xí)解決本質(zhì)困難。新技術(shù)給高手帶來(lái)方便。菜鳥(niǎo)們卻不用指望被新技術(shù)拯救。沿用以前的比喻,一流的攝影師不會(huì)因?yàn)橄鄼C(jī)的更新?lián)Q代而丟掉飯碗,反而可能借助先進(jìn)技術(shù)留下傳世佳作。因?yàn)閿z影的本質(zhì)困難,還是攝影師的藝術(shù)感覺(jué)。熱門(mén)技術(shù)也就等于相機(jī)。不停追新,學(xué)習(xí)這個(gè)框架,那個(gè)軟件,好比成天鉆研不同相機(jī)的說(shuō)明書(shū)。而熱門(mén)技術(shù)后的來(lái)龍去脈,才好比攝影技術(shù)。為什么推出這個(gè)框架?它解決了什么其它框架不能解決的問(wèn)題?它在哪里適用?它在哪里不適用?它用了什么新的設(shè)計(jì)?它改進(jìn)了哪些舊的設(shè)計(jì)?
**Title: **Python Success Stories
**Reference: **https://www.python.org/about/success/esr/
**Keynotes: **
- One course I did not consider was going back to C as a default language. the days when it made sense to do your own memory management in a new program are long over, outside of a few specialty areas like kernel hacking, scientific computing and 3-D graphics -- places where you absolutely must get maximum speed and tight control of memory usage, because you need to push the hardware as hard as possible. For most other situations, accepting the debugging overhead of buffer overruns, pointer-aliasing problems, malloc/free memory leaks and all the other associated ills is just crazy on today's machines. Far better to trade a few cycles and a few kilobytes of memory for the overhead of a scripting language's memory manager and economize on far more valuable human time.
- An important measure of effort in coding is the frequency with which you write something that doesn't actually match your mental representation of the problem, and have to backtrack on realizing that what you just typed won't actually tell the language to do what you're thinking. An important measure of good language design is how rapidly the percentage of missteps of this kind falls as you gain experience with the language. When you're writing working code nearly as fast as you can type and your misstep rate is near zero, it generally means you've achieved mastery of the language. Most languages have so much friction and awkwardness built into their design that you learn most of their feature set long before your misstep rate drops anywhere near zero. Python was the first general-purpose language I'd ever used that reversed this process.
- Perl still has its uses. For tiny projects (100 lines or fewer) that involve a lot of text pattern matching, I am still more likely to tinker up a Perl-regexp-based solution than to reach for Python. For good recent examples of such things, see the timeseries and growthplot scripts in the fetchmail distribution. Actually, these are much like the things Perl did in its original role as a sort of combination awk/sed/grep/sh, before it had functions and direct access to the operating system API. For anything larger or more complex, I have come to prefer the subtle virtues of Python -- and I think you will, too.
**Title: **So You Want to be a Functional Programmer
**Reference: **https://medium.com/@cscalfani/so-you-want-to-be-a-functional-programmer-part-6-db502830403#.s1je3dr88
**Keynote: **
- Learning Functional Programming takes a while. So be patient.
Most useful Pure Functions must take at least one parameter.
All useful Pure Functions must return something.
Pure Functions will always produce the same output given the same inputs.
Pure functions have no side effects.
There are no variables in Functional Programming.
Functional Programming uses recursion to do looping.
Immutability creates simpler and safer code. - In Functional Programming, a function is a first-class citizen of the language. In other words, a function is just another value.
Higher-order Functions either take functions as parameters, return functions or both.
A closure is a function’s scope that’s kept alive by a reference to that function. - Code reuse sounds great but is difficult to achieve. Make the code too specific and you can’t reuse it. Make it too general and it can be too difficult to use in the first place.
- The order of execution in a Pure Functional Language can be determined by the compiler. This is extremely advantageous considering that CPUs are not getting faster. Instead, manufactures are adding more and more cores. This means that code can execute in parallel at the hardware level. Unfortunately, with Imperative Languages, we cannot take full advantage of these cores except at a very coarse level. But to do so requires drastically changing the architecture of our programs. With Pure Functional Languages, we have the potential to take advantage of the CPU cores at a fine grained level automatically without changing a single line of code.
**Title: **達(dá)達(dá)-高性能服務(wù)端優(yōu)化之路
**Reference: **https://tech.imdada.cn/2015/11/04/高性能服務(wù)端優(yōu)化之路/
**Keynote: **在業(yè)務(wù)發(fā)展的各個(gè)階段的決策與權(quán)衡。
- 作為創(chuàng)業(yè)公司,最重要的一點(diǎn)是敏捷,快速實(shí)現(xiàn)產(chǎn)品,對(duì)外提供服務(wù),于是我們選擇了公有云服務(wù),保證快速實(shí)施和可擴(kuò)展性,節(jié)省了自建機(jī)房等時(shí)間。
- 隨著業(yè)務(wù)的發(fā)展,訪問(wèn)量的極速增長(zhǎng),上述的方案很快不能滿足性能需求。數(shù)據(jù)庫(kù)儼然已成為瓶頸,我們必須得快速做架構(gòu)升級(jí)。實(shí)現(xiàn)讀寫(xiě)分離后,數(shù)據(jù)庫(kù)的壓力減少了許多,CPU使用率和IO使用率都降到了5%內(nèi),Slow Query也趨近于0。當(dāng)然,沒(méi)有一個(gè)方案是萬(wàn)能的。讀寫(xiě)分離,暫時(shí)解決了Mysql壓力問(wèn)題,同時(shí)也帶來(lái)了新的挑戰(zhàn)。主從延遲。
- 這時(shí),主庫(kù)成為了性能瓶頸,我們意識(shí)到,必需得再一次做架構(gòu)升級(jí),將主庫(kù)做拆分,一方面以提升性能,另一方面減少系統(tǒng)間的相互影響,以提升系統(tǒng)穩(wěn)定性。垂直分庫(kù)過(guò)程,我們也遇到不少挑戰(zhàn),最大的挑戰(zhàn)是:不能跨庫(kù)join,同時(shí)需要對(duì)現(xiàn)有代碼重構(gòu)。單庫(kù)時(shí),可以簡(jiǎn)單的使用join關(guān)聯(lián)表查詢;拆庫(kù)后,拆分后的數(shù)據(jù)庫(kù)在不同的實(shí)例上,就不能跨庫(kù)使用join了。
- 以前,系統(tǒng)壓力逼迫我們架構(gòu)升級(jí),這一次,我們需提前做好架構(gòu)升級(jí),實(shí)現(xiàn)數(shù)據(jù)庫(kù)的水平擴(kuò)展(sharding)。
- 創(chuàng)業(yè)是與時(shí)間賽跑的過(guò)程,前期為了快速滿足業(yè)務(wù)需求,我們采用簡(jiǎn)單高效的方案,如使用云服務(wù)、應(yīng)用服務(wù)直接訪問(wèn)單點(diǎn)DB;后期隨著系統(tǒng)壓力增大,性能和穩(wěn)定性逐漸納入考慮范圍,而DB最容易出現(xiàn)性能瓶頸,我們采用讀寫(xiě)分離、垂直分庫(kù)、水平分庫(kù)等方案。面對(duì)高性能和高穩(wěn)定性,架構(gòu)升級(jí)需要盡可能超前完成,否則,系統(tǒng)隨時(shí)可能出現(xiàn)系統(tǒng)響應(yīng)變慢甚至宕機(jī)的情況。