一直以来伴随我的一些学习习惯(四)——程序员的知识结构
By 刘未鹏(pongba)
C++的罗浮宫(http://blog.csdn.net/pongba)
TopLanguage(https://groups.google.com/group/pongba)
自从建立了 TopLanguage 以来,发现在上面待的时间越来越多,与高手讨论问题是个粘性十足的事情,一方面,分享自己的认识是整理不成熟的想法的极好途径,另一方面,互相之间视角不同,所以往往自己忽视的地方会被别人发现。在讨论中不断精化既有的知识体系。以下这段基本上摘抄自(略有整理和添加)在 TopLanguage 上的发言:
抓住不变量
我喜欢把知识分为essential的和non-essential的。对于前者采取提前深入掌握牢靠的办法,对于后者采取待用到的时刻RTM (Read the manual)方法(用本)。
如何区分essential和non-essential的知识想必绝大多数时候大家心里都有数,我举几个例子:对程序员来说,硬件体系结构是essential的,操作系统的一些重要的实现机制是essential的,主流编程范式(OO、FP)是为了满足什么需求出现的(出现是为了解决什么问题),是怎么解决的,自身又引入了哪些新的问题,从而适用哪些场景)。 这些我认为都是essential的。我想补充一点的是,并不是说硬件体系结构就要了解到逻辑门、晶体管层面才行(其实要了解到这个层面代价也很小,一两本好书就行了),也并不是说就要通读《Computer Architecture: Quantitative Approach》才行。而是关键要了解那些重要的思想(很长时间不变的东西),而不是很细的技术细节(易变的东西)。《Computer Systems: A Programmer’s Perspective》就是为此目的,针对程序员的需求总结出那些essential knowledge的好书。
再来说一下为什么需要预先牢靠掌握这些essential的知识:
-
根据Joel Spolsky同学的说法(原文),编程语言技术是对底层设备的封装,然而封装总是会出现漏洞的,于是程序员被迫下到“下水道”当中去解决问题,一旦往下走,漂亮的OO、N层抽象就不复存在了,这时候不具备坚硬的底层知识就会无法解决问题。简而言之就是这些底层知识会无可避免的需要用到,既然肯定会被用到那还是预先掌握的好,否则一来用到的时候再查是来不及的,因为essential的知识也往往正是那些需要较长时间消化掌握的东西,不像Ruby的mixin或closure这种翻一下manual就能掌握的东西。(英语也是这样的essential knowledge——上次在PyCN上看到一个招Python开发人员的帖子将英语列为必备技能,却并不将自然语言处理列为必备技能,正是因为英语不是可以临阵磨枪的东西,而且作为知识的主要载体,任何时候都少不了它,如果不具备英语能力,这个就会成为个人知识结构的短板或瓶颈,而且由于需要长时间才能获得这项能力,所以这个瓶颈将持续很长时间存在。我们曾经在 TopLanguage 上讨论过如何花最少的时间掌握英语)另一方面,在问题解决当中,如果不具备必要的知识,是根本无从思考的,再好的分析能力也并不是每个问题都能分析出该用哪些知识然后再去查手册的,很多时候是在工具和问题之间比较,联想,试探性的拼凑来解决问题;这就使得一个好的既有知识基变得至关重要。(实际上以上这个是一个较大的话题,希望有一天我能够把它详细展开说清:))
-
如果你不知道某个工具的存在,遇到问题的时候是很难想到需要使用这么样一个工具的,essential knowldge就是使用最为广泛的工具,编程当中遇到某些问题之后,如果缺乏底层知识,你甚至都不知道需要去补充哪些底层知识才能解决这个问题。
-
你必须首先熟悉你的工具,才能有效地使用它(须知工具的强是无敌的,但这一切得以“了解你的工具”为前提,甚至得以“了解目前可能有哪些工具适合你的问题”为前提)。一门语言,你必须了解它的适用场景,不适用场景(比如继承能解决你的问题不代表继承就是解决你的问题的最适合的方案,须知问题是一个复杂系统,解决方案总是常常引入新的问题)。你必须了解它支持的主要编程范式,此外你还必须了解它的traps和pitfalls(缺陷和陷阱,如果不知道陷阱的存在,掉进去也不知道怎么掉的。)这些都是essential knowledge,如果不事先掌握,指望用的时候查manual,是很浪费时间的,而且正如第2点所说,正因为你不知道这些知识(如适用场景),从而用sub-optimal的方式使用了一门语言自己可能还不知道(最小白的例子是,如果你不知道语言支持foreach,那么可能每次都要写一个冗长的循环,较常见的例子是不知道有很方便的库设施可以解决手头的问题所以傻乎乎的自己写了一堆代码),因为人的评价标准常常是:只要解决了最醒目的问题并且引入的新问题尚能忍受,就行。注意,熟悉并非指熟悉所有细节,而是那些重要的,或者无法在需要用到的时候按需查找的知识。比如上面提到的:适用场景不适用场景,编程范式,主要语言特性,缺陷和陷阱。
当然,以上作为程序员的essential knowledge列表并不完备,关键是自己在学习新知识的时候带着第三只眼来敏锐地判断这个知识是否是不变量,或不易变的量,是否完全可以在用的时候查手册即可,还是需要提前掌握(一些判断方法在上文也有所提及)。并且学会在纷繁的知识中抽象出那些重要的,本质的,不变的东西。我在之前的part里面也提到我在学习新知识的时候常常问自己三个问题:该知识的(体系或层次)结构是什么、本质是什么、第一原则是什么。
另外还有一些我认为是essential knowledge的例子:分析问题解决问题的思维方法(这个东西很难读一两本书就掌握,需要很长时间的锻炼和反思)、判断与决策的方法(生活中需要进行判断与决策的地方远远多于我们的想象),波普尔曾经说过:All Life is Problem-Solving。而判断与决策又是其中最常见的一类Problem Solving。尽管生活中面临重大决策的时候并不多,但另一方面我们时时刻刻都在进行最重大的决策:如:决定自己的日常时间到底投入到什么地方去。如:你能想象有人宁可天天花时间剪报纸上的优惠券,却对于房价的1%的优惠无动于衷吗?(《别做正常的傻瓜》、《Predictably Irrational》)如:你知道为什么当手头股票的股价不可抑止地滑向深渊时我们却一边揪着头发一边愣是不肯撤出吗?(是的,我们适应远古时代的心理机制根本不适应金融市场。)糟糕的判断与决策令我们的生活变得糟糕,这还不是最关键的,最关键的是我们从来不会去质疑自己的判断,而是总是能“找到”其他为自己辩护的理由(《错不在我(Mistakes were made, but not by me)》)又,现在是一个信息泛滥的时代,于是另一个问题也出现:如何在海洋中有效筛选好的信息,以及避免被不好的信息左右我们的大脑(Critical Thinking)关于以上提到的几点我在豆瓣上有一个专门的豆列(“学会思考”),希望有一天我能够积累出足够多的认识对这个主题展开一些详细介绍。
最后分享一个学习小Tip:
学习一个小领域的时候,时时把“最终能够写出一篇漂亮的Survey”放在大脑中提醒自己,就能有助于在阅读和实践的时候有意无意地整理知识的结构、本质和重点,经过整理之后的知识理解更深刻,更不容易忘记,更容易被提取。
杨军在 TopLanguage 上也曾分享了三篇非常棒的学习心得的文章,字字珠玑:
[1] 有些事情做起来比想象中容易
[2] 有关读书方法的一点想法
[3] 一件事情如果你没有说清楚,十有八九不能做好
最后告知大家,TopLanguage 最近经历了一次很大的管理策略修订,可以预期将彻底摆脱这两个月来的噪音问题,未来的讨论质量将会越来越高。详情可参见这里。
分享到:
相关推荐
- **白盒测试**(又称结构测试或逻辑驱动测试)则深入软件内部结构,侧重于代码级别的测试,如路径覆盖、条件覆盖等,主要用于结构化开发环境。这种测试方法由程序员执行,旨在检查程序逻辑和代码质量。 ### 软件...
传统编程中,程序员编写代码直接告诉计算机要做什么,而在机器学习中,程序员向计算机提供输入数据,计算机从中学习并找出规律,然后作出预测或决策。 机器学习的类型大致分为三类:监督学习、非监督学习和强化学习...
《iOS应用源码分析——基于HangmanMP-Complete项目》 在iOS开发领域,源码学习是提升技术能力的重要途径之一。本次我们关注的是由shawngrimes开发的开源项目" HangmanMP-Complete",版本号9a87414。这个项目是一个...
【C语言实验(严蔚敏教材版)】是基于经典的C语言教材——严蔚敏教授编著的《C程序设计语言》所设计的一系列实验。这本书是中国计算机教育领域的重要教材,以其清晰的语法讲解和丰富的实例深受广大程序员及学生喜爱...
2. **学习和掌握Java基础知识**:Java的面向对象特性包括封装、继承、多态等核心概念。其中: - **封装**是指将数据成员和操作这些数据的方法组合在一个类中,以达到隐藏实现细节的目的。 - **继承**允许子类继承...
《C#程序开发基础——北大青鸟S1课程实例解析》 C#,全称CSharp,是由微软公司推出的面向对象的编程语言,它在...每一步的进阶,都伴随着新的挑战和乐趣,愿你在C#的世界里探索无尽的可能性,成为一名优秀的程序员。
虽然描述中没有明确提及,但通常源代码会伴随着一些文档,如设计文档、API文档或开发者笔记,以帮助理解代码的结构和功能。这些文档对于理解和修改代码至关重要。 6. **毕业设计和课程设计**: 这些小游戏的源...
1. **源码管理**:源码是程序员编写程序的原始文本,包含了所有的函数、类、变量和控制结构。源码管理是任何项目的基础,通过版本控制系统(如Git)来跟踪代码变更、协同工作和回滚错误修改。 2. **编程语言**:...
7.1.5 伴随结构的智能帮助 300 7.1.6 RECT结构 301 7.1.7 使用指针处理结构 302 7.2 数据类型、对象、类和实例 303 7.2.1 类的起源 305 7.2.2 类的操作 305 7.2.3 术语 306 7.3 理解类 306 7.3.1 ...
【Android版宝石迷阵游戏完整源码】是一个用于学习和参考的开源项目,它提供了实现经典宝石消除游戏——宝石迷阵的全部代码。这个源码是针对Android平台编写的,适用于移动设备,可以让开发者深入了解如何在Android...
李文娟,中国石油大学(华东)硕士,现供职于国家行政学院,工作后一直从事软件开发和软件项目管理工作,对计算机语言、计算机体系结构、操作系统都非常熟悉,尤其是精通C和C++编程技术. 目录 封面 -19 封底 -18 扉页...
ChatGPT调研报告详细分析了OpenAI最新推出的人工智能工具——ChatGPT,这款工具在2022年11月30日发布后,迅速受到全球关注,成为增长最快的应用之一。ChatGPT展现出强大的语言理解和生成能力,能够准确理解用户意图...
《计算机软件商业源码分析——以“demo.zip”为例》 在信息技术日新月异的今天,源码作为软件开发的核心部分,对于理解和改进软件功能、优化系统性能具有至关重要的作用。本文将以“计算机软件-商业源码-demo.zip”...
【标题】: "一个项目源码" 涵盖了软件开发的核心元素——源代码,它是程序员用编程语言编写的、可读性强的人类指令集合。源码是软件的基石,它通过编译或解释转化为计算机能理解的机器语言,进而实现预定功能。在IT...
【标题】"助推宝优化版1.1.85源码"揭示了这是一个关于软件开发的项目,具体来说是助推宝应用的一个特定版本——1.1.85的优化源代码。源码是程序员用于创建软件的基础,它包含了程序的所有指令和逻辑,使我们能够深入...
《LeetCode习题答案解析——系统开源篇》 在编程领域,LeetCode是一个深受程序员喜爱的在线平台,它提供了一系列的编程题目,旨在提升开发者们的算法思维和编程能力。本资源包“leetcode答案-leetcode:leetcode习题...
【帕斯卡语言翻译器——开源软件的力量】 在信息技术领域,开源软件已经成为推动创新和进步的重要力量。"pas-sisw-开源"项目正是这样一个基于帕斯卡编程语言的开源翻译器,它允许开发者和爱好者们对源代码进行查看...