导航:首页 > 源码编译 > 补丁编译原理

补丁编译原理

发布时间:2023-01-25 07:30:20

㈠ 了解什么叫做jit compiling,与传统的编译技术有何不同

java 应用程序的性能经常成为开发社区中的讨论热点。因为该语言的设计初衷是使用解释的方式支持应用程序的可移植性目标,早期
Java 运行时所提供的性能级别远低于 C 和
C++
之类的编译语言。尽管这些语言可以提供更高的性能,但是生成的代码只能在有限的几种系统上执行。在过去的十年中,Java
运行时供应商开发了一些复杂的动态编译器,通常称作即时(Just-in-time,JIT)编译器。程序运行时,JIT
编译器选择将最频繁执行的方法编译成本地代码。运行时才进行本地代码编译而不是在程序运行前进行编译(用 C 或
C++ 编写的程序正好属于后一情形),保证了可移植性的需求。有些 JIT 编译器甚至不使用解释程序就能编译所有的代码,但是这些编译器仍然通过在程序执行时进行一些操作来保持 Java 应用程序的可移植性。
由于动态编译技术的多项改进,在很多应用程序中,现代的 JIT 编译器可以产生与 C 或 C++
静态编译相当的应用程序性能。但是,仍然有很多软件开发人员认为 —— 基于经验或者传闻 ——
动态编译可能严重干扰程序操作,因为编译器必须与应用程序共享 CPU。一些开发人员强烈呼吁对 Java
代码进行静态编译,并且坚信那样可以解决性能问题。对于某些应用程序和执行环境而言,这种观点是正确的,静态编译可以极大地提高 Java
性能,或者说它是惟一的实用选择。但是,静态地编译 Java 应用程序在获得高性能的同时也带来了很多复杂性。一般的
Java 开发人员可能并没有充分地感受到 JIT 动态编译器的优点。

本文考察了 Java 语言静态编译和动态编译所涉及的一些问题,重点介绍了实时 (RT) 系统。简要描述了 Java
语言解释程序的操作原理并说明了现代 JIT 编译器执行本地代码编译的优缺点。介绍了 IBM 在 WebSphere Real Time 中发布的
AOT 编译技术和它的一些优缺点。然后比较了这两种编译策略并指出了几种比较适合使用 AOT
编译的应用程序领域和执行环境。要点在于这两种编译技术并不互斥:即使在使用这两种技术最为有效的各种应用程序中,它们也分别存在一些影响应用程序的优缺
点。

执行 Java 程序

Java 程序最初是通过 Java SDK 的 javac程序编译成本地的与平台无关的格式(类文件)。可将此格式看作 Java
平台,因为它定义了执行 Java 程序所需的所有信息。Java 程序执行引擎,也称作 Java 运行时环境(JRE),包含了为特定的本地平台实现
Java 平台的虚拟机。例如,基于 linux 的 Intel x86 平台、Sun Solaris 平台和 AIX 操作系统上运行的 IBM
System p 平台,每个平台都拥有一个 JRE。这些 JRE 实现实现了所有的本地支持,从而可以正确执行为
Java 平台编写的程序。

事实上,操作数堆栈的大小有实际限制,但是编程人员极少编写超出该限制的方法。JVM 提供了安全性检查,对那些创建出此类方法的编程人员进行通知。

Java 平台程序表示的一个重要部分是字节码序列,它描述了 Java
类中每个方法所执行的操作。字节码使用一个理论上无限大的操作数堆栈来描述计算。这个基于堆栈的程序表示提供了平台无关性,因为它不依赖任何特定本地平台
的 CPU 中可用寄存器的数目。可在操作数堆栈上执行的操作的定义都独立于所有本地处理器的指令集。Java
虚拟机(JVM)规范定义了这些字节码的执行(参见 参考资料)。执行 Java 程序时,用于任何特定本地平台的任何 JRE 都必须遵守 JVM
规范中列出的规则。

因为基于堆栈的本地平台很少(Intel X87 浮点数协处理器是一个明显的例外),所以大多数本地平台不能直接执行 Java 字节码。为了解决这个问题,早期的 JRE 通过解释字节码来执行 Java 程序。即 JVM 在一个循环中重复操作:

◆获取待执行的下一个字节码;

◆解码;

◆从操作数堆栈获取所需的操作数;

◆按照 JVM 规范执行操作;

◆将结果写回堆栈。

这种方法的优点是其简单性:JRE 开发人员只需编写代码来处理每种字节码即可。并且因为用于描述操作的字节码少于 255 个,所以实现的成本比较低。当然,缺点是性能:这是一个早期造成很多人对 Java 平台不满的问题,尽管拥有很多其他优点。

解决与 C 或 C++ 之类的语言之间的性能差距意味着,使用不会牺牲可移植性的方式开发用于 Java 平台的本地代码编译。

编译 Java 代码

尽管传闻中 Java 编程的 “一次编写,随处运行”
的口号可能并非在所有情况下都严格成立,但是对于大量的应用程序来说情况确实如此。另一方面,本地编译本质上是特定于平台的。那么 Java
平台如何在不牺牲平台无关性的情况下实现本地编译的性能?答案就是使用 JIT 编译器进行动态编译,这种方法已经使用了十年(参见图 1):

图 1. JIT 编译器

使用 JIT 编译器时,Java
程序按每次编译一个方法的形式进行编译,因为它们在本地处理器指令中执行以获得更高的性能。此过程将生成方法的一个内部表示,该表示与字节码不同但是其级
别要高于目标处理器的本地指令。(IBM JIT
编译器使用一个表达式树序列表示方法的操作。)编译器执行一系列优化以提高质量和效率,最后执行一个代码生成步骤将优化后的内部表示转换成目标处理器的本
地指令。生成的代码依赖运行时环境来执行一些活动,比如确保类型转换的合法性或者对不能在代码中直接执行的某些类型的对象进行分配。JIT
编译器操作的编译线程与应用程序线程是分开的,因此应用程序不需要等待编译的执行。

图 1 中还描述了用于观察执行程序行为的分析框架,通过周期性地对线程取样找出频繁执行的方法。该框架还为专门进行分析的方法提供了工具,用来存储程序的此次执行中可能不会改变的动态值。

因为这个 JIT 编译过程在程序执行时发生,所以能够保持平台无关性:发布的仍然是中立的 Java 平台代码。C 和 C++ 之类的语言缺乏这种优点,因为它们在程序执行前进行本地编译;发布给(本地平台)执行环境的是本地代码。

挑战

尽管通过 JIT 编译保持了平台无关性,但是付出了一定代价。因为在程序执行时进行编译,所以编译代码的时间将计入程序的执行时间。任何编写过大型 C 或 C++ 程序的人都知道,编译过程往往较慢。

为了克服这个缺点,现代的 JIT
编译器使用了下面两种方法的任意一种(某些情况下同时使用了这两种方法)。第一种方法是:编译所有的代码,但是不执行任何耗时多的分析和转换,因此可以快
速生成代码。由于生成代码的速度很快,因此尽管可以明显观察到编译带来的开销,但是这很容易就被反复执行本地代码所带来的性能改善所掩盖。第二种方法是:
将编译资源只分配给少量的频繁执行的方法(通常称作热方法)。低编译开销更容易被反复执行热代码带来的性能优势掩盖。很多应用程序只执行少量的热方法,因
此这种方法有效地实现了编译性能成本的最小化。

动态编译器的一个主要的复杂性在于权衡了解编译代码的预期获益使方法的执行对整个程序的性能起多大作用。一个极端的例子是,程序执行后,您非常清楚哪些方
法对于这个特定的执行的性能贡献最大,但是编译这些方法毫无用处,因为程序已经完成。而在另一个极端,程序执行前无法得知哪些方法重要,但是每种方法的潜
在受益都最大化了。大多数动态编译器的操作介于这两个极端之间,方法是权衡了解方法预期获益的重要程度。

Java 语言需要动态加载类这一事实对 Java
编译器的设计有着重要的影响。如果待编译代码引用的其他类还没有加载怎么办?比如一个方法需要读取某个尚未加载的类的静态字段值。Java
语言要求第一次执行类引用时加载这个类并将其解析到当前的 JVM
中。直到第一次执行时才解析引用,这意味着没有地址可供从中加载该静态字段。编译器如何处理这种可能性?编译器生成一些代码,用于在没有加载类时加载并解
析类。类一旦被解析,就会以一种线程安全的方式修改原始代码位置以便直接访问静态字段的地址,因为此时已获知该地址。

IBM JIT
编译器中进行了大量的努力以便使用安全而有效率的代码补丁技术,因此在解析类之后,执行的本地代码只加载字段的值,就像编译时已经解析了字段一样。另外一
种方法是生成一些代码,用于在查明字段的位置以前一直检查是否已经解析字段,然后加载该值。对于那些由未解析变成已解析并被频繁访问的字段来说,这种简单
的过程可能带来严重的性能问题。

动态编译的优点

动态地编译 Java 程序有一些重要的优点,甚至能够比静态编译语言更好地生成代码,现代的 JIT 编译器常常向生成的代码中插入挂钩以收集有关程序行为的信息,以便如果要选择方法进行重编译,就可以更好地优化动态行为。

关于此方法的一个很好的例子是收集一个特定 array操作的长度。如果发现每次执行操作时该长度基本不变,则可以为最频繁使用的

array长度生成专门的代码,或者可以调用调整为该长度的代码序列。由于内存系统和指令集设计的特性,用于复制内存的最佳通用例程的执行速度通
常比用于复制特定长度的代码慢。例如,复制 8
个字节的对齐的数据可能需要一到两条指令直接复制,相比之下,使用可以处理任意字节数和任意对齐方式的一般复制循环可能需要 10 条指令来复制同样的 8

个字节。但是,即使此类专门的代码是为某个特定的长度生成的,生成的代码也必须正确地执行其他长度的复制。生成代码只是为了使常见长度的操作执行得更快,
因此平均下来,性能得到了改进。此类优化对大多数静态编译语言通常不实用,因为所有可能的执行中长度恒定的操作比一个特定程序执行中长度恒定的操作要少得
多。

此类优化的另一个重要的例子是基于类层次结构的优化。例如,一个虚方法调用需要查看接收方对象的类调用,以便找出哪个实际目标实现了接收方对象的虚方法。
研究表明:大多数虚调用只有一个目标对应于所有的接收方对象,而 JIT
编译器可以为直接调用生成比虚调用更有效率的代码。通过分析代码编译后类层次结构的状态,JIT
编译器可以为虚调用找到一个目标方法,并且生成直接调用目标方法的代码而不是执行较慢的虚调用。当然,如果类层次结构发生变化,并且出现另外的目标方法,
则 JIT
编译器可以更正最初生成的代码以便执行虚调用。在实践中,很少需要作出这些更正。另外,由于可能需要作出此类更正,因此静态地执行这种优化非常麻烦。

因为动态编译器通常只是集中编译少量的热方法,所以可以执行更主动的分析来生成更好的代码,使编译的回报更高。事实上,大部分现代的
JIT
编译器也支持重编译被认为是热方法的方法。可以使用静态编译器(不太强调编译时间)中常见的非常主动的优化来分析和转换这些频繁执行的方法,以便生成更好
的代码并获得更高的性能。

这些改进及其他一些类似的改进所产生的综合效果是:对于大量的 Java 应用程序来说,动态编译已经弥补了与 C 和 C++ 之类语言的静态本地编译性能之间的差距,在某些情况下,甚至超过了后者的性能。

缺点

但是,动态编译确实具有一些缺点,这些缺点使它在某些情况下算不上一个理想的解决方案。例如,因为识别频繁执行的方法以及编译这些方法需要时间,所以应用
程序通常要经历一个准备过程,在这个过程中性能无法达到其最高值。在这个准备过程中出现性能问题有几个原因。首先,大量的初始编译可能直接影响应用程序的
启动时间。不仅这些编译延迟了应用程序达到稳定状态的时间(想象 Web
服务器经
历一个初始阶段后才能够执行实际有用的工作),而且在准备阶段中频繁执行的方法可能对应用程序的稳定状态的性能所起的作用也不大。如果 JIT
编译会延迟启动又不能显着改善应用程序的长期性能,则执行这种编译就非常浪费。虽然所有的现代 JVM
都执行调优来减轻启动延迟,但是并非在所有情况下都能够完全解决这个问题。

其次,有些应用程序完全不能忍受动态编译带来的延迟。如 GUI 接口之类交互式应用程序就是这样的例子。在这种情况下,编译活动可能对用户使用造成不利影响,同时又不能显着地改善应用程序的性能。

最后,用于实时环境并具有严格的任务时限的应用程序可能无法忍受编译的不确定性性能影响或动态编译器本身的内存开销。

因此,虽然 JIT 编译技术已经能够提供与静态语言性能相当(甚至更好)的性能水平,但是动态编译并不适合于某些应用程序。在这些情况下,Java 代码的提前(Ahead-of-time,AOT)编译可能是合适的解决方案。

AOT Java 编译

大致说来,Java 语言本地编译应该是为传统语言(如 C++ 或
Fortran)而开发的编译技术的一个简单应用。不幸的是,Java 语言本身的动态特性带来了额外的复杂性,影响了 Java
程序静态编译代码的质量。但是基本思想仍然是相同的:在程序执行前生成 Java 方法的本地代码,以便在程序运行时直接使用本地代码。目的在于避免
JIT 编译器的运行时性能消耗或内存消耗,或者避免解释程序的早期性能开销。

挑战

动态类加载是动态 JIT 编译器面临的一个挑战,也是 AOT
编译的一个更重要的问题。只有在执行代码引用类的时候才加载该类。因为是在程序执行前进行 AOT
编译的,所以编译器无法预测加载了哪些类。就是说编译器无法获知任何静态字段的地址、任何对象的任何实例字段的偏移量或任何调用的实际目标,甚至对直接调
用(非虚调用)也是如此。在执行代码时,如果证明对任何这类信息的预测是错误的,这意味着代码是错误的并且还牺牲了 Java 的一致性。

因为代码可以在任何环境中执行,所以类文件可能与代码编译时不同。例如,一个 JVM
实例可能从磁盘的某个特定位置加载类,而后面一个实例可能从不同的位置甚至网络加载该类。设想一个正在进行 bug
修复的开发环境:类文件的内容可能随不同的应用程序的执行而变化。此外,Java 代码可能在程序执行前根本不存在:比如 Java
反射服务通常在运行时生成新类来支持程序的行为。

缺少关于静态、字段、类和方法的信息意味着严重限制了 Java 编译器中优化框架的大部分功能。内联可能是静态或动态编译器应用的最重要的优化,但是由于编译器无法获知调用的目标方法,因此无法再使用这种优化。

内联

内联是一种用于在运行时生成代码避免程序开始和结束时开销的技术,方法是将函数的调用代码插入到调用方的函数中。但是内联最大的益处可能是优化方可见的代码的范围扩大了,从而能够生成更高质量的代码。下面是一个内联前的代码示例:

int foo() { int x=2, y=3; return bar(x,y); }final int bar(int a, int b) { return a+b; }

如果编译器可以证明这个 bar就是 foo()中调用的那个方法,则 bar中的代码可以取代 foo()中对
bar()的调用。这时,bar()方法是 final类型,因此肯定是 foo()中调用的那个方法。甚至在一些虚调用例子中,动态 JIT
编译器通常能够推测性地内联目标方法的代码,并且在绝大多数情况下能够正确使用。编译器将生成以下代码:

int foo() { int x=2, y=3; return x+y; }

在这个例子中,简化前名为值传播的优化可以生成直接返回
5的代码。如果不使用内联,则不能执行这种优化,产生的性能就会低很多。如果没有解析
bar()方法(例如静态编译),则不能执行这种优化,而代码必须执行虚调用。运行时,实际调用的可能是另外一个执行两个数字相乘而不是相加的
bar方法。所以不能在 Java 程序的静态编译期间直接使用内联。

AOT
代码因此必须在没有解析每个静态、字段、类和方法引用的情况下生成。执行时,每个这些引用必须利用当前运行时环境的正确值进行更新。这个过程可能直接影响
第一次执行的性能,因为在第一次执行时将解析所有引用。当然,后续执行将从修补代码中获益,从而可以更直接地引用实例、静态字段或方法目标。

另外,为 Java 方法生成的本地代码通常需要使用仅在单个 JVM 实例中使用的值。例如,代码必须调用 JVM
运行时中的某些运行时例程来执行特定操作,如查找未解析的方法或分配内存。这些运行时例程的地址可能在每次将 JVM 加载到内存时变化。因此 AOT
编译代码需要绑定到 JVM 的当前执行环境中,然后才能执行。其他的例子有字符串的地址和常量池入口的内部位置。

在 WebSphere Real Time 中,AOT 本地代码编译通过 jxeinajar工具(参见图 2)来执行。该工具对 JAR 文件中所有类的所有方法应用本地代码编译,也可以选择性地对需要的方法应用本地代码编译。结果被存储到名为 Java eXEcutable (JXE) 的内部格式中,但是也可轻松地存储到任意的持久性容器中。

您可能认为对所有的代码进行静态编译是最好的方法,因为可以在运行时执行最大数量的本地代码。但是此处可以作出一些权衡。编译的方法越多,代码占用的内存
就越多。编译后的本地代码大概比字节码大 10 倍:本地代码本身的密度比字节码小,而且必须包含代码的附加元数据,以便将代码绑定到 JVM
中,并且在出现异常或请求堆栈跟踪时正确执行代码。构成普通 Java 应用程序的 JAR
文件通常包含许多很少执行的方法。编译这些方法会消耗内存却没有什么预期收益。相关的内存消耗包括以下过程:将代码存储到磁盘上、从磁盘取出代码并装入
JVM,以及将代码绑定到 JVM。除非多次执行代码,否则这些代价不能由本地代码相对解释的性能优势来弥补。

图 2. jxeinajar

跟大小问题相违背的一个事实是:在编译过的方法和解释过的方法之间进行的调用(即编译过的方法调用解释过的方法,或者相反)可能比这两类方法各自内部之间
进行的调用所需的开销大。动态编译器通过最终编译所有由 JIT
编译代码频繁调用的那些解释过的方法来减少这项开销,但是如果不使用动态编译器,则这项开销就不可避免。因此如果是选择性地编译方法,则必须谨慎操作以使
从已编译方法到未编译方法的转换最小化。为了在所有可能的执行中都避免这个问题而选择正确的方法会非常困难。
优点
虽然 AOT 编译代码具有上述的缺点和挑战,但是提前编译 Java 程序可以提高性能,尤其是在不能将动态编译器作为有效解决方案的环境中。

可以通过谨慎地使用 AOT 编译代码加快应用程序启动,因为虽然这种代码通常比 JIT
编译代码慢,但是却比解释代码快很多倍。此外,因为加载和绑定 AOT
编译代码的时间通常比检测和动态编译一个重要方法的时间少,所以能够在程序执行的早期达到那样的性能。类似地,交互式应用程序可以很快地从本地代码中获
益,无需使用引起较差响应能力的动态编译。

RT 应用程序也能从 AOT 编译代码中获得重要的收益:更具确定性的性能超过了解释的性能。WebSphere Real Time
使用的动态 JIT 编译器针对在 RT 系统中的使用进行了专门的调整。使编译线程以低于 RT
任务的优先级操作,并且作出了调整以避免生成带有严重的不确定性性能影响的代码。但是,在一些 RT 环境中,出现 JIT
编译器是不可接受的。此类环境通常需要最严格的时限管理控制。在这些例子中,AOT
编译代码可以提供比解释过的代码更好的原始性能,又不会影响现有的确定性。消除 JIT
编译线程甚至消除了启动更高优先级 RT 任务时发生的线程抢占所带来的性能影响。

优缺点统计

动态(JIT)编译器支持平台中立性,并通过利用应用程序执行的动态行为和关于加载的类及其层次结构的信息来生成高质量的代码。但是
JIT
编译器具有一个有限的编译时预算,而且会影响程序的运行时性能。另一方面,静态(AOT)编译器则牺牲了平台无关性和代码质量,因为它们不能利用程序的动
态行为,也不具有关于加载的类或类层次结构的信息。AOT 编译拥有有效无限制的编译时预算,因为 AOT
编译时间不会影响运行时性能,但是在实践中开发人员不会长期等待静态编译步骤的完成。

表 1 总结了本文讨论的 Java 语言动态和静态编译器的一些特性:

表 1. 比较编译技术

两种技术都需要谨慎选择编译的方法以实现最高的性能。对动态编译器而言,编译器自身作出决策,而对于静态编译器,由开发人员作出选择。让
JIT 编译器选择编译的方法是不是优点很难说,取决于编译器在给定情形中推断能力的好坏。在大多数情况下,我们认为这是一种优点。

因为它们可以最好地优化运行中的程序,所以 JIT 编译器在提供稳定状态性能方面更胜一筹,而这一点在大量的生产 Java
系统中最为重要。静态编译可以产生最佳的交互式性能,因为没有运行时编译行为来影响用户预期的响应时间。通过调整动态编译器可以在某种程度上解决启动和确
定性性能问题,但是静态编译在需要时可提供最快的启动速度和最高级别的确定性。表 2 在四种不同的执行环境中对这两种编译技术进行了比较:

表 2. 使用这些技术的最佳环境

图 3 展示了启动性能和稳定状态性能的总体趋势:

图 3. AOT 和 JIT 的性能对比

使用 JIT 编译器的初始阶段性能很低,因为要首先解释方法。随着编译方法的增多及 JIT
执行编译所需时间的缩短,性能曲线逐渐升高最后达到性能峰值。另一方面,AOT 编译代码启动时的性能比解释的性能高很多,但是无法达到 JIT
编译器所能达到的最高性能。将静态代码绑定到 JVM 实例中会产生一些开销,因此开始时的性能比稳定状态的性能值低,但是能够比使用 JIT
编译器更快地达到稳定状态的性能水平。

没有一种本地代码编译技术能够适合所有的 Java
执行环境。某种技术所擅长的通常正是其他技术的弱项。出于这个原因,需要同时使用这两种编译技术以满足 Java
应用程序开发人员的要求。事实上,可以结合使用静态和动态编译以便提供最大可能的性能提升 —— 但是必须具备平台无关性,它是 Java
语言的主要卖点,因此不成问题。

结束语

本文探讨了 Java 语言本地代码编译的问题,主要介绍了 JIT 编译器形式的动态编译和静态 AOT 编译,比较了二者的优缺点。

虽然动态编译器在过去的十年里实现了极大的成熟,使大量的各种 Java 应用程序可以赶上或超过静态编译语言(如 C++ 或
Fortran)所能够达到的性能。但是动态编译在某些类型的应用程序和执行环境中仍然不太合适。虽然 AOT
编译号称动态编译缺点的万能解决方案,但是由于 Java 语言本身的动态特性,它也面临着提供本地编译全部潜能的挑战。

这两种技术都不能解决 Java 执行环境中本地代码编译的所有需求,但是反过来又可以在最有效的地方作为工具使用。这两种技术可以相互补充。能够恰当地使用这两种编译模型的运行时系统可以使很大范围内的应用程序开发环境中的开发人员和用户受益。

㈡ 适合初学者学习的嵌入式教程

原文链接:网页链接

嵌入式Linux学习路线图

我是1999年上的大学,物理专业。在大一时,我们班里普遍弥漫着对未来的不安,不知道学习了物理后出去能做什么。你当下的经历、当下的学习,在未来的一天肯定会影响到你。毕业后我们也各自找到了自己的职业:出国深造转行做金融、留校任教做科研、设计芯片、写程序、创办公司等等,这一切都离不开在校时学到的基础技能(数学、IT、电子电路)、受过煅炼的自学能力。

所以,各位正在迷茫的在校生,各位正在尝试转行的程序员,未来一定有你的位置,是好是坏取决于你当下的努力与积累。

我不能预言几年后什么行业会热门,也不能保证你照着本文学习可以发财。我只是一个有十几年经验的程序员,给对编程有兴趣的你,提供一些建议。

1.程序员的三大方向

程序员的方向,一般可以分为3类:专业领域、业务领域、操作系统领域。你了解它们后,按兴趣选择吧。

对于专业领域,我提供不了建议。

业务,也就是应用程序,它跟操作系统并不是截然分开的:

①开发实体产品时,应用程序写得好的人,有时候需要操作系统的知识,比如调度优先级的设置、知道某些函数可能会令进程休眠。

②写应用程序的人进阶为系统工程师时,他需要从上到下都了解,这时候就需要有操作系统领域的知识了,否则,你怎么设计整个系统的方案呢?

③做应用程序的人,需要了解行业的需求,理解业务的逻辑。所以,当领导的人,多是做应用的。一旦钻入了某个行业,很难换行业。

④而操作系统领域,做好了这是通杀各行业:他只负责底层系统,在上面开发什么业务跟他没关系。这行很多是技术宅,行业专家。

⑤操作系统和业务之间并没有一个界线。有操作系统经验,再去做应用,你会对系统知根知底,碰到问题时都有解决思路。有了业务经验,你再了解一下操作系统,很快就可以组成一个团队自立门户,至少做个CTO没问题。

1.1 专业领域

它又可以分为下面2类。

1.1.1 学术研究

比如语音、图像处理、人工智能,这类工作需要你有比较强的理论知识,我倾向于认为这类人是“科学家”,他们钻研多年,很多时候是在做学术研究。

在嵌入式领域,需要把他们的成果用某种算法表达出来,针对某种芯片进行优化,这部分工作也许有专人来做。

1.1.2 工程实现

也有这样一类人,他们懂得这些专业领域的概念,但是没有深入钻研。可以使用各类开源资料实现某个目标,做出产品。比如图像处理,他懂得用opencv里几百个复杂函数来实现头像识别。有时候还可以根据具体芯片来优化这些函数。

“专业领域”不是我的菜,如果你要做这一块,我想最好的入门方法是在学校学习研究生、博士课程。

1.2 业务领域

换句话说,就是应用程序,这又可以分为下面2类。

1.2.1 界面显示

做产品当然需要好的界面,但是,不是说它不重要,是没什么发展后劲。

现在的热门词是Android APP和IOS APP开发。你不要被Android、IOS两个词骗了,它们跟以前的VC、VB是同一路货色,只是、仅仅是一套GUI控件的实现。

希望没有冒犯到你,我有理由。

一个程序需要有GUI界面,但是程序的内在逻辑才是核心。Android、IOS的开发工具给我们简化了GUI的开发,并提供了这些控件的交互机制,封装并提供了一些服务(比如网络传输)。但是程序内部的业务逻辑、对视频图像声音的处理等等,这才是核心。另外别忘了服务器那边的后台程序:怎样更安全地保存数据、保护客户的隐私,怎样处理成千上万上百万的并发访问,等等,这也是核心。

但是,从Android、IOS APP入门入行,这很快!如果你是大四,急于找到一份工作,那么花上1、2个月去学习Android或IOS,应该容易找到工作,毕竟APP的需求永远是最大的,现在这两门技术还算热门。在2011、2012年左右,Android程序员的起薪挺高,然后开始下滑。Android APP的入门基本只要1个月,所以懂的人也越来越多。2013、2014年,IOS开发的工资明显比Android高了,于是各类IOS培训也火曝起来。中华大地向来不缺速成人才,估计再过一阵子IOS工程师也是白菜价了。

会Android、IOS只是基本要求,不信去51job搜搜Android或IOS,职位要求里肯定其他要求。

1.2.2 业务逻辑

举个简单例子,做一个打卡软件,你需要考虑这些东西:

①正常流程是上班下班时都要打卡

②有人忘记了怎么办?作为异常记录在案,推送给管理员

③请假时怎么处理?

④加班怎么处理?

对于更复杂的例子,视频会议系统里,各个模块怎么对接,各类协议怎么兼容,你不深入这个行业,你根本搞不清楚。

应用开发的职位永远是最多的,入门门槛也低。基本上只要你会C语言,面试时表现比较得体,一般公司都会给你机会。因为:

①你进公司后,还需要重新培训你:熟悉它们的业务逻辑。

②你要做的,基本也就是一个个模块,框架都有人给你定好了,你去填代码就可以了。

说点让你高兴的事:软件公司里,做领导的基本都是写应用程序的(当然还有做市场的)。写应用程序的人,对外可以研究市场接待客户,对内可以管理程序员完成开发,不让他做领导让谁做?

如果你的志向是写应用程序,那么我建议你先练好基本功:数据结构、算法是必备,然后凭兴趣选择数据库、网络编程等等进行深入钻研。

最后,选择你看好的、感兴趣的行业深耕个10年吧。做应用开发的人选择了某个行业,后面是很难换行业的,选行很重要!

1.3 操作系统领域

UCOS太简单,VxWorks太贵太专业,Windows不玩嵌入式了,IOS不开源,所以对于操作系统领域我们也只能玩Linux了。

在嵌入式领域Linux一家独大!

Android呢?Android跟QT一样,都是一套GUI系统。只是Google的实力太强了,现在Android无处不在,所以很多时候Linux+Android成了标配。注意,在这里我们关心的是Android的整个系统、里面的机制,而不是学习几个API然后开发界面程序。操作系统领域所包含的内容,简单地说,就是制作出一台装好系统的专用“电脑”,可以分为:

①为产品规划硬件:

按需求、性能、成本选择主芯片,搭配周边外设,交由硬件开发人员设计。

②给单板制作、安装操作系统、编写驱动

③定制维护、升级等系统方案

④还可能要配置、安装Android等GUI系统:

⑤为应用开发人员配置开发环境

⑥从系统角度解决疑难问题


这个领域,通常被称为“底层系统”或是“驱动开发”。

先解决2个常见误区:

①这份工作是写驱动程序吗?

看看上面罗列的6点,应该说,它包含驱动开发,但远远不只有驱动开发。

②我们还需要写驱动吗?不是有原厂吗?或者只需要改改就可以?

经常有人说,芯片原厂都做好驱动了,拿过来改改就可以了。如果,你的硬件跟原厂的公板完全一样,原厂源码毫无BUG,不想优化性能、削减成本,不想做一些有特色的产品,那这话是正确的。


但是在这个不创新就是找死的年代,可能吗?!原因有二:

①即使只是修改代码,能修改的前提是能理解;能理解的最好煅炼方法是从零写出若干驱动程序。

②很多时候,需要你深度定制系统。


以前做联发科手机只需要改改界面就可以出货了,现在山寨厂一批批倒下。大家都使用原厂的方案而不加修改时,最后只能拼成本。

举个例子,深圳有2家做交通摄像头、监控摄像头的厂家,他们曾经找我做过4个项目:

①改进厂家给的SD卡驱动性能,使用DMA。

②换了Flash型号后,系统经常出问题,需要修改驱动BUG。

③触摸屏点击不准,找原因,后来发现是旁路电容导致的。

④裁减成本,把4片DDR换为2片DDR,需要改bootloader对DDR的初始化。

这些项目都很急,搞不定就无法出货,这时候找原厂?除非你是中兴华为等大客户,否则谁理你?


我在中兴公司上班时,写驱动的时间其实是很少的,大部分时间是调试:系统调优,上帮APP工程师、下帮硬件工程师查找问题。我们从厂家、网上得到的源码,很多都是标准的,当然可以直接用。但是在你的产品上也许优化一下更好。比如我们可以把摄像头驱动和DMA驱动揉合起来,让摄像头的数据直接通过DMA发到DSP去。我们可以在软件和硬件之间起桥梁作用,对于实体产品,有可能是软件出问题也可能是硬件出问题,一般是底层系统工程师比较容易找出问题。


当硬件、软件应用出现问题,他们解决不了时,从底层软件角度给他们出主意,给他们提供工具。再比如方案选择:芯片性能能否达标、可用的BSP是否完善等等,这只能由负责整个方案的人来考虑,他必须懂底层。


在操作系统领域,对知识的要求很多:

①懂硬件知识才能看懂电路图

②英文好会看芯片手册

③有编写、移植驱动程序的能力

④对操作系统本身有一定的理解,才能解决各类疑难问题

⑤理解Android内部机制

⑥懂汇编、C语言、C++、JAVA


它绝对是一个大坑,没有兴趣、没有毅力的人慎选。

①这行的入门,绝对需要半年以上,即使全天学习也要半年。

②它的职位,绝对比APP的职位少

③并且你没有1、2年经验,招你到公司后一开始你做的还是APP。


优点就是:

①学好后,行业通杀,想换行就换行;想自己做产品就自己做产品。

②相比做应用程序的人,不会被经常变动的需求搞得天天加班。

③门槛高,当然薪水相对就高。


操作系统领域,我认为适合于这些人:

①硬件工程师想转软件工程师,从底层软件入门会比较好

单片机工程师,想升级一下。会Linux底层的人肯定会单片机,会单片机的人不一定会Linux。

③时间充足的学生:如果你正读大二大三,那么花上半年学习嵌入式Linux底层多有益处。

④想掌握整个系统的人,比如你正在公司里写APP,但是想升为系统工程师,那么底层不得不学。

⑤想自己创业做实体产品的工程师,你有钱的话什么技术都不用学,但是如果没钱又想做产品,那么Linux底层不得不学。

⑥做Linux APP的人,没错,他们也要学习。

这部分人不需要深入,了解个大概就可以:bootloader是用来启动内核,Linux的文件系统(第1个程序是什么、做什么、各目录干嘛用)、APP跟驱动程序的调用关系、工具链,有这些概念就可以了

本文中,就把操作系统默认为Linux,讲讲怎么学习嵌入式Linux+Android系统。


1.4 嵌入式Linux+Android系统包含哪些内容

嵌入式Linux系统包含哪些东西?不要急,举一个例子你就知道了。

①电脑一开机,那些界面是谁显示的?

是BIOS,它做什么?一些自检,然后从硬盘上读入windows,并启动它。

类似的,这个BIOS对应于嵌入式Linux里的bootloader。这个bootloader要去Flash上读入Linux内核,并启动它。


②启动windows的目的是什么?

当然运行应用程序以便上网、聊天什么的了。

这些上网程序、聊天程序在哪?

在C盘、D盘上。

所以,windows要先识别出C盘、D盘。在Linux下我们称之为根文件系统。

③windows能识别出C盘、D盘,那么肯定有读写硬盘的能力。


这个能力我们称之为驱动程序。当然不仅仅是操作硬盘,还有网卡、USB等等其他硬件。嵌入式Linux能从Flash上读出并执行应用程序,肯定也得有Flash的驱动程序啊,当然也不仅仅是Flash。


简单地说,嵌入式LINUX系统里含有bootloader、内核、驱动程序、根文件系统、应用程序这5大块。而应用程序,我们又可以分为:C/C++、Android。

所以,嵌入式Linux+Android系统包含以下6部分内容:

①bootloader

②Linux内核

③驱动程序

④使用C/C++编写的应用程序

⑤Android系统本身

⑥Android应用程序


Android跟Linux的联系实在太大了,它的应用是如此广泛,学习了Linux之后没有理由停下来不学习Android。在大多数智能设备中,运行的是Linux操作系统;它上面要么安装有Android,要么可以跟Android手机互联。现在,Linux+Android已成标配。


2. 怎么学习嵌入式Linux操作系统

本文假设您是零基础,以实用为主,用最快的时间让你入门;后面也会附上想深入学习时可以参考的资料。


在实际工作中,我们从事的是“操作系统”周边的开发,并不会太深入学习、修改操作系统本身。

①操作系统具有进程管理、存储管理、文件管理和设备管理等功能,这些核心功能非常稳定可靠,基本上不需要我们修改代码。我们只需要针对自己的硬件完善驱动程序

②学习驱动时必定会涉及其他知识,比如存储管理、进程调度。当你深入理解了驱动程序后,也会加深对操作系统其他部分的理解

③Linux内核中大部分代码都是设备驱动程序,可以认为Linux内核由各类驱动构成


但是,要成为该领域的高手,一定要深入理解Linux操作系统本身,要去研读它的源代码。

在忙完工作,闲暇之余,可以看看这些书:

①赵炯的《linux内核完全注释》,这本比较薄,推荐这本。他后来又出了《Linux 内核完全剖析》,太厚了,搞不好看了后面就忘记前面了。

②毛德操、胡希明的《LINUX核心源代码情景分析》,此书分上下册,巨厚无比。当作字典看即可:想深入理解某方面的知识,就去看某章节。

③其他好书还有很多,我没怎么看,没有更多建议


基于快速入门,上手工作的目的,您先不用看上面的书,先按本文学习。


2.1 入门路线图

假设您是零基础,我们规划了如下入门路线图。前面的知识,是后面知识的基础,建议按顺序学习。每一部分,不一定需要学得很深入透彻,下面分章节描述。

2.2 学习驱动程序之前的基础知识

2.2.1 C语言

只要是理工科专业的,似乎都会教C语言。我见过很多C语言考试90、100分的,一上机就傻了,我怀疑他们都没在电脑上写过程序。

理论再好,没有实践不能干活的话,公司招你去干嘛?

反过来,实践出真知,学习C语言,必须练练练、写写写!

当你掌握基本语法后,就可以在电脑上练习一些C语言习题了;

当你写过几个C程序后,就可以进入下一阶段的裸机开发了。


①不需要太深入

作为快速入门,只要你会编写“Hello, world!”,会写冒泡排序,会一些基础的语法操作,暂时就够了。

指针操作是重点,多练习;

不需要去学习过多的数据结构知识,只需要掌握链表操作,其他不用学习,比如:队列、二叉树等等都不用学;不需要去学习任何的函数使用,比如文件操作、多线程编程、网络编程等等;这些知识,在编写Linux应用程序时会用,但是在操作系统特别是驱动学习时,用不着!

永往直前吧,以后碰到不懂的C语言问题,我们再回过头来学习。

在后续的“裸机开发”中,会让你继续练习C语言,那会更实战化。

C语言是在写代码中精进的。


②可以在Visual Studio下学习,也可以在Linux下学习,后者需要掌握一些编译命令,我们暂时没有提供C语言的教程,找一本C语言书,网上找找免费的C语言视频(主要看怎么搭建环境),就可以自学了。


2.2.2 PC Linux基本操作:

对于PC Linux,我们推荐使用Ubuntu,在它上面安装软件非常简便。

我们的工作模式通常是这样:在Windows下阅读、编写代码,然后把代码上传到PC Linux去编译。实际上,Ubuntu的桌面系统已经很好用了,我们拿到各种智能机可以很快上手,相信Ubuntu的桌面系统也可以让你很快上手。为了提高工作效率,我们通常使用命令行来操作Ubuntu。


不用担心,你前期只需要掌握这几条命令就可以了,它们是如此简单,我干脆列出它们:

①cd : Change Directory(改变目录)

cd 目录名 // 进入某个目录cd .. // cd “两个点”:返回上一级目录cd - // cd “短横”:返回上一次所在目录

②pwd : Print Work Directory(打印当前目录 显示出当前工作目录的绝对路径)

③mkdir : Make Directory(创建目录)

mkdir abc // 创建文件夹abcmkdir -p a/b/c // 创建文件夹a,再a下创建文件夹b,再在b下创建文件夹c

④rm : Remove(删除目录或文件)

rm file // 删除名为file的文件rm -rf dir // 删除名为dir的目录

⑤ls : List(列出目录内容)

⑥mount : 挂载

mount -t nfs -o nolock,vers=2 192.168.1.123:/work/nfs_root /mntmount -t yaffs /dev/mtdblock3 /mnt

⑦chown : Change owner(改变文件的属主,即拥有者)

chown book:book /work -R //对/work目录及其下所有内容,属主改为book用户,组改为book

⑧chmod : Change mode(改变权限),下面的例子很简单粗暴

chmod 777 /work -R // 对/work目录及其下所有内容,权限改为可读、可写、可执行

⑨vi : Linux下最常用的编辑命令,使用稍微复杂,请自己搜索用法。


要练习这些命令,你可以进入Ubuntu桌面系统后,打开终端输入那些命令;或是用SecureCRT、putty等工具远程登录Ubuntu后练习。


2.2.3 硬件知识

我们学习硬件知识的目的在于能看懂原理图,看懂通信协议,看懂芯片手册;不求能设计原理图,更不求能设计电路板。

对于正统的方法,你应该这样学习:

①学习《微机原理》,理解一个计算机的组成及各个部件的交互原理。

②学习《数字电路》,理解各种门电路的原理及使用,还可以掌握一些逻辑运算(与、或等)。

③《模拟电路》?好吧,这个不用学,至少我在工作中基本用不到它,现在全忘光了。


就我个人经验来说,这些课程是有用的,但是:

①原理有用,实战性不强。

比如《微机原理》是基于x86系统,跟ARM板子有很大差别,当然原理相通。

我是在接触嵌入式编程后,才理解了这些课程。

②每本书都那么厚,内容都很多,学习时间过长,自学有难度。


针对这些校园教材的不足,并结合实际开发过程中要用到的知识点,我们推出了《学前班_怎么看原理图》的系列视频:

学前班第1课第1节___怎么看原理图之GPIO和门电路.wmv

学前班第1课第2.1节_怎么看原理图之协议类接口之UART.wmv

学前班第1课第2.2节_怎么看原理图之协议类接口之I2C.wmv

学前班第1课第2.3节_怎么看原理图之协议类接口之SPI.wmv

学前班第1课第2.4节_怎么看原理图之协议类接口之NAND Flash.wmv

学前班第1课第2.5节_怎么看原理图之协议类接口之LCD.wmv

学前班第1课第3节___怎么看原理图之内存类接口.wmv

学前班第1课第4.1节_怎么看原理图之分析S3C2410开发板.wmv

学前班第1课第4.2节_怎么看原理图之分析S3C2440开发板.wmv

学前班第1课第4.3节_怎么看原理图之分析S3C6410开发板.wmv


即使你只具备初中物理课的电路知识,我也希望能通过这些视频,让你可以看懂原理图,理解一些常见的通信协议;如果你想掌握更多的硬件知识,这些视频也可以起个索引作用,让你知道缺乏什么知识。


这些视频所讲到的硬件知识,将在《裸板开发》系列视频中用到,到时可以相互对照着看,加深理解。


2.2.4 要不要专门学习Windows下的单片机开发

很多学校都开通了单片机的课程,很多人都是从51单片机、AVR单片机,现在比较新的STM32单片机开始接触嵌入式领域,并且使用Windows下的开发软件,比如keil、MDK等。

问题来了,要不要专门学习Windows下的单片机开发?

①如果这是你们专业的必修课,那就学吧

②如果你的专业跟单片机密切相关,比如机械控制等,那就学吧

③如果你只是想从单片机入门,然后学习更广阔的嵌入式Linux,那么放弃在Windows下学习单片机吧!


理由如下:

①Windows下的单片机学习,深度不够

Windows下有很好的图形界面单片机开发软件,比如keil、MDK等。

它们封装了很多技术细节,比如:

你只会从main函数开始编写代码,却不知道上电后第1条代码是怎么执行的;

你可以编写中断处理函数,但是却不知道它是怎么被调用的;

你不知道程序怎么从Flash上被读入内存;

也不知道内存是怎么划分使用的,不知道栈在哪、堆在哪;

当你想裁剪程序降低对Flash、内存的使用时,你无从下手;

当你新建一个文件时,它被自动加入到工程里,但是其中的机理你完全不懂;

等等等。


②基于ARM+Linux裸机学习,可以学得更深,并且更贴合后续的Linux学习。实际上它就是Linux下的单片机学习,只是一切更加原始:所有的代码需要你自己来编写;哪些文件加入工程,需要你自己来管理。

在工作中,我们当然倾向于使用Windows下更便利的工具,但是在学习阶段,我们更想学习到程序的本质。


一切从零编写代码、管理代码,可以让我们学习到更多知识:

你需要了解芯片的上电启动过程,知道第1条代码如何运行;

你需要掌握怎么把程序从Flash上读入内存;

需要理解内存怎么规划使用,比如栈在哪,堆在哪;

需要理解代码重定位;

需要知道中断发生后,软硬件怎么保护现场、跳到中断入口、调用中断程序、恢复现场;

你会知道,main函数不是我们编写的第1个函数;

你会知道,芯片从上电开始,程序是怎么被搬运执行的;

你会知道,函数调用过程中,参数是如何传递的;

你会知道,中断发生时,每一个寄存器的值都要小心对待;

等等等。


你掌握了ARM+Linux的裸机开发,再回去看Windows下的单片机开发,会惊呼:怎么那么简单!并且你会完全明白这些工具没有向你展示的技术细节。


驱动程序=Linux驱动程序软件框架+ARM开发板硬件操作,我们可以从简单的裸机开发入手,先掌握硬件操作,并且还可以:

①掌握如何在PC Linux下编译程序、把程序烧录到板子上并运行它

②为学习bootloader打基础:掌握了各种硬件操作后,后面一组合就是一个bootloader


2.2.5 为什么选择ARM9 S3C2440开发板,而不是其他性能更好的?

有一个错误的概念:S3C2440过时了、ARM9过时了。

这是不对的,如果你是软件工程师,无论是ARM9、ARM11、A8还是A9,对我们来说是没有差别的。

一款芯片,上面有CPU,还有众多的片上设备(比如UART、USB、LCD控制器)。我们写程序时,并不涉及CPU,只是去操作那些片上设备。

所以:差别在于片上设备,不在于CPU核;差别在于寄存器操作不一样。

因为我们写驱动并不涉及CPU的核心,只是操作CPU之外的设备,只是读写这些设备的寄存器。

之所以推荐S3C2440,是因为它的Linux学习资料最丰富,并有配套的第1、2期视频。


2.2.6 怎么学习ARM+Linux的裸机开发

学习裸机开发的目的有两个:

①掌握裸机程序的结构,为后续的u-boot作准备

②练习硬件知识,即:怎么看原理图、芯片手册,怎么写代码来操作硬件


后面的u-boot可以认为是裸机程序的集合,我们在裸机开发中逐个掌握各个部件,再集合起来就可以得到一个u-boot了。

后续的驱动开发,也涉及硬件操作,你可以在裸机开发中学习硬件知识。


注意:如果你并不关心裸机的程序结构,不关心bootloader的实现,这部分是可以先略过的。在后面的驱动视频中,我们也会重新讲解所涉及的硬件知识。


推荐两本书:杜春蕾的《ARM体系结构与编程》,韦东山的《嵌入式Linux应用开发完全手册》。后者也许是国内第1本涉及在PC Linux环境下开发的ARM裸机程序的书,如果我说错了,请原谅我书读得少。


对于裸机开发,我们提供有2部分视频:

①环境搭建

第0课第1节_刚接触开发板之接口接线.wmv

第0课第2节_刚接触开发板之烧写裸板程序.wmv

第0课第3节_刚接触开发板之重烧整个系统.wmv

第0课第4节_刚接触开发板之使用vmwae和预先做好的ubuntu.wmv

第0课第5节_刚接触开发板之u-boot打补丁编译使用及建sourceinsight工程.wmv

第0课第6节_刚接触开发板之内核u-boot打补丁编译使用及建sourceinsight工程.wmv

第0课第7节_刚接触开发板之制作根文件系统及初试驱动.wmv

第0课第8节_在TQ2440,MINI2440上搭建视频所用系统.wmv

第0课第9节_win7下不能使用dnw烧写的替代方法.wmv

.................

原文链接:网页链接

㈢ linux 的学习除了掌握必要的指令外,还要学习什么

谈如何学习linux一.为什么要学linux?

当然最重要是爱好和兴趣!如果你这种必要学,或者根本不喜欢,请不要浪费时间,你学也学不好!

二.起步

你应该为自己创造一个学习linux的环境--在电脑上装一个linux或unix
问题1:版本的选择

北美用redhat,欧洲用SuSE,桌面mandrake较多,而debian是技术最先进的linux
开发人员中用debian的最多,其次是redhat,从全球linux各应用领域市场份额来看
无疑redhat是最多的,此外还有很多出名的发行版本,不再列举。
对于初学linux的人来说,我建议是使用redhat,原因如下:
1)现在很多书都是以redhat为例讲的,为了与书本协调一致
2)周围的人都用redhat,交流比较方便
3)redhat应用范围广,有典型性和代表性
4)它易于使用和安装,我们没有必要把时间浪费在“装系统”上
而应集中精力学习最有用的东西。

//注:现在觉得RH很死板,AS,ES等用在服务器上或许不错,
Personal desktop用mandrake,debian,suse都不错,笔者现在用Mandrake,因为她长得漂亮

如果你并不打算深入学习linux,而是有诸如适应北京市政府办公平台迁移到
linux上这种需要,那么中软,红旗等中文linux是不错的选择

我强烈建议:自己亲自动手把linux装到你的硬盘上,
你必须学会独立安装linux系统的技能,对于现在的版本来说,其实跟装WinXP一样简单

从此现在开始,请不要以windows的工作方式来考虑问题,
应该尝试挖掘linux身上的“天才unix”的气质。

三.进阶
掌握至少50个以上的常用命令
理解shell管道"|",文件流重定向">"及追加">>"等
熟悉Gnome/KDE等X-windows桌面环境操作
掌握.tgz.rpm.biz等软件包的常用安装方法
学习添加外设,安装设备驱动程序(比如modem)
熟悉Grub/Lilo引导器及简单的修复操作
熟悉系统固有目录的名称及公用
学会用mount命令访问其他文件系统
了解vi,gcc,gdb等常用编辑器,编译器,调试器
学习linux环境下的简单组网

建议:买一本不需要太厚的linux教材,大致可以满足要求
//现在的书越来越多了,还带很多图,我当时可没这么多书:)

四.高级应用

澄清一些概念:
linux的普通操作与真正的系统管理不能相提并论,后者需要很多知识

我个人认为比较重要几种linux语言
1.英语
即使你不学linux,我也强烈建议你学好英文[U.S.english]
因为实质上计算机语言就是英文和字符,所谓的多国语言只是外部包装
你必须能无障碍的阅读大量的英文技术文档
在搜索引擎找到的英文网站和网页中熟练的检索
最好能有用英文直接交流的能力,
摆脱了这个障碍,你的学习和理解速度就能快很多,你就有机会拉开和别人的差距

2.shell[sed/awk]
shell是命令解释器,是内核与用户界面交流通道,shell写的小脚本有点类似于win下的.bat
但shell比.bat强大的多,shell不只是解释命令,更是一种编程语言,有时候几百行的c用shell
几十行就能代替完成工作,因为shell的工作方式建立在系统已有的众多应用程序之上
这也是CS中的一个重要思想。
此外,shell可以实现工作自动化,这个概念也比较重要
sed,awk用来处理文本,历来很常用

3.Perl/php
漂亮的脚本, CGI的首选,比ASP好,应用面很广

4.C\C++
C、C++是linux/unix的核心语言,系统代码都是C写的

5.ASM
系统底层及内核,硬件,设备驱动程序,嵌入式开发都需要
//走核心路线的话,才c\c++,asm最重要

6.Java,Python,Tcl,XML

*系统管理篇
在熟悉linux的基础上还需要掌握至少一种unix
我首推Solaris,其次是FreeBSD
比如运营级系统一般是Solaris+Oracle/DB2之类的
学习apache,ssh,sendmail/Qmail,proftp/vsftp,Samba,Squid,MySQL/PostgreSQL/Oracle,Bind
等各种应用服务器的构架及电子商务的应用
熟悉TCP/IP协议族,学习诸如apache+php+proftp+mysql+quota的实现以及大型局域网,分布式集群
等各种企业级应用解决方案
熟悉多用户管理,数据库管理,文件系统,逻辑存储管理,日志分析,备份与灾难数据修复
系统补丁,内核升级,以及在此基础上的防火墙构架等以保障系统安全在内的各种系统管理技能

我觉得,如果在此基础上再掌握路由/交换设备便是一个不错的系统管理员

各种基于linux的解决方案可参考相关书籍和文献,必要时用google或各大linux站点站内
搜索引擎寻找最新文档,以避免错误和漏洞
有几本技术大全和技术内幕我认为都是这方面不错的书

*深入学习linux

我个人理解的读linux内核需要的基础:
在此之前,希望先把应用层的东西学一下,那样会比较好理解
1.C
如果学过潭浩强的大学教科书(除了编几个数学模型好像什么也做不了的那种),
建议再看一下
《The C Programming Language》Second Edition这本圣经
/*如果想学缓冲区溢出,这点C的功力可能是不够的*/
还有,,,
反正经典书看多了是没有坏处的

2.asm (AT&T语法,保护模式)
保护模式下的比较复杂,基本上每本讲内核的书都会有介绍
有80x86 Intel语法的基础就行,
有兴趣可以看看Intel的官方****

3.数据结构(离散数学)
计算机专业的核心课程,重要性我就不说了

4.操作系统原理
看懂这个再去读linux吧

5.微机原理/组成原理(数字电路)
底层直接和硬件打交道,所以这个也要

6.了解linux/unix
我想至少你要会操作吧,了解unix的API

7.软件工程/编译原理

这方面的经典书去www.china-pub.com可以搜到很多
我觉得APUE这种书不适合初学者,还是先看看UPE之类的吧

APUE:
《》
《unix环境高级编程》
作者:W.Richard.Stevens共有6本经典书,尊为“圣经”
他的书为全世界黑客所拜读!

UPE:《unixprogrammingenvironment》
《unix编程环境》比较适合初学者的,深入浅出,
其中有一些比较重要的思想
另外,介绍linux下应用层编程的书也有很多,比如
,redhat,redflag出的书...........
经典书还有很多很多......
操作系统:设计与实现//交大的考研参考书目,讲Minix的
unix操作系统设计
4.4BSD操作系统设计与实现
昂莱氏unix源代码分析
ulk:understanding the linux kernel (2nd)深入理解linux内核
linux设备驱动程序 (2nd)
linux内核源代码情景分析
保护方式下的80386及其编程

参考资料来自:51cto技术论坛

㈣ 就业方向

考哪些证书对我的就业有帮助
如CCNA就是思科的入门体系,这表明你已经基本地掌握了思科的网络知识,可是现在的话CCNA人数已经大有人在,如果以后想往思科方向发展最少要通过CCNP了,能拿到CCIE的证书是最好不过了。

再有就是思科属于国际认证,是各大企业招聘的优先选择标准,有真正的技术和能力,是很受社会青睐的呀。

计算机专业毕业后大致的工作方向是软、硬、网、图 四大类
尤其以软件、网络为现今的首选

从岗位上分,又可以分为技术道路、营销道路两大方向

if 你选择作技术,then 从现在开始,牢记:
天道酬勤!!!
if 你选择软件技术 then 每天都要用大量的时间学习高级语言,绝对不能仅限于学校的安排。优秀的程序员都是大学阶段就已经自学得非常深入了。
if you选择网络技术,那么你就多多从网上阅读有关资料

if you 选择营销类,那么,你只要将老师教授的学好就ok
但是,一定要用大量的时间到计算机公司去兼职做营销,踏踏实实提高自己与客户接触能力。

一、给计算机专业的同学

1.首先请你热爱这个专业。只有这样,你才会从抽象的理论中找到实实在在的快乐。如果你不热爱她,或者只因为这是个热门专业,那么极力要求你放弃这个专业,因为计算机是一把双刃剑,学好了你会飞黄腾达,学不好你毕业后会极其痛苦,高不成低不就,没有发展潜力,如同学英语专业的人到了美国一样。
2.不要用功利眼光对待这个学科,这绝对不是点点鼠标就能挣钱的专业。不要去想做网站挣钱,不要想靠点击率增加广告,这个在4年前已经过时,如果你现在仍然这么想,千万别说出来,因为我会觉得你很土。计算级专业的成就感总是伴随着身体上的痛苦而来,肩周炎,颈椎病,眼睛干涩,掉头发,腰椎间盘突出,关节炎,不夸张,这么帅的我工作了两个月以后发现开始掉头发了。
3.搞明白计算机“科学”与“技术”的含义。做网页,做图片,做flash,玩游戏,上网,听歌,录mp3,搞电影字幕,装windows,改注册表,为软件皮肤……这通通不叫计算机科学与技术,如果你是计算机的学生,会做以上事情,那是你应该的,不会做,也没什么丢人的,我们需要的不是让别人称作“高手”。
4.明确你最终的专业方向是软件还是硬件。方向是网络?网络不是专业方向。网络是最优秀的软件工程师、最优秀的硬件工程师与最优秀的通信工程师的智慧结晶。如果你是软件方向,请你在学精一揽子数学、数据结构、算法设计、数值分析、汇编语言、操作系统、编译原理、数据库原理、软件工程之类课程后,仔细的听一听硬件课程,他对你有用。软件工程绝对不是背背就能过的课,计算机理论可能是一个人就能研究出来,软件工程是成千万网软件工程师几十年来失败的教训凝结成的结晶,请认真听课。不要问我应该学什么语言,计算级专业的人必须具备任何语言1小时上手的能力,最起码要在10分钟把"hello world"做出来。如果说有必须学的两种语言,那他们是c++与java,学他们不是在学语言,而是在学thinking in c++,thinging in java,一个是软件的基础理论,一个是面向对象的基础理论,从来没有人听说过“thinking in basic”。如果你说c++过时了,那么千万别告诉别人你的名字,因为很丢人。山科大的老师只会教给你c,不会教给你++,所以不要被他蒙蔽,大胆的问他++,如果他不会,干脆换老师。学硬件的同学在认真听听以上课程后,学精除了政治以外的其他课程。
5.即使你学好了以上课程,我们仍然差得很远,我们只弄清学什么了,但是还不知道做什么。我们的课程设计太小儿科了,别对你在国外的同学说,否则会被笑话,所以我们要尽可能的多做设计,别一个人们闷着头做,两三个人合作一个项目,不会交流的计算机人员30岁以后肯定会下岗。题目呢,尽量是一些简单的底层开发,可以去国外大学网站上搜一搜,要自信你一定能做出来,毕竟不是什么难题,而是我们应当具备的素质。
6.如果你对网络有意,在具备了一定动手能力后从协议或者底层硬件的角度去学习它。否则你是自甘从一名高贵的计算机专业人员堕落为做着沉重机械体力劳动的民工。对网络安全感兴趣,那么你就在学会使用各种工具的一个月后从编程的角度深入学习网络协议和操作系统吧!只会用工具攻击无知人员的漏洞是一种意淫的行为,如果乐此不疲,并到处叫嚷“黑客”,那么这种行为可以被称作“手淫”。网上呼吁中美、中日黑客战时,希望你安心学习课程,或者睡觉休息,或者去运动娱乐,不要给祖国抹黑。
7.正确对待认证。绝大部分认证不是高薪的敲门砖,而是你上岗前的智商水平测试。如果你考过了认证,别对别人说这个认证是垃圾,请告诉别人你在学习中懂得了那些知识,如果你没有懂得知识,那么你是个paper,认证不是垃圾,你是垃圾。如果你连认证都没考就到处喊它垃圾,那么你就亲自考考试试,考过了,懂了,那么你随便;如果过了但是不懂,认证不是垃圾你是垃圾,如果没考过,那么看这个贴子的所有人都知道你是什么了。MCSE、CCNA、CIW等等都有它存在的意义,只要你有钱都值得一学,他们是最正规的知识来源,是经过理论、实践、时间与市场考验的产品。

㈤ 大家好,小弟一直不明白对linux或uboot源码包打补丁的原因。在网上查了资料也没有详细的介绍。

1、配置源码需要重新编译,而重新编译系统会花费大量的时间,而且Linux系统并不是修改源码就能编译通过,还涉及到很多的Makefile,那么要你单独一个个的修改工作量也会比较大。但是源码补丁可以自动识别和替换需要的,方便了一些并不是太熟悉Linux的人,而且减轻了用户的工作量。
2、既然是补丁,肯定都是针对某一些特殊情况开发的,并不是所有人都会遇到这些情况,也并不是所有人都需要这些补丁。Linux发布的源码都是一些Linux比较大的升级时候发布一次的,而源码是提供给所有人的,那么也不是每个人都需要这个补丁的源码呀,一般都只是下载和自己所从事专业有关的。

补丁的话随便你自己,因为不是所有人都需要那个补丁,就算你不装,也没什么问题的

㈥ Linux和windows的优势对比

Linux和Windows是两种操作系统,对于服务器运维的人来说,在为服务器选择操作系统系统的时候,是选择Linux还是Windows是让人困惑的事?

从用户群来说Linux是一个以开发者为中心的操作系统,而windows是以消费者为中心的操作系统,这也是两个操作系统作为根本的区别。简单来讲,两个系统的选择就是看你是开发用还是作为消费者使用。

具体到Linux与Windows的优缺点,可以总结为一下几点

1.Linux可以看到源代码,windows不行。

这一点直接导致的结果就是在特殊应用的场合可以自行剪裁和定制所需的内核模块,这对于高级系统内核管理优化和驱动程序的开发相当有利,另外也因为代码可见,不用担心恶意功能或者后门,对于军政企的使用比较有利。另外在系统出现严重问题的时候,可以自行修改代码或者接个几k的patch就能编译然后使用,而windows你得等微软的补丁。

2、Linux命令行功能强大,可以做任何事情,windows也有命令行,但是属于附属品。

命令行是Linux的根本,甚至你对某些命令不满意,你也可以自己修改或者编个自己的命令出来。命令行的好处是可重复。想要知道命令行的具体是什么你可以访问老男孩教育。如果你想要告诉别人一件事怎么做,一个命令行发过去就可以,想要再做一遍之前做过的一件事,调出历史命令记录重新执行一下就行。很多要定时做的事情写成脚本设个crontab定时,就完事儿。另外这样也可以保证你用一样的命令行,做的是一样的事情。

3、开放源码和高度可定制

开放源码的初衷,不是为了自由而是为了定制。AT&T UNIX从来就是有版权的,但是源代码仍然可用,这是为了让用户能够根据需要,去修改它。Linux社区所赞赏的软件和系统,多半遵循同样的规则——它应该能够适应不同用户的不同环境,能够轻易的改变自己的行为,能够轻松的与不同环境整合。与其假设别人和你的需求一致,不如给予它们定制系统的自由。

4、去中心化

分散的软件开发,也注定了系统的接口和形式不统一——因为大家都喜欢发明轮子。而每个人的轮子或多或少更适合自己和社区,而非所有人,而在Linux的环境下又没有人能强迫所有人用自己的轮子(除了Kernel开发者,但其实很多distro对kernel也有patch),所以与其制定一种实践,Linux更多的让用户去选择生活的方式。

你会看到Linux生态环境中有大量的distro,不同的distro有不同的init方式,不同的软件包管理器和安装策略;每个人习惯使用不同的VCS,不同的shell,不同的编辑器,都就是更多的选择的哲学的体现。

5、Linux是基于网络的,诞生于网络。

远程连接上SSH,你就可以轻松操控远在千里之外的Linux服务器,只要有相应的权限,几乎和坐在物理机面前没有区别,哪怕网速很糟糕,实际只是一些加密的字符在传送,需要的带宽很小。

㈦ c语言编译程序属于应用软件,系统软件还是工具软件

c语言编译程序属于系统软件。

编译程序(Compiler,compiling program)也称为编译器,是指把用高级程序设计语言书写的源程序,翻译成等价的机器语言格式目标程序的翻译程序。这里的编译程序是一种动作,是根据编译原理技术,由高级程序设计语言编译器翻译成机器语言二进制代码行为。因此它是系统软件。

计算机软件总体分为系统软件和应用软件两大类:系统软件是各类操作系统,如windows、Linux、UNIX等,还包括操作系统的补丁程序及硬件驱动程序,都是系统软件类。

应用软件可以细分的种类就更多了,如工具软件、游戏软件、管理软件等都属于应用软件类。电脑工具软件就是指在使用电脑进行工作和学习时经常使用的软件。

(7)补丁编译原理扩展阅读:

不同点

1、表现形式不同

硬件有形,有色,有味,看得见,摸得着,闻得到。而软件无形,无色,无味,看不见,摸不着,闻不到。软件大多存在人们的脑袋里或纸面上,它的正确与否,是好是坏,一直要到程序在机器上运行才能知道。这就给设计、生产和管理带来许多困难。

2、生产方式不同

软件是开发,它是人的智力的高度发挥,不是传统意义上的硬件制造。尽管软件开发与硬件制造之间有许多共同点,但这两种活动是根本不同的。

3、要求不同

硬件产品允许有误差,而软件产品却不允许有误差。

4、维护不同

硬件是要用旧用坏的,在理论上,软件是不会用旧用坏的,但在实际上,软件也会变旧变坏。因为在软件的整个生存期中,一直处于改变(维护)状态。

网络-计算机软件

阅读全文

与补丁编译原理相关的资料

热点内容
幼儿编程教育培训多少钱 浏览:401
经常生气有什么东西能解压 浏览:900
代理服务器地址和端口可以怎么填 浏览:62
unity5手游编译模型 浏览:265
安卓无人机app源码 浏览:808
pl1编程语言 浏览:801
台达plc编程换算指令大全 浏览:174
手机上的编程游戏 浏览:108
服务器密码机有什么用 浏览:477
dos磁盘命令 浏览:955
单片机cpu52的功能 浏览:691
opc服务器怎么开发 浏览:373
觅喜是个什么app 浏览:402
加密cd机 浏览:946
社保用什么app缴纳 浏览:313
nodevlinux 浏览:582
腾讯tt服务器怎么登录密码 浏览:898
windows命令提示符 浏览:352
win7管理员权限命令 浏览:729
地图app哪个适合老年人用 浏览:74