写一本关于编程的书,是我大概15年前就有的一个想法,当时,我体会到了编程中数据结构的美妙和神奇,有一种收获的喜悦和分享的冲动。这种收获是我反复阅读教程十几遍,花大量时间上机练习调试得到的,这是一个比较痛苦的过程。我想,如果把我学到的知识更为清晰易懂地表达出来,其他人不就可以掌握编程容易一些,并体会到那种喜悦了吗?不过,当时感觉自己学识太浅,要学习的东西太多,想一想也就算了。
触发我开始写作是在2016年年初,可汗学院的事迹震撼了我。可汗学院的创始人是萨尔曼·可汗,他自己录制了3000多个短视频,主要教中小学生基础课。他为每门课程建立了知识地图,地图由知识点组成,知识点之间有依赖关系。每个知识点都有一个视频,每个视频10分钟左右,他的讲解清晰透彻,极受欢迎。比尔·盖茨声称可汗是他最欣赏的老师,邀请其在TED发表演讲,同时投资可汗成立了非营利机构可汗学院,可汗也受到了来自谷歌等公司的投资。可以说,可汗以一己之力推动了全世界的教育。
我就想,我可不可以学习可汗,为计算机编程教育做一点事情?也就是说,为编程的核心知识建立知识地图,从最基础的概念开始,分解为知识点,一个知识点一个知识点地讲解,每一个知识点都力争清晰透彻,阐述知识点是什么、怎么用、有什么用途、实现原理是什么、思维逻辑是什么、与其他知识点有什么关系等。可汗的形式是视频,但我想先从文字总结开始。我希望表达的是编程的通用知识,但编程总要用一个具体语言,我想就用我最熟悉的Java吧。
过去十几年,Java一直是软件开发领域最主流的语言之一,在可以预见的未来,Java还将是最主流的语言之一。但关于Java编程的书比比皆是,也不乏经典之作,市场还需要一本关于Java编程的书吗?甚至,还需要编程的书吗?如果需要,需要什么样的书呢?
关于编程的需求,我想答案是肯定的。过去几十年,IT革命深刻地改变了人们的生活,但这次革命还远远没有停止,在可以预见的未来,人工智能等前沿技术必将进一步改变世界,而要掌握人工智能技术,必须先掌握基本编程技术。人工智能在我国已经上升为国家战略。2017年7月,国务院印发了《新一代人工智能发展规划》,其中提到“实施全民智能教育项目,在中小学阶段设置人工智能相关课程,逐步推广编程教育”,未来,可能大部分人都需要学习编程。
关于编程的书是很多,但对于非计算机专业学生而言,掌握编程依然是一件困难的事情。绝大部分教程以及培训班过于追求应用,读者学完之后虽然能照着例子写一些程序,但却懵懵懂懂,知其然而不知其所以然,无法灵活应用,当希望进一步深入学习时,发现大部分专业书籍晦涩难懂,难以找到通俗易懂的与学过的应用相结合的进阶原理类书籍。
即使计算机专业的学生,学习编程也不容易。学校开设了很多理论课程,但学习理论的时候往往感觉比较枯燥,比如二进制、编码、数据结构和算法、设计模式、操作系统中的线程和文件系统知识等。而学习具体编程语言的时候,又侧重学习的是语法和API。学习计算机理论的重要目的是为了更好地编程,但学生却难以在理论和编程之间建立密切的联系。
这样,我的想法基本就确定了,用Java语言写一本帮助理解编程到底是怎么回事的书,尽量用通俗易懂的方式循序渐进地介绍编程中的主要概念、语法和类库,不仅介绍用法和应用,还剖析背后的实现原理,以与基础理论相结合,同时包含一些实用经验和教训,并解释一些更为高层的框架和库的基本原理,以与实践应用相结合,在此过程中,融合编程的一些通用思维逻辑。
我有能力写好吗?我并不是编程大师,但我想,可汗也不是每个领域的大师,但他讲授了很多领域的知识,的确帮助了很多人。过去十几年我一直从事编程方面的工作,也在不断学习和思考,我想,只要用心写,至少会给一些人带来一点帮助吧。
于是,我在2016年3月创建了微信公众号“老马说编程”,开始发布系列文章“计算机程序的思维逻辑”。每一篇文章对我都是一个挑战,每一个知识点我都花大量时间用心思考,反复琢磨,力求表达清晰透彻,做到最好。写作是一个痛苦和快乐交织的过程,最痛苦的就是满脑子都是相关的内容,但就是不知道该怎么表达的时候,而最快乐的就是写完一篇文章的时候。令人欣慰的是,这些文章受到了大量读者的极高评价,他们的溢美之词、自发分享和红包赞赏进一步增强了我写作的信心和动力。到2017年7月底,共写了95篇文章,关于Java编程的基本内容也就写完了。
在写作过程中,很多读者反馈希望文章可以尽快整理成书,以便阅读。2016年9月,机械工业出版社的高婧雅女士联系到了我,商讨出版的可能,在她的鼎力帮助和出版社的大力支持下,就有了大家看到的这本书。
本书致力于帮助读者真正理解Java编程。对于每个语言特性和API,不仅介绍其概念和用法,还分析了为什么要有这个概念,实现原理是什么,背后的思维逻辑是什么;对于类库,分析了大量源码,使读者不仅知其然,还知其所以然,以透彻理解相关知识点。
本书虽然是Java语言描述,但以更为通用的编程逻辑为主,融入了很多通用的编程相关知识,如二进制、编码、数据结构和算法、设计模式、操作系统、编程思维等,使读者不仅能够学习Java语言,还可以提升整体的编程和计算机水平。
本书不仅注重实现原理,而且重视实用性。本书介绍了很多实践中常用的技术,包含不少实际开发中积累的经验和教训,使读者可以少走一些弯路。在实际开发中,我们经常使用一些高层的系统程序、框架和库,以提升开发效率,本书也介绍了如何利用基本API开发一些系统程序和框架,比如键值数据库、消息队列、序列化框架、DI(依赖注入)容器、AOP(面向切面编程)框架、热部署、模板引擎等,讲解这些内容的目的不是为了“重新发明轮子”,而是为了帮助读者更好地理解和应用高层的系统程序与框架。
本书高度注重表述,尽力站在读者的角度,循序渐进、简洁透彻,从最基本的概念开始,一步步推导出更为高级的概念,在介绍每个知识点时,都会尽力先介绍用法、示例和应用,再分析实现原理和思维逻辑,并与其他知识点建立联系,以便读者能够容易地、全面透彻地理解相关知识。
本书侧重于Java编程的主要概念,绝大部分内容适用于Java 5以上的版本,但也包含了最近几年Java的主要更新,包括Java 8引入的重要更新—Lambda表达式和函数化编程。
本书面向所有希望进一步理解编程的主要概念、实现原理和思维逻辑的读者,具体来说有以下几种。
本书分为六大部分,共26章内容。
第一部分(第1~2章)介绍编程基础与二进制。第1章介绍编程的基础知识,包括数据类型、变量、赋值、基本运算、条件执行、循环和函数。第2章帮助读者理解数据背后的二进制,包括整数的二进制表示与位运算、小数计算为什么会出错、字符的编码与乱码。
第二部分(第3~7章)介绍面向对象。第3章介绍类的基础知识,包括类的基本概念、类的组合以及代码的基本组织机制。第4章介绍类的继承,包括继承的基本概念、细节、实现原理,分析为什么说继承是把双刃剑。第5章介绍类的一些扩展概念,包括接口、抽象类、内部类和枚举。第6章介绍异常。第7章剖析一些常用基础类,包括包装类、String、StringBuilder、Arrays、日期和时间、随机。
第三部分(第8~12章)介绍泛型与容器及其背后的数据结构和算法。第8章介绍泛型,包括其基本概念和原理、通配符,以及一些细节和局限性。第9章介绍列表和队列,剖析ArrayList、LinkedList以及ArrayDeque。第10章介绍各种Map和Set,剖析HashMap、HashSet、排序二叉树、TreeMap、TreeSet、LinkedHashMap、LinkedHashSet、EnumMap和EnumSet。第11章介绍堆与优先级队列,包括堆的概念和算法及其应用。第12章介绍一些抽象容器类,分析通用工具类Collections,最后对整个容器类体系从多个角度进行系统总结。
第四部分(第13~14章)介绍文件。第13章主要介绍文件的基本技术,包括文件的一些基本概念和常识、Java中处理文件的基本结构、二进制文件和字节流、文本文件和字符流,以及文件和目录操作。第14章介绍文件处理的一些高级技术,包括一些常见文件类型的处理、随机读写文件、内存映射文件、标准序列化机制,以及Jackson序列化。
第五部分(第15~20章)介绍并发。第15章介绍并发的传统基础知识,包括线程的基本概念、线程同步的基本机制synchronized、线程协作的基本机制wait/notify,以及线程的中断。第16章介绍并发包的基石,包括原子变量和CAS、显式锁与显式条件。第17章介绍并发容器,包括写时复制的List和Set、ConcurrentHashMap、基于跳表的Map和Set,以及各种并发队列。第18章介绍异步任务执行服务,包括基本概念和实现原理、主要的实现机制线程池,以及定时任务。第19章介绍一些专门的同步和协作工具类,包括读写锁、信号量、倒计时门栓、循环栅栏,以及ThreadLocal。第20章对整个并发部分从多个角度进行系统总结。
第六部分(第21~26章)介绍动态与函数式编程。第21章介绍反射,包括反射的用法和应用。第22章介绍注解,包括注解的使用、创建,以及两个应用:定制序列化和DI容器。第23章介绍动态代理的用法和原理,包括Java SDK动态代理和cglib动态代理以及一个应用:AOP。第24章介绍类加载机制,包括类加载的基本机制和过程,ClassLoader的用法和自定义,以及它们的应用:可配置的策略与热部署。第25章介绍正则表达式,包括语法、Java API、一个简单的应用(模板引擎),最后剖析一些常见表达式。第26章介绍Java 8引入的函数式编程,包括Lambda表达式、函数式数据处理、组合式异步编程、以及Java 8的日期和时间API。
对于有一定经验的读者,可以挑选感兴趣的章节直接阅读。而对于初学者,建议从头阅读,但对于一些比较深入的原理性内容,以及一些比较高级的内容,如果理解比较困难可以跳过,有一定实践经验后再回头阅读。任何读者都可以将本书作为一本案头参考书,以备随时查阅不确定的概念、用法和原理。
由于作者的水平有限,编写时间仓促,书中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果您有更多的宝贵意见,欢迎您关注我的微信公众号“老马说编程”,在后台留言,在“关于”部分,也有最新的微信和QQ群信息,欢迎加入讨论,我会尽量提供满意的解答。同时,您也可以通过邮箱swiftma@sina.com联系到我,期待能够得到你们的真挚反馈,在技术之路上互勉共进。
感谢我的微信公众号“老马说编程”、掘金、开发者头条和博客园技术社区的广大读者,他们的极高评价、自发分享和红包赞赏让我备受鼓舞,更重要的是,他们指出了很多文章中的错误,使我可以及时修正。
感谢掘金和开发者头条技术社区,他们经常推荐我的文章,使更多人可以看到。
感谢我在北京理工大学学习时的老师和同学们,在老师的教导和同学们的探讨中,我掌握了比较扎实的计算机基础,特别是我的已故恩师古志民教授,古教授指导我完成了本科到博士的学业,他严谨认真的学术态度深深地影响了我。
感谢我工作以来的领导和同事们,由于他们的言传身教,我得以不断提高自己的技术水平。
感谢机械工业出版社的编辑高婧雅,在一年多的时间中始终支持我的写作,她的帮助和建议引导我顺利完成全部书稿。
特别感谢我的爱人吴特和儿子久久,我为写作这本书,牺牲了很多陪伴他们的时间,但也正因为有了他们的付出与支持,我才能坚持写下去。
特别感谢我岳父母,特别是我的岳母,不遗余力地帮助我们照顾儿子,有了他们的帮助和支持,我才有时间和精力去完成写作工作。
特别感谢我的父母,他们在困难的生活条件下,付出了巨大的汗水与心血,将我养育成人,使我能够完成博士学业,他们一生勤劳朴素的品质深深地影响了我。
特别感谢我的兄长马俊杰,他一直是我成长路上的指明灯,也是从他的耐心讲解中,我第一次了解到了计算机的基本工作机制。
谨以此书献给我最亲爱的家人,以及众多热爱编程技术的朋友们!
马俊昌