由于项目需要,前一段时间涉足了一些 C++ 的开发, 而且是要在 PC IOS Andriod MAC 上面运行。对于写了这么久 Javascript 的我来说也算是一个挑战,也从中学到了很多东西,虽然大学的适合写得最多的也是C,C++。但是毕竟没有接触过工程级别的开发,都只是在OnlineJudge上面提交点算法题玩玩。所以也是遇到了很多坑,分享给Javascript开发者。技多不压身嘛。
1:运行模式的区别
首先我认为在Javascript包括其他解释型语言和C++或者说C语言直接最大的不同不应该是语法,也不应该是面向对象或者模块划分的区别,而是它们运行环境,运行模式的区别。其实就是解释与非解释的区别。
我们说Javascript是跨平台的,Java是跨平台的。其实C++也是跨平台的。只是它们跨平台的方式不一样,javascript是解释型的语言,它是运行中Javascript的引擎下的,比如说Chrome的V8,Opera的Presto,IE的Trident。说以跨平台的事情让JS引擎去做了,只要在不同的平台上保证Javascript的规则相同,引擎能够正确去解释就可以了。但是对于C++来说呢,它是编译为二进制文件直接在操作系统上面运行的。所以不同平台上需要对于编译不同的二进制文件。所以跨平台这一步是需要在编译器这一个级别去做的。由于C++的语法可以说是一个规范和标准,通过不同的编译器就能够保证C++的跨平台。所以说C++的的跨平台是通过语言的规范来实现的,不过毕竟在不同的平台上由于操作系统不相同,如果涉及到需要调用操作系统底层API的时候就不是语言的规范能够限制的范围了,尤其是UI方面,所以如果需要涉及操作系统API的跨平台任务就需要编写中间层将不同的操作系统的API封装为统一的API使用。
所以写C++就要先意识到C++是以二进制的形式直接运行在操作系统上的,所以编写程序和调试程序都需要对操作系统运行机制有一定的认识,其中最关键的两点就是:内存,线程。
2:关于内存
理解内存其实是每一个程序员都必须掌握的知识点,就像有人说过其实考察一个程序员是否合格其实就两点,指针和递归。其中的指针其实就是考察了对计算机内存的理解。说是对内存的理解实际上就是对计算机运行本质原理的理解。
首先基础知识是要知道,计算机程序最终都是会被编译为机器码存放在内存中,程序执行的过程也就是讲内存中的机器指令发送到CPU去执行,无论是变量还是函数其实都是被存放在内存中的。对于javascript这一类的解释性语言,因为和操作系统中间还夹杂着一层虚拟机或者说是解释器,所以很多东西面向javascript程序变得透明。但是对于C++来说,你写的每一行代码最终都会被编译为机器码放到内存中执行,很多时候要有这样的意识:操作变量就是操作内存中的数据,执行函数就是执行内存中的机器码。
举一个例子,在javascript中如果某一个变量不是你预期的,呐如果不是解释器的问题的话就一定是你代码某一个地方将这个变量给改变了。如果是C++的话那就有可能是其他的方的操作附带不小心修改了这一块内存,活着是不小心将内存释放,使得原来的指针变成了野指针。
3:关于线程
对于javascript来说程序是单线程执行的,所有的一切都是事件驱动,无论有多少任务在队列里面都得等待现场空闲的时候才能执行,这一其实对于开发者来说是友好的。无论是程序的逻辑还是debug都简单了很多,只要一步一步来就能搞定。但是对于多线程的程序来说就不好办了,一个内存可能回被两个地方同时读取或者写入。其实玩转多线程其实就是要玩转内存。就是要控制好同时操作同一块内存的逻辑控制。多线程去同时操作一个函数就是多个地方同时去读取一段内存,所以这个过程总要保证大家不会逻辑混乱的错误的对这块内存做修改。操作系统提供了一个简单有效的方法,就是加锁。我们可以通过操作系统底层的API来对某一段内存做加锁。对应代码中就是对某一个代码块进行加锁,这一块可以网上找找资料继续了解,包括信号量,临界区的概念,虽然大学都学过,但是我想很多javascript程序员可能都忘了吧。
4:其他一些底层的东西
TODO