**Title: **学习C++:实践者的方法(Beta1)
**Reference: **http://blog.csdn.net/pongba/article/details/1930150
**Keynote: **
- 重读此文
- 有些业界的有身份的专家还是在一本接一本的出语言孔乙己的书(写一些普通程序员八辈子用不着的技巧和碰不着的角落)
- 每个人都喜欢戴着脚镣跳舞。
- 目前大多数C++学习者的态度和方法是什么呢?——在真正用C++之前看上一摞语言书(日常编程八辈子都未必用得到)。而为什么会存在这样的学习态度呢?这就是真正需要解释的问题。
- CSAPP &TCPL& AC++&TC++PL
- 重复第一点
**Title: **你应当如何学习C++(以及编程)(rev#1)
**Reference: **http://blog.csdn.net/pongba/article/details/1611593
**Keynote: **
- 一是C++语言的细节太多。二是一些著名的C++书籍总在(不管有意还是无意)暗示语言细节的重要性和有趣。三是现代C++库的开发哲学必须用到一些犄角旮旯的语言细节(但注意,是库设计,不是日常编程)
- C++中众多的细节虽然在库设计者手里面有其用武之地,但普通程序员则根本无需过多关注,尤其是没有实际动机的关注。
- C++的书,Bjarne的圣经《The C++ Programming Language》是高屋建瓴的。《大规模C++程序设计》是挺务实的。《Accelerated C++》是最佳入门的。《C++ Templates》是仅作参考的。《C++ Template Metaprogramming》是精力过剩者可以玩一玩的,普通程序员碰都别碰的。避免去过问任何语言细节,除非必要。
- 至于这种抠语言细节的哲学为何能在社群里面呈野火燎原之势,就是一个心理学的问题了。想像人们在论坛上讨论问题时,一个对语言把握很细致的人肯定能够得到更多的佩服,而由于论坛上的问题大多是小问题,所以解决实际问题的真正能力并不能得到显现,也就是说,知识型的人能够得到更多佩服,后者便成为动力和仿效的砝码。《你的灯还亮着吗?》一书中有讲到人们沉迷于解决问题的过程中的乐趣,而不是结果。
- 重要的是这个磨练过程,而不是结果,要的是你粗壮的腿,而不是你身上背的那袋盐巴。
- 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 二进制兼容》 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: **银弹和我们的职业
**Reference: **http://blog.csdn.net/g9yuayon/article/details/1437195
**Keynote: **我们得把时间用于学习解决本质困难。新技术给高手带来方便。菜鸟们却不用指望被新技术拯救。沿用以前的比喻,一流的摄影师不会因为相机的更新换代而丢掉饭碗,反而可能借助先进技术留下传世佳作。因为摄影的本质困难,还是摄影师的艺术感觉。热门技术也就等于相机。不停追新,学习这个框架,那个软件,好比成天钻研不同相机的说明书。而热门技术后的来龙去脉,才好比摄影技术。为什么推出这个框架?它解决了什么其它框架不能解决的问题?它在哪里适用?它在哪里不适用?它用了什么新的设计?它改进了哪些旧的设计?
**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: **达达-高性能服务端优化之路
**Reference: **https://tech.imdada.cn/2015/11/04/高性能服务端优化之路/
**Keynote: **在业务发展的各个阶段的决策与权衡。
- 作为创业公司,最重要的一点是敏捷,快速实现产品,对外提供服务,于是我们选择了公有云服务,保证快速实施和可扩展性,节省了自建机房等时间。
- 随着业务的发展,访问量的极速增长,上述的方案很快不能满足性能需求。数据库俨然已成为瓶颈,我们必须得快速做架构升级。实现读写分离后,数据库的压力减少了许多,CPU使用率和IO使用率都降到了5%内,Slow Query也趋近于0。当然,没有一个方案是万能的。读写分离,暂时解决了Mysql压力问题,同时也带来了新的挑战。主从延迟。
- 这时,主库成为了性能瓶颈,我们意识到,必需得再一次做架构升级,将主库做拆分,一方面以提升性能,另一方面减少系统间的相互影响,以提升系统稳定性。垂直分库过程,我们也遇到不少挑战,最大的挑战是:不能跨库join,同时需要对现有代码重构。单库时,可以简单的使用join关联表查询;拆库后,拆分后的数据库在不同的实例上,就不能跨库使用join了。
- 以前,系统压力逼迫我们架构升级,这一次,我们需提前做好架构升级,实现数据库的水平扩展(sharding)。
- 创业是与时间赛跑的过程,前期为了快速满足业务需求,我们采用简单高效的方案,如使用云服务、应用服务直接访问单点DB;后期随着系统压力增大,性能和稳定性逐渐纳入考虑范围,而DB最容易出现性能瓶颈,我们采用读写分离、垂直分库、水平分库等方案。面对高性能和高稳定性,架构升级需要尽可能超前完成,否则,系统随时可能出现系统响应变慢甚至宕机的情况。