菜鸟笔记
提升您的技术认知

程序员修炼必读清单 ( 二)-ag真人游戏

阅读 : 789

一个优秀程序员一定不是只掌握一门编程语言,每个语言都有它的优点,同时有它的缺点,有它适应的应用场景,无论是从语言本身还是从软件工程学角度来讲。可以这么说,一个优秀的程序员,可以不依赖于任何一门开发语言,并且可以选择多种开发语言实现复杂系统。之前写过一篇好的程序员应该熟悉的几门编程语言,虽然现在语言有所发展,趋势有所变化,但大部分仍然是适用的。今天我们重拾旧题,一名优秀程序员应该熟悉以下几种编程语言:

4.1 汇编语言

程序员是跟计算机打交道的,是要用指令控制计算机,而汇编语言是控制计算机最直接的编程语言,每一行代码都是一个独立的指令,程序员可以发挥最大的聪明才智,写出最高效的代码,这些对于一些与硬件打交道的程序员是必不可少的。无论什么样的操作系统,启动代码(bootloader)都是由全部或部分的汇编语言写成的,甚至操作系统本身也有部分汇编语言代码。然而,对于一个软件项目而言,除了可行性、 性能,还要考虑一个重要的指标,就是成本,汇编语言的开发、维护成本是很高的,所以只能用在刀刃上。
2004年秋,一个朋友找到我,他在做一个电子锁的项目,之前是用汇编语言写的,大约有2万行,一个月之内就要交付项目了,否则面临着的是违约,而原来的开发人员失联了。在我看了代码之后毅然决然地决定用c语言重写,终于一个月之内,用2500的c代码完成了所有的软件功能与硬件联调测试,顺利交付到了李亚鹏家,据说装锁当天还见到了王菲(为什么没叫上我?)c与汇编语言的开发、维护成本可见一斑。
但是,只有了解了汇编,才能知道其它高级编程语言,最后是如何被解释、编译、执行的,才能知道怎样写出高效的代码。
记得2005年在做一个单片机的项目时,由于片上的rom有限,最后编译完的代码超过了rom的容量,然后就通过不断改变c语言的表达语句,争取在完成同样功能下生成的汇编代码量比较少,do-while, while, -for各种循环都试一遍,再选择一个较好的方式。如果用汇编语言更容易控制一些,不需要依赖编译器的编译水平。
现在很少用汇编的,平时用不到没必要花太多精力,但通读一遍,理解一些指令,了解一下哪些指令执行速度快,哪些指令执行速度慢是必要的,这样你才能知道在用高级语言写算法的时候为什么用移位操作代替,比如:
a = b / 8
会写成
a = b >> 3,
b = a * 8
会写成
b = (a << 3) & 0x07
因为移位操作只需要一条指令即可执行完成,除法会被转成n个减法,而乘法会被转成n次加法来实现,效率不在同一个量级上,如果是图像处理,每一像素都要进行乘除运算的话与使用移位操作来对比,处理一张图片的时间可能直接影响到一个系统的可用性,比如动态的人脸识别。

4.2 c/c

c/c 经常被放在一起,当成一种编程语言来看待,也对也不对。也为两种语言的编程思想就不太想同,c语言属于过程式编程语言,而c 则是支持面向对像编程,而两都又关系密切,所以常放在一起,但差别真的挺大,而且c 的学习难度要远大于c。关系密切就在于都有一个c,而差异在于2个加号 ,为什么是两个加号而不是一个加号,就是因为差异太大,c 是c的一个超集,在支持面向对像编程的同时,完全兼容了c语言的特性。
要学习c语言的原因在于c语言是与操作系统交互最流行最普遍的语言,所有的操作系统提供的api都是基于c语言的,然后才会在此基础上封装成其它编程语言,所以,在一些计算密集型的应用上,c/c 被广泛使用,如果主要语言采用其它语言如java或c#甚至javascript、python,对于核心的性能瓶颈处都可以通过c语言实现算法,几乎所有的其它高级编程语言都会提供与c语言的交互接口,记住,如果你在用其它的编程语言写一些比较消耗cpu的工作,如果实在解决不了性能问题,就可以考虑加一下用c/c 实现核心算法。
c/c 语言的最大优势在于对内存的控制灵活性,但最大的难度也在于对内存的管理上,一把双刃剑,练好了无敌,练不好自伤。
首先推荐的还是《c primer》,此书是c 的经典教程,书中丰富的教学辅助内容、醒目的知识点提示,以及精心组织的编程示范,让这本书在 c 领域的权威地位更加不可动摇。无论是初学者入门,或是中、高级程序员提升,本书均为不容置疑的首选。

其次,推荐《essentail c 》,该书以四个面向来表现c 的本质:procedural(面向过程的)、generic(泛型的)、object-based(基于对象的)、objectoriented(面向对象的)。全书围绕一系列逐渐繁复的程序问题,以及用以解决这些问题的语言特性来组织。循此方式,你将不只学到c 的功能和结构,也可学到它们的设计目的和基本原理。

《c 编程思想》,该书讲解深入浅出地讲解如休用c 去思考、解决问题,系统性、完整性很强。

然后建议有时间还是读一下c 之父[美] bjarne stroustrup的《the design and evolution of c 》,作者详细介绍了c 的发展史,c 语言设计的原委,可以更好了理解c 是如何被设计出来的,为什么要这么设计,怎么一步步演进的。

健壮性是代码质量的一个重要指标,如何能写出稳定的、健壮的c 代码,一定要学习下《exceptional c 》,对异常安全的保障有详尽的讲解,什么时候要抛出异常,如何捕获异常,如何从异常中恢复,一定细读,即使不经常使用c 语言的程序员也应该认真阅读下本书。

效率又是代码质量的另一个重要指标,《effective c 》、《more effective c 》必读。一共给出了编写高效c 代码的90个准则,是高效代码编写的阶梯。


然后,模板,是c 中最难的一部分,如果能灵活使用模板编程,大型项目的可维护性可以显著提高,但难度相对也较大,c 标准库中的stl但是一些常用模板类的封装,它更是如神兵利器。

最后要推荐的就是c 模板编程的必读书《c 模板元编程》,对开源模板库boost中的mpl进行了比较详细的介绍。mpl是c 对函数式编程的一个精巧包装。

到了最后,其实还想推荐一本《深入浅出mfc》,它系统、深入介绍了微软visual studio中的mfc类库,其实是一个介绍图形化界面类实现的非常好的范例,该书对于图形化界面,无论是pc、mac还是web甚至微信小程序,如果要从底层实现一个图形化界面的框架该书可以作为教科书。

4.3 c#/java

c#和java可以放在一起说,因为这两个语言很像,都是在操作系统上面又封装了一层运行时,相当于虚拟机,可以把c#和java当成运行在虚拟机上的程序,这样的好处就是移植性,因为移植的时候只要有虚拟机即可,就是sdk和clr,目前java在所有的主流操作系统中可以运行,而c#也可以在linux、windows、macos甚至android上运行。有了可移植性,跨平台软件的开发成本就会低很多,但也要牺牲一些特性,尤其是gui程序,不同系统的差异还是有的,很难做到原生程序的性能和体验,商业软件嘛,多是要性能和成本综合考虑的,系统间的差异会随着时间越来越小,开发成本也会越来越低,再c#和java的用武之地
有了虚拟机的隔离安全性和稳定性也会更好,c#、java如果不去通过c/c 的接口调用一些操作系统的api很难把系统整死机,而c/c 相对就更容易一些。
java和c#目前都是比较成熟的语言,尤其是java有着无与伦比的生态优势力,对于大型的系统实现,依然是首选。我也在macos上进行测试了一下java、c#、c 的函数拆分的已开通split函数的性能,测试代码如下:
java:

import java.util.calendar;
import java.util.date;
public class splitperformance {
  
    public static void main(string[] args)
    {
  
        string s = "字段1,字段2,字段3,字段4,字段5,字段6,字段7,字段8,字段9,字段10";
        calendar cal = calendar.getinstance();
        date d0 = cal.gettime();
        string[] fields = null;
        for(int i=0 ;i<100000000;   i){
  
            fields = s.split(",");
        }
        date d1 = calendar.getinstance().gettime();
        system.out.format("time elapsed: %d s\n", d1.gettime() - d0.gettime());
    }
}

c#:

using system;
namespace split
{
  
    class program
    {
  
        static void main(string[] args)
        {
  
            datetime t0 = datetime.now;
            string s = "字段1,字段2,字段3,字段4,字段5,字段6,字段7,字段8,字段9,字段10";
            string[] fields = null;
            for (int i = 0; i < 100000000;   i)
            {
  
                fields = s.split(",");
            }
            datetime t1 = datetime.now;
            timespan ts = t1 - t0;
            console.out.writeline("time elapse {0}s", ts.totalseconds);
        }
    }
}

c/c :

#include 
#include 
#include 
int main(int argc, const char * argv[]) {
  
    // insert code here...
    char const* line =  "字段1,字段2,字段3,字段4,字段5,字段6,字段7,字段8,字段9,字段10";
    
    time_t t0, t1;
    
    time(&t0);
    size_t len = strlen(line) 1;
    char* buff = (char*)malloc(len);
    for(size_t n=0; n<100000000;   n){
  
        strcpy(buff, line);
        char* fields[10] = {
  buff};
        int i=1;
        for(char* p = buff; *p != 0;   p){
  
            if( *p == ','){
  
                fields[i] = p 1;
                i  ;
                *p = 0;
            }
        }
        
        //    for(int j=0; j

测试结果:

java:    25.427s
c#:         30.623776s
c  :    21s

结果充分证明了java和c#的性能优化得还是相当好的,很久没有对比了过了,这个结果是让我吃惊的,c#在windows上的表现可能会更好。
所以,一般的项目使用java、c#都是没问题的,即使是计算机密集型的代码,尤其是c#支持unfafe模式,可以使用c 的语法,为什么是#,就是4个 号,也就是c 就是因为它是c 的一个超超集,只是语法并不完全兼容c 的语法而特性是基本兼容的,所以学习c#的话上面c 的读一下也是大有裨益的。

c#必读书

《clr via c#》对clr和.net framework 4.0进行深入、全面的探讨,并结合实例介绍了如何利用它们进行设计、开发和调试。这本书在语言方面讲解全面、深入,是学习c#首选,可以对c#有一个全面的了解,以后可以作为案头手册,随时翻阅。

之后再读《c#高级编程》可以略过语言本身的介绍,阅读关于更多界面开发和应用技术,如webform、消息队列、com 、ad等windows系统的编程基本一览无余,也是必读。

然后就是进阶阅读,如何写出高效的c#代码,《effective c#》

java必读书

对于语言本身首选《java核心技术》,一套两本,对java的特性讲解条理清晰,深入、全面,读完了可以作为案头手册,随时翻阅。


另一本《java编程思想》也是非常好的,豆瓣的评分更高,值得细读,尤其是其面向对像的思想介绍,初学者一定好好串讲,这本书软件工程思想融入对java特性的讲解中。

与c 、c#一样,也有一本介绍高效编程的《effective java》

java语言诞生之初是想“write once,run anywhere",但是用java写桌面软件真的不多,除非是跨平台需求比较强烈,确实有几个非常好的软件是用java写的,比如magicdraw、intellij、eclipse等,但主要还是做服务或web比较多。web开发核心框架spring还是要好好学一下的。

学习的不是仅spring框架怎么使用,更应该是它的设计思想,如何才是学好了,就是自己思考一下,如果让自己来重新实现spring能不能实现。而对于容器的学习,下面这本就很不错:

4.4 javascript

javascript现在已经不是只用于web前端开发了,现在成了一个全栈语言,除了开发web前端界面,还可以使用node.js开发后端的服务,还可以使用taro开发微信小程序、android、ios、快应用等移动端应用,真可是一门语言可以干所有的事了。本人还是比较喜欢javascript,因为喜欢c系的语法,它足够简洁、优雅,不是太喜欢python的语法,忍受不了python的__init__, __del__这样的函数名,当然也可能习惯了c系的代码,此外,javascript还是比python性能要好,可以干更多的事儿。javascript还有个typescript的变种,语法更加严谨,更加趋向于面向对象编程,更适合开发大型的项目。
《javascript权威南》必读;《javascript高级程序设计》评分不低,但这本书没有读过,正打算买下来再复习一下。


但这两本书稍微有点儿旧,都是基于emac5的,后面的新性书中没讲,再读一下《深入理解es6》就完美了。

对于typescript也一本就够了《深入理解typescript》

4.5 python

python用得不多,因为不太喜欢,可推荐的不多,《python核心编程》应该也够了。最开始的时候看python的代码缩进都是强制性的,这样确实在语法层面融入软件工程学思想非常好,但语言设计之始考虑不够严谨,导致后面3.x与2.x的不兼容,很多开源代码不能直接使用,浪费大量人力物力;又设计出个虚拟环境,用来解决包的版本不兼容、开发语言版本不兼容的问题,其实是把问题搞得更糟,实践中解决问题更复杂。总得来讲还是不错的语言,它的流行性证明了一切,主要得益于前几年所谓大数据、人工智能的暴发式增长,凭着它的简单性迅速占领了程序员的桌面,但它真的不适合做大的项目。

4.6 结语

现在的编程语言很多,根据不同领域、不同岗位的程序员需要的主要语言各有不同,但无论哪种,要想做到优秀,c/c 都是必须要熟悉的,即使不太熟练,java/c#至少要熟练使用一种,javascript/python必须熟练使用其一,甚至两种都要熟练使用。比如前些天在做爬是的验证码识别的时候选择了javascript,在使用opencv是就费了一些周折,好在对c 比较熟悉,搞定比较快,否则使用python可能会更方便一些,开源的东西,用的人多了坑就没那么多了。
当然用得多的还有php、go、swift等数不胜数,按编译过程分主要有:

  • 汇编语言:直接通过计算机所支持的指令集编程;性能可控性比较好,开发难度大,成本高,可移植性差,不同架构的cpu的指令集不同,适合控制硬件的应用,一般用于底层寄存器修改,上层再用c封装;
  • 编译型语言(c/c ):直接编译成二进制机器码再执行;这类语言有些可移植性并不高,如basic,主要依赖于编译器,而c/c 的可移植性是很高的,因为gcc可以支持几乎所有的操作系统,而商业的unix系统厂家也都提供了自己的商业编译器,性能更好;
  • 解释型语言(python、ruby等):无需编译,一边解释一边执行;
  • 即时编译型语言:c#、java都是编译型语言,但又与c/c 等不同,它编译后并不是直接是机器码,而是一种中间语言,这种中间语言执行时再由虚拟机编译成机器码执行,不知道怎么命名,借助即时编译的技术(jit,just-in-time),命合为”即时编译型语言“以区分直接编译成二进制的编译型语言。
    另外一角度,从编译思想上分可以分为:
  • 结构化编程语言(过程式编程):如c语言等;
  • 面向对象程序语言:如c 、java等;
  • 函数式编程语言:如lisp等;
  • 逻辑式编程语言:如prolog等
    而函数式编程语言、逻辑式编程语言适用范围较小,所以,没有应用时有所了解即可,有兴趣的也可以研究了一下,笔者没有研究太多。
    有了这些编程语言也可以再读一下《编译原理》以系统地了解编程语言的编译过程,从而方便日后解决疑难问题。

    语言,只是工具,最基础的工具学好了,有了较强的表达能力,才能与计算机之间进行流畅的交流,计算机才会听话,高效、可靠地为我们服务。然后,正如上面所说,每一类编程语言至少要熟悉一种,这样会掌握更多的表达方式,更多的与计算机交互的模式,才能在系统设计与实现时选择最合适的编程语言。
    然而,要学习的还有很多… (待序)
网站地图