如何看懂源代码--(分析源代码方法)
java源码阅读技巧
![java源码阅读技巧](https://img.taocdn.com/s3/m/ec21b7241fb91a37f111f18583d049649b660efa.png)
java源码阅读技巧
阅读Java源码是每个Java程序员都应该具备的重要技能,以
下是一些阅读Java源码的技巧:
1. 理清目的,在阅读Java源码之前,首先要明确自己的阅读
目的是什么,是为了理解某个特定功能的实现,还是为了学习优秀
的编程实践和设计模式。
2. 选择合适的版本,Java的版本更新很快,不同版本的源码
可能会有一些差异,因此要根据自己的需要选择合适的版本进行阅读。
3. 从入口开始,通常情况下,阅读Java源码应该从入口开始,比如某个类或者某个方法,然后根据需要逐步深入。
4. 注重关键类和方法,Java源码非常庞大,不可能一下子全
部理解,因此要有选择地关注一些关键的类和方法,比如常用的集
合类、IO类等。
5. 结合文档,阅读Java源码时,要结合官方文档,了解每个
类和方法的作用和用法,这样能更好地理解源码的含义。
6. 调试和实践,阅读Java源码不仅仅是 passively reading,更重要的是要结合自己的实际项目进行调试和实践,这样能更深入
地理解源码的运行逻辑和细节。
7. 查阅其他资料,有时候Java源码本身并不能完全解答你的
疑惑,这时候可以查阅一些权威的书籍或者网络资料,加深自己的
理解。
总的来说,阅读Java源码需要耐心和细心,要有一颗渴望探索
的心态,同时要善于总结和归纳,不断地积累经验和知识。
希望以
上技巧对你有所帮助。
如何看懂源代码
![如何看懂源代码](https://img.taocdn.com/s3/m/1003913483c4bb4cf7ecd1b0.png)
如何看懂源代码我们在写程式时,有不少时间都是在看别人的代码。
例如看小组的代码,看小组整合的守则,若一开始没规划怎么看,不管是参考也好,从开源抓下来研究也好,为了了解箇中含意,在有限的时间下,不免会对庞大的源代码解读感到压力。
六个章节:( 1 )读懂程式码,使心法皆为我所用。
( 2 )摸清架构,便可轻松掌握全貌。
( 3 )优质工具在手,读懂程式非难事。
( 4 )望文生义,进而推敲组件的作用。
( 5 )找到程式入口,再由上而下抽丝剥茧。
( 6 )阅读的乐趣,透过程式码认识作者。
阅读他人的程式码(1 )---读懂程式码,使心法皆为我所用程式码是别人写的,只有原作者才真的了解程式码的用途及涵义。
许多程式人心里都有一种不自觉的恐惧感,深怕被迫去碰触其他人所写的程式码。
但是,与其抗拒接收别人的程式码,不如彻底了解相关的语言和惯例,当成是培养自我实力的基石。
对大多数的程式人来说,撰写程式码或许是令人开心的一件事情,但我相信,有更多人视阅读他人所写成的程式码为畏途。
许多人宁可自己重新写过一遍程式码,也不愿意接收别人的程式码,进而修正错误,维护它们,甚至加强功能。
这其中的关键究竟在何处呢?若是一语道破,其实也很简单,程式码是别人写的,只有原作者才真的了解程式码的用途及涵义。
许多程式人心里都有一种不自觉的恐惧感,深怕被迫去碰触其他人所写的程式码。
这是来自于人类内心深处对于陌生事物的原始恐惧。
读懂别人写的程式码,让你收获满满不过,基于许多现实的原因,程式人时常受迫要去接收别人的程式码。
例如,同事离职了,必须接手他遗留下来的工作,也有可能你是刚进部门的菜鸟,而同事经验值够了,升级了,风水轮流转,一代菜鸟换菜鸟。
甚至,你的公司所承接的专案,必须接手或是整合客户前一个厂商所遗留下来的系统,你们手上只有那套系统的原始码(运气好时,还有数量不等的文件)。
诸如此类的故事,其实时常在程式人身边或身上持续上演着。
许多程式人都将接手他人的程式码,当做一件悲惨的事情。
读懂IL代码就这么简单(一)
![读懂IL代码就这么简单(一)](https://img.taocdn.com/s3/m/841892c281eb6294dd88d0d233d4b14e85243e4d.png)
读懂IL代码就这么简单(⼀)⼀前⾔ 感谢 @冰麟轻武指出⽂章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初⼀看完全不知所云,只听⾼⼿们说,了解IL代码你能更加清楚的知道你的代码是如何运⾏相互调⽤的,此⾔⼀出不明觉厉。
然后开始接触IL,了解了⼀段时后才发现原来读懂IL代码并不难。
进⼊正题1.1 什么是IL IL是.NET框架中中间语⾔(Intermediate Language)的缩写。
使⽤.NET框架提供的可以直接将源程序编译为.exe或.dll⽂件,但此时编译出来的程序代码并不是CPU能直接执⾏的机器代码,⽽是⼀种中间语⾔IL(Intermediate Language)的代码(来源百度)1.2 为什么要了解IL 在很多时候不明⽩代码是如何操作时就可以通过IL指令来解释,⽐如,装箱,拆箱是否只是听别⼈说或者书上讲是怎么怎么实现的,⾃⼰是否证实过呢?了解IL指令你可清楚看到是每⼀步是如何处理的1.3 怎么学IL 世上有个定律叫“⼆⼋定律” ,80%的功能,只要⽤20%的技术就可以完成,但要完成另外20%可能就需要80%技术了,对于IL代码也是如此,有200多个指令,我们只需要⽤到其20%的指令就可以解决我们80%的问题了,所以我不会写太多,只是让⼤家能看懂普通的程序代码编译成IL代码后就⾏了,还有就是要多看,IL代码的每⼀条指令都是特定的意思,看得多了⾃然就懂了,当对⾃⼰代码有疑问时尝试看看它对应的IL代码,也许你会了解得更多。
IL指令⼤全IL代码编译器 ILDasm⼆如何查看IL代码 2.1 步骤 1 编写代码并编译通过 2 找到源⽂件的obj⽂件下的 .exe⽂件3 导⼊到ILDasm中反编译成IL代码上图1 -2步 3 导⼊到ILDasm中 ILDasm中图标含义三如何读IL(⼤致了解) 以上步骤完成后我们就可以看到代码被编译后的IL代码,以下部份将会对每⼀条IL指令做详细的解释C#代码1static void Main(string[] args)2 {3int i = 1;4int j = 2;5int k = 3;6 Console.WriteLine(i+j+k);7 }IL代码// Call Stack是⼀个栈,⽽Call Stack中的Record Frame则是⼀个局部变量列表,⽤于存储 .locals init (int32 V_0,int32 V_1,int32 V_2)初始化后的参数 V_0,V_1,V_2因图中没有把Record Frame 标记出来,所以⾃⼰画了⼀张图// Evaluation Stack 是⼀个栈 ldc.i4.2 这种指令都会先把值压⼊栈中等待操作在第四段时⼤家可以理解得更清楚⼀点另外@ 指出IL指令中第 9 11 13⾏容易让⼈误解值是从Record Frame中加载的现强调IL指令中第 9 11 13⾏的ldc.i4.1,ldc.i4.2,ldc.i4.3 执⾏这⼏条指令时值是还没有加载到Record Frame中的,但是MSDN也没有指出从哪⾥加载所以只能根据个⼈的想法解释,程序在编译后值类型数据会存在线程栈中,所以我认为此时的9 11 13⾏的值是从线程栈中取的1 .method private hidebysig static void Main(string[] args) cil managed2 {3 .entrypoint //程序⼊⼝4// Code size 19 (0x13)5 .maxstack 3//定义函数代码所⽤堆栈的最⼤深度,也指Evaluation Stackk中最多能同时存在3个值6//以下我们把它看做是完成代码中的初始化7 .locals init (int32 V_0,int32 V_1,int32 V_2) //定义 int 类型参数 V_0,V_1,V_2 (此时已经把V_0,V_1,V_2存⼊了Call Stack中的Record Frame中)8 IL_0000: nop //即No Operation 没有任何操作,我们也不⽤管它9 IL_0001: ldc.i4.1//加载第⼀个变量"i"的值 (压⼊Evaluation Stack中)10 IL_0002: stloc.0//从栈中把"i"的值弹出并赋值给Record Frame中第0个位置(V_0) 11 IL_0003: ldc.i4.2//加载第⼆个变量"j"的值 (压⼊Evaluation Stack中) 12 IL_0004: stloc.1//从栈中把"j"的值弹出并赋值给Record Frame中第1个位置(V_1)13 IL_0005: ldc.i4.3//加载第三个变量"k"的值 (压⼊Evaluation Stack中)14 IL_0006: stloc.2//从栈中把 "k"的值弹出并赋值给Record Frame中第2个位置(V_2)1516//上⾯代码初始化完成后要开始输出了,所以要把数据从Record Frame中取出1718 IL_0007: ldloc.0//取Record Frame中位置为0的元素(V_0)的值("i"的值)并压⼊栈中 (相当于Copy⼀份值Call Stack中V_0的值。
.net源码解析
![.net源码解析](https://img.taocdn.com/s3/m/3c763d08ff4733687e21af45b307e87101f6f8e0.png)
.net源码解析在.NET中,源代码解析是一种重要的技术,用于理解、分析和修改程序的内部逻辑。
下面是一些解析.NET源代码的基本步骤:1.安装开发环境: 安装适用于.NET开发的集成开发环境(IDE),例如Visual Studio或Visual Studio Code。
这些工具可以提供代码编辑、编译、调试等功能。
2.获取源代码: 可以从GitHub、NuGet、开源项目网站等渠道获取.NET源代码。
也可以直接从自己的项目中获取源代码。
3.了解代码结构: 阅读并理解代码的组织结构。
通常,源代码会被组织成不同的文件,例如包含类型定义的.cs文件、包含资源或字符串的.resx文件等。
4.解析类和对象: .NET是面向对象的编程语言,因此需要理解如何解析类和对象。
每个类都有属性、方法、事件等成员,可以通过这些成员理解类的行为和功能。
5.分析方法和逻辑: 分析方法如何被调用、方法的参数是什么、方法的返回值是什么,以及方法的内部逻辑。
这可以帮助理解整个程序是如何运行的。
6.使用调试器: 使用IDE的调试器可以帮助理解代码的执行流程。
设置断点、单步执行、查看变量值等操作可以帮助理解代码的执行过程。
7.阅读文档和注释: 源代码中的注释和文档可以帮助理解代码的意图和功能。
此外,还可以查阅.NET的官方文档以获取更深入的理解。
8.使用静态分析工具: 有一些工具可以帮助自动分析代码,例如Roslyn分析器、SonarQube等。
这些工具可以提供关于代码质量、潜在错误等方面的反馈。
9.修改和重构: 在理解源代码的基础上,可以进行修改或重构以提高代码质量、修复错误或增加新功能。
10.测试: 对修改后的代码进行测试,确保没有引入新的问题或破坏原有的功能。
解析.NET源码是一个不断学习和探索的过程,需要耐心和深入的理解。
通过不断地实践,可以提高自己的编程技能和理解能力。
检查代码的方法
![检查代码的方法](https://img.taocdn.com/s3/m/22bcd3677275a417866fb84ae45c3b3567ecdd84.png)
检查代码的方法全文共四篇示例,供读者参考第一篇示例:在软件开发过程中,代码检查是非常重要的环节。
它可以帮助开发人员发现潜在的bug和错误,并且提升代码质量。
本文将介绍一些常用的检查代码的方法,帮助开发人员更好地进行代码检查。
一、代码审查代码审查是最常用的一种检查代码的方法。
一般情况下,代码审查包括两种形式:静态代码审查和动态代码审查。
静态代码审查是通过检查源代码或编译后的代码进行审查。
它可以发现一些潜在的bug和编码风格问题。
常用的静态代码审查工具包括Lint、PMD、Checkstyle等。
动态代码审查是通过运行程序来检查代码的质量。
可以使用断点调试工具来检查代码的执行过程,查看变量的值是否正确、程序的执行路径是否正确等。
二、单元测试单元测试是一种非常有效的代码检查方法。
通过编写单元测试用例,可以测试代码的各个功能模块是否正常工作。
如果单元测试用例都通过了,那么说明代码的质量较高。
在编写单元测试用例时,需要考虑尽可能多的测试场景,包括正常情况和异常情况下的处理逻辑。
可以使用Mock框架来模拟一些外部依赖,从而使测试更加容易。
代码走查是一种通过团队协作来检查代码的方法。
一般在代码走查会有一个专门的评审小组,由团队成员轮流担任Leader,负责主持代码走查的过程。
在代码走查中,团队成员可以提出自己的看法和建议,帮助发现代码中的问题。
这种方法可以增强团队之间的沟通和合作,提升整个团队的代码质量。
四、代码规范检查代码规范检查是一种通过检查代码是否符合编码规范来评估代码质量的方法。
编码规范是一种统一的编码风格,可以帮助开发人员编写易读、易维护的代码。
在进行代码规范检查时,可以使用代码检查工具来自动检查代码中的规范问题,如缩进、命名规范、文档注释等。
这种方法可以节省开发人员的时间,同时提高代码的一致性和可读性。
五、自动化测试自动化测试是一种自动化进行测试的方法。
通过编写自动化测试脚本,可以帮助开发人员快速地测试代码的各个功能,提高测试效率和代码质量。
python 源码详解
![python 源码详解](https://img.taocdn.com/s3/m/7be397d24bfe04a1b0717fd5360cba1aa8118cbf.png)
python 源码详解Python是一种高级编程语言,具有简洁易读的语法和强大的功能,适用于各种领域的开发。
本文将详细解析Python源码,包括其结构、特点以及一些常见的模块和函数。
一、Python源码结构Python的源码由C语言编写而成,它采用了面向对象的设计思想,整体结构清晰。
源码主要包括以下几个模块:1. Parser模块:负责解析Python源码,将其转换为抽象语法树(AST)。
2. Compiler模块:将AST编译为字节码文件,即.pyc文件。
3. Interpreter模块:解释执行字节码文件,将其转换为机器码并执行。
二、Python源码特点Python源码有以下几个特点:1. 简洁易读:Python源码采用了简洁的语法,可读性强,使得开发人员能够更加快速地理解和修改代码。
2. 动态类型:Python是一种动态类型语言,源码中的变量可以根据上下文自动推断类型,提高了开发效率。
3. 内置模块丰富:Python源码中包含了大量的内置模块,提供了各种功能的实现,例如字符串处理、文件操作等,减少了开发人员的工作量。
4. 强大的库支持:Python拥有庞大的第三方库,覆盖了各种领域,如科学计算、机器学习、Web开发等,使得开发人员能够快速构建复杂的应用。
三、常见的Python模块和函数1. os模块:提供了与操作系统交互的功能,如文件操作、进程管理等。
其中的os.path模块封装了与路径相关的操作,如路径拼接、文件名提取等。
2. sys模块:提供了对Python解释器的访问和控制,可以获取命令行参数、修改模块搜索路径等。
3. re模块:用于进行正则表达式匹配和替换,可以方便地对字符串进行复杂的模式匹配操作。
4. datetime模块:处理日期和时间相关的操作,如获取当前时间、日期格式化等。
5. math模块:提供了数学运算相关的函数,如平方根、对数、三角函数等。
6. random模块:生成随机数的函数,如生成随机整数、随机选择列表中的元素等。
如何进行代码质量分析和管理
![如何进行代码质量分析和管理](https://img.taocdn.com/s3/m/d1396f4cb42acfc789eb172ded630b1c58ee9b1a.png)
如何进行代码质量分析和管理代码质量分析和管理是确保软件项目成功的关键步骤之一。
良好的代码质量能够降低软件维护成本,提高系统的可靠性和稳定性,增加开发效率,提高开发团队的工作满意度,能够帮助团队在竞争激烈的市场中立于不败之地。
在本文中,我将介绍如何进行代码质量分析和管理,以及为什么代码质量分析和管理对软件开发团队如此重要。
一、代码质量分析方法1.静态代码分析静态代码分析是一种无需在运行时执行代码的分析方法,通过检查代码本身来寻找潜在的错误和问题。
通常,静态代码分析可以通过使用一些自动化的工具来实现,这些工具能够检测代码中可能存在的错误、不良的编程习惯、潜在的安全漏洞和性能问题等。
常用的静态代码分析工具有SonarQube、Checkstyle、PMD等。
2.动态代码分析动态代码分析是一种在代码运行时监视其行为和性能的方法。
通过动态代码分析,开发团队可以找出代码中的性能瓶颈和内存泄漏等问题。
动态代码分析通常需要在开发、测试和生产环境中运行代码,并监测其行为、收集数据,然后进行分析。
常用的动态代码分析工具有JProfiler、YourKit等。
3.代码审查代码审查是一种通过人工检查和评审代码的方法,以发现和修复潜在的问题。
代码审查可以发现静态代码分析和动态代码分析工具无法检测到的问题,如代码逻辑错误、设计问题、与需求不符等。
代码审查可以通过一对一的代码审查、小组审查、工具辅助的代码审查等形式进行。
4.单元测试单元测试是一种通过编写测试用例对代码进行测试的方法,以确保代码能够按照预期的方式工作。
单元测试可以检查代码的功能正确性,避免由于后续修改而引入的错误。
良好的单元测试覆盖率可以帮助团队更好地理解代码的行为,并保证代码在修改后仍能够正常工作。
常用的单元测试框架有JUnit、TestNG等。
二、代码质量管理1.设定代码质量标准和指标在进行代码质量管理之前,团队需要制定适当的代码质量标准和指标。
标准和指标可以包括代码格式、注释规范、安全漏洞检测、性能指标等。
源代码是什么意思
![源代码是什么意思](https://img.taocdn.com/s3/m/aeefdff677a20029bd64783e0912a21614797fc2.png)
源代码是什么意思
源代码是指原始代码,可以是任何语言代码。
源码就是指编写的最原始程序的代码。
运行的软件是要经过编写的,程序员编写程序的过程中需要他们的“语言”。
1.计算机里面运行的所有东西都是用程序编出来的(包括操作系统,如Windows,还有Word等,网络游戏也一样),而编写程序要用到计算机语言,用计算机语言直接编出来的程序就叫源码,比如VisualBasic编写的源码文件一般为.bas文件,而用C++编写的一般为.cpp文件,源代码不能直接运行,必须编译后才能运行。
源码经过编译处理后就可以直接在操作系统下运行了。
2.很多的站长都喜欢使用建网站的程序源码,因为可以很方便的修改,对于任何一个seo人员来说,都是非常好的一个切入点。
3.从字面意义上来讲,源文件是指一个文件,指源代码的集合.源代码则是一组具有特定意义的可以实现特定功能的字符(程序开发代码)。
4.“源代码”在大多数时候等于“源文件”。
软件测试中的源代码分析
![软件测试中的源代码分析](https://img.taocdn.com/s3/m/c8d46e1fbdd126fff705cc1755270722192e59c9.png)
软件测试中的源代码分析在软件测试过程中,源代码分析是一种重要的技术手段,用于检查和评估软件系统的质量。
通过对源代码的深入分析,可以发现潜在的错误和缺陷,并提供改进软件系统的建议。
本文将介绍软件测试中的源代码分析的作用、方法和相应的工具。
作用源代码分析在软件测试中扮演着至关重要的角色。
首先,它可以帮助测试人员深入理解软件系统的内部运行机制,从而更好地进行测试设计和执行。
其次,通过源代码分析,可以检查代码中的潜在缺陷和漏洞,提前发现并修复可能导致软件故障的问题。
最后,源代码分析还可以评估代码的可维护性和可靠性,为软件开发团队提供改进代码质量的方向和建议。
方法源代码分析的方法包括静态分析和动态分析。
静态分析是指在不运行软件系统的情况下,通过对源代码进行分析来识别错误和缺陷。
动态分析是指在软件系统运行时,通过监控和分析程序的执行来检测问题。
下面将详细介绍这两种方法。
1. 静态分析静态分析是最常用的源代码分析方法之一。
它可以通过检查源代码的语法、结构和上下文关系来发现潜在的错误和漏洞。
静态分析可以通过手动分析或使用静态分析工具来完成。
手动分析需要测试人员具备良好的代码理解能力和经验。
他们需要仔细阅读代码,寻找潜在问题,并进行充分的评估和验证。
手动分析虽然需要更多的人力和时间,但对于复杂的软件系统和特定的测试需求,它仍然是一种有价值的方法。
静态分析工具可以自动化地分析源代码,并提供详细的错误和缺陷报告。
这些工具可以检查代码的质量、安全性、性能等方面,并提供相应的建议和改进措施。
常见的静态分析工具包括PMD、Checkstyle、FindBugs等。
2. 动态分析动态分析是通过在软件系统运行时监控和分析程序的执行过程来发现问题。
与静态分析相比,动态分析更加关注运行时行为和实际输入数据的影响。
动态分析可以帮助测试人员发现代码中的逻辑错误、内存泄漏、性能问题等。
动态分析的常见方法包括代码覆盖率分析、断言验证和性能分析。
python的源码解读
![python的源码解读](https://img.taocdn.com/s3/m/fbfb137fac02de80d4d8d15abe23482fb4da02b0.png)
python的源码解读
Python是一种高级编程语言,广泛应用于Web开发、数据分析、人工智能等领域。
Python的流行和成功,与其源代码的开放和易读性密不可分。
本文旨在探讨Python源代码的解读方法和技巧,让读者能够深入理解Python的实现原理和内部机制。
我们将从Python解释器、标准库、内置函数等方面入手,介绍Python源代码的组织结构、语法风格、注释规范等内容,同时讲解Python的一些高级特性,如元类、装饰器、生成器等,帮助读者提高Python编程水平。
无论你是初学者还是有一定经验的开发者,本文都能帮助你更好地理解和使用Python,欢迎阅读!
- 1 -。
Nginx源码分析:3张图看懂启动及进程工作原理
![Nginx源码分析:3张图看懂启动及进程工作原理](https://img.taocdn.com/s3/m/d6ea09c9ab00b52acfc789eb172ded630b1c9865.png)
Nginx源码分析:3张图看懂启动及进程⼯作原理编者按:⾼可⽤架构分享及传播在架构领域具有典型意义的⽂章,本⽂由陈科在⾼可⽤架构群分享。
转载请注明来⾃⾼可⽤架构公众号「ArchNotes」。
导读:很多⼯程师及架构师都希望了解及掌握⾼性能服务器开发,阅读优秀源代码是⼀种有效的⽅式,nginx 是业界知名的⾼性能 Web 服务器实现,如何有效的阅读及理解 nginx?本⽂⽤图解的⽅式帮助⼤家来更好的阅读及理解 nginx 关键环节的实现。
陈科,⼗年⾏业从业经验,曾在浙江电信、阿⾥巴巴、华为、五⼋同城任开发⼯程及架构师等职,⽬前负责河狸家后端架构和运维。
博客地址:/wiki/doku.php图⼀:nginx 启动及内存申请过程分析任何程序都离不开启动和配置解析。
ngx 的代码离不开 ngx_cycle_s 和 ngx_pool_s 这两个核⼼数据结构,所以我们在启动之前先来分析下。
内存申请过程分为 3 步1. 假如申请的内存⼩于当前块剩余的空间,则直接在当前块中分配。
2. 假如当前块空间不⾜,则调⽤ ngx_palloc_block 分配⼀个新块然后把新块链接到 d.next中,然后分配数据。
3. 假如申请的⼤⼩⼤于当前块的最⼤值,则直接调⽤ ngx_palloc_large 分配⼀个⼤块,并且链接到 pool→large 链表中内存分配过程图解如下(图⽚来⾃⽹络)为了更好理解上⾯的图,可以参看⽂末附 2 的⼏个数据结构:ngx_pool_s 及 ngx_cycle_s。
知道了这两个核⼼数据结构之后,我们正式进⼊ main 函数,main 函数执⾏过程如下调⽤ ngx_get_options() 解析命令参数;调⽤ ngx_time_init() 初始化并更新时间,如全局变量ngx_cached_time;调⽤ ngx_log_init() 初始化⽇志,如初始化全局变量 ngx_prefix,打开⽇志⽂件ngx_log_file.fd;清零全局变量 ngx_cycle,并为 ngx_cycle.pool 创建⼤⼩为 1024B 的内存池;调⽤ ngx_save_argv() 保存命令⾏参数⾄全局变量 ngx_os_argv、ngx_argc、ngx_argv 中;调⽤ ngx_os_init() 初始化系统相关变量,如内存页⾯⼤⼩ ngx_pagesize , ngx_cacheline_size ,最⼤连接数 ngx_max_sockets 等;调⽤ ngx_crc32_table_init() 初始化 CRC 表 ( 后续的 CRC 校验通过查表进⾏,效率⾼ );调⽤ ngx_add_inherited_sockets() 继承 sockets:解析环境变量 NGINX_VAR = 'NGINX' 中的 sockets,并保存⾄ ngx_cycle.listening 数组;设置 ngx_inherited = 1;调⽤ ngx_set_inherited_sockets() 逐⼀对 ngx_cycle.listening 数组中的 sockets 进⾏设置;初始化每个 module 的 index,并计算 ngx_max_module;调⽤ ngx_init_cycle() 进⾏初始化;该初始化主要对 ngx_cycle 结构进⾏;若有信号,则进⼊ ngx_signal_process() 处理;调⽤ ngx_init_signals() 初始化信号;主要完成信号处理程序的注册;若⽆继承 sockets,且设置了守护进程标识,则调⽤ ngx_daemon() 创建守护进程;调⽤ ngx_create_pidfile() 创建进程记录⽂件;( ⾮ NGX_PROCESS_MASTER = 1 进程,不创建该⽂件 )进⼊进程主循环;若为 NGX_PROCESS_SINGLE=1模式,则调⽤ ngx_single_process_cycle() 进⼊进程循环;否则为 master-worker 模式,调⽤ ngx_master_process_cycle() 进⼊进程循环;在 main 函数执⾏过程中,有⼀个⾮常重要的函数 ngx_init_cycle,这个阶段做了什么呢?下⾯分析 ngx_init_cycle,初始化过程:1. 更新 timezone 和 time2. 创建内存池3. 给 cycle 指针分配内存4. 保存安装路径,配置⽂件,启动参数等5. 初始化打开⽂件句柄6. 初始化共享内存7. 初始化连接队列8. 保存 hostname9. 调⽤各 NGX_CORE_MODULE 的 create_conf ⽅法10. 解析配置⽂件11. 调⽤各NGX_CORE_MODULE的init_conf⽅法12. 打开新的⽂件句柄13. 创建共享内存15. 创建socket进⾏监听16. 调⽤各模块的init_module图⼆:master 进程⼯作原理及⼯作⼯程以下过程都在ngx_master_process_cycle 函数中进⾏,启动过程:1. 暂时阻塞所有 ngx 需要处理的信号2. 设置进程名称3. 启动⼯作进程4. 启动cache管理进程5. 进⼊循环开始处理相关信号master 进程⼯作过程1. 设置 work 进程退出等待时间2. 挂起,等待新的信号来临3. 更新时间4. 如果有 worker 进程因为 SIGCHLD 信号退出了,则重启 worker 进程5. master 进程退出。
XFS服务源代码级深入解析20066794142532
![XFS服务源代码级深入解析20066794142532](https://img.taocdn.com/s3/m/a7a7e351f01dc281e53af07a.png)
“Diebold XFS服务”源代码级深入解析这篇文章的目的是记录一下我分析“Diebold XFS服务”软件是怎样实现的过程。
当然,我是没有Diebold软件的源代码的,也没看过一句我所分析内容涉及到的代码,其源代码只在国外才有,我手中只有执行程序,不过,一个软件有没有源代码对于我来说是无关紧要的,面对着计算机这个东西,我只看到代表0和1的高低电平在机器里面跳跃着,在总线、硬盘、内存之间不停的忙碌着,其实它们与人类的世界并没有什么分别。
如果你对Diebold XFS服务是怎样实现的感兴趣的话,可以看看,不过估计能够基本看懂这篇文章的人极少。
因为本来熟悉ATM平台软件编写的人就少,再者熟悉Diebold软件的人也少,而这两者都熟悉的人在中国不会再找到了。
不过,如果你有足够的技术基础和ATM行业知识的话,这篇文章应该对你会有些帮助的。
你要是接触过Diebold的机器,那么对于我在下文中提到的东西应该非常熟悉了,虽然你从来没有去想过在“Diebold XFS服务”背后,它都做了些什么工作。
(本文假设大家对ATM的相关标准都比较熟悉,不专门解释文中出现的每个术语)我这次是分析基于Windows平台下面的符合CEN/XFS标准2.0版(其实3.0基本不变)的Diebold软件,不管以前在OS/2下面常用的TCS 912等系统。
下面提到的底层都指Windows平台的底层,一般被迪堡称为Agilis Power平台。
因为Diebold在Windows平台下面的软件都是符合WOSA/XFS标准的,所以分为两个大部分,一个属于XFS Manager上面的一层,对应的业界标准一般是ActiveXFS规范,另外一个属于XFS Manager下面的一层,俗称SP,对应业界的WOSA/XFS规范。
“Diebold XFS服务”是XFS Manager上面的一层,但是它却跟其他上层模块没有太大关系。
如果接触过Diebold软件的人都知道,Diebold机器上要想运行ATM软件,首先是启动一个Windows系统服务,叫做Diebold XFS。
[ipsec][strongswan]strongswan源码分析--(一)SA整体分析
![[ipsec][strongswan]strongswan源码分析--(一)SA整体分析](https://img.taocdn.com/s3/m/b62c30ceba4cf7ec4afe04a1b0717fd5360cb27b.png)
[ipsec][strongswan]strongswan源码分析--(⼀)SA整体分析strongswan SA分析(⼀)1 概念下⾯主要介绍两个本⽂将要阐述的核⼼概念。
他们是SA和SP。
注意,这不是⼀篇不需要背景知识的⽂章。
作者认为你适合阅读接下来内容的的前提是,你已经具备了⼀下三⽅⾯的知识:a. 什么是VPN。
b. 什么是IPsec,包括IKE,ESP,strongswan都是什么等。
c. ⼀般的linux使⽤⽅法和常见概念。
1.1 什么是SAD,SPDSAD是Security Association Database的缩写。
SPD是Security Policy Database的缩写。
SAD是⽤来存储SA的数据库。
SPD是⽤来存储SP的数据库。
1.2 什么是SPISPI是Security Parameter Index的缩写。
是有⼀组数字(长度?)。
被使⽤在SAD和SPD⾥作为索引的⼀部分。
是由IKE协商的两侧客户端随机选择的UUID?。
0-255是被保留的值,禁⽌在SPI中使⽤。
1.3 什么是SASA是Security Association的缩写。
SA是⼀组算法和算法参数(包括key)的集合,⽤来完成单个⽅向的数据流加密和验证任务。
通过SPI加数据包的⽬的地址可以唯⼀查找到⼀个SA。
包含的属性:加密算法属性key验证算法属性keySPI⽬的地址1.4 什么是SPSP是Security Policy的缩写。
SP是⼀条规则,决定⼀条流(flow)是否需要被IPsec处理。
SP的处理有三种⽅式:丢弃不处理处理需要被IPsec处理的流,会被指向到⼀个template。
⼀个template可以理解为指向⼀个SA,template包含以下属性:协议AH或ESP。
模式transport或tunnel模式。
pattern源IP加⽬的IP对。
NAT的PORT对。
SP有⼀个⽅向属性,取值分别为:outinfwd1.5 总结在整个IPsec的数据流转逻辑中,SP⽤来表达What todo。
一个简单木马的源代码
![一个简单木马的源代码](https://img.taocdn.com/s3/m/b9f31b2d2af90242a895e5fb.png)
代码没给大家讲解,不知道看懂没。
所以,现在我原理给大家说一下,腾讯QQ 安装了两个钩子一个是WH_DEBUG,还有一个是WH_KEYBOARD_LL,当QQ的密码框获得焦点的时候DEBUG钩子就开始用SendInput发送乱码,在QQ启动的时候也会先调用SendInput发送一个乱码,所以就挂钩SendInput 这个函数,我们正确安装按键的时候QQ会通过WH_KERBOARD_LL低级钩子,发送一个错误的按键信息,在这里通过分析,发现在WIN7系统上真实的按键的就在0x12faa0处记录着,挂钩之后判断一下来源,if(nRetAddress!=0x74F3&&nRetAddress!=0x7374) ,就排除不是真实按键调用的,当然上面这句我们是WIn7上的地址,所有有朋友说,在XP上不行,由于我是WIN7的系统,还没装XP的虚拟机,所以并没添加这个判断,传进来的pInputs等我们基本上就不用去管他,然后通过if(pInputs->ki.dwFlags==0)判断是否是键盘按下,如果是按下,我们就开始记录。
DWORD nRetAddress=0;_asm{mov eax,0mov ax,[ebp+4]mov nRetAddress,eax}if(nRetAddress!=0x74F3&&nRetAddress!=0x7374)这就是取得是什么地方在调用SendInput.char key=0;_asm{mov ebx,0x12faa0mov eax,0mov al,[ebx]mov key,al}获取真实的按键,稍后我换上XP系统后,会将这个几个关键西方的发出,大家就可以在XP上也能使用这个木马了。
有人会问为什么我的文件是User32Hook.cpp 实际挂钩的是SendInput,这个是因为,我用OD分析的时候发现在User32.dll 中有一个固定地址通过[ebp+c]之后也可以获取到键盘按下的真实按键信息,只要挂钩在那里,也是可以获得真确的按键信息,然后写出木马,并且可以早于QQ的WH_KEYBOARD_LL钩子获取真实按键,就算QQ在WH_KEYBOARD_LL把WIN7下地址为0x12faa0的真实按键信息清0,也是没有用的,兴趣的朋友,就在WH_KEYBOARD_LL上下段,然后往上跟就会看到了。
如何阅读和理解他人的代码
![如何阅读和理解他人的代码](https://img.taocdn.com/s3/m/ca4066b5f71fb7360b4c2e3f5727a5e9856a2796.png)
如何阅读和理解他人的代码代码是计算机程序的基础,也是开发者之间交流和合作的重要方式。
然而,阅读和理解他人的代码并不容易。
不同的开发者有不同的编码风格和思维方式,理解他们的代码需要一定的技巧和经验。
本文将介绍一些有效的方法,帮助读者更好地阅读和理解他人的代码。
1. 注重代码结构和命名规范在阅读代码之前,首先要注意代码的结构和命名规范。
一个良好的代码结构能够使代码更易于理解和阅读。
因此,在阅读代码之前,可以先浏览代码的目录结构,查看代码组织是否清晰。
此外,代码中的命名规范也是关键。
开发者应该使用有意义的变量名、函数名和类名,以提高代码的可读性。
读者可以根据命名规范来推测代码的功能和作用,从而更好地理解代码。
2. 弄清上下文和功能在阅读代码时,要先弄清楚代码的上下文和功能。
可以阅读代码所在的文件和目录,查找相关的注释或文档,了解代码所在的项目和模块。
此外,还可以查看代码的版本控制记录,了解代码的修改历史和背景信息。
通过这些方式,读者可以更好地理解代码所处的环境和功能。
3. 逐步调试和运行代码阅读他人的代码时,可以尝试逐步调试和运行代码。
通过运行代码,可以观察代码的输出和行为,验证代码的正确性。
此外,借助调试器等工具,可以逐步跟踪代码的执行过程,了解代码的逻辑和控制流程。
通过调试和运行代码,读者可以更直观地理解代码的具体实现方式和运行机制。
4. 注重代码的注释和文档在阅读代码时,注释和文档是宝贵的资源。
好的注释可以解释代码的关键逻辑、算法和设计思路,帮助读者理解代码的含义和目的。
因此,在阅读代码时,要注意查找和阅读注释。
此外,如果有文档或说明文件,也应该仔细阅读。
文档可以提供代码的使用方法和注意事项,指导读者更好地理解和利用代码。
5. 利用工具和资源为了更好地阅读和理解他人的代码,可以利用各种工具和资源。
例如,代码编辑器可以提供代码高亮、自动补全等功能,提高代码的可读性。
代码分析工具可以帮助检测代码中的潜在错误和问题。
Code reading
![Code reading](https://img.taocdn.com/s3/m/d7f6e9707fd5360cba1adb5c.png)
• 图书目录 • 第1章 导论 • 第2章 基本编程元素 • 第3章 高级C数据类型 • 第4章 C数据结构 • 第5章 高级控制流程 • 第6章 应对大型项目 6 • 第7章 编码规范和约定 • 第8章 文档 • 第9章 系统构架 • 第10章 代码阅读工具 • 第11章 一个完整的例子 • 附录A 代码概况 • 附录B 阅读代码的格言
• • • • • • • • 第2章 基本编程元素 分析一个程序时,一般是从底部到顶部。 函数和全局变量 #include <stdio.h> int a; int b[100]; static void func(int a; int b); 上面包括了头文件、全局变量和函数声明。
6 6
代码阅读方法与实践
11 11
代码阅读方法与实践
• 面向对象技术-大型的复杂性经常使用面向对象 的技术和实现技术来控制。一般将面向对象组成 不同的层,用继承还提取公共行为,动态调动技 术使得单一代码可以处理众多不同的对象。 • 运算符重载-使用运算符重载,将专有的数据类 型提升为“一等公民”,然后就可以使用语言的 内建运算符对他们进行操作。 • 库-组件-进程-大型系统中代码经常分为对象 模块库,可重用组件,甚至是独立的进程。 • 领域专用和定制的语言工具-大型的编码工作通 常涉及到工具的创建,或者在相关的工具中收益, 比如编译过程中,使用的专用工具等等。
12 12
代码阅读方法与实践
• 项目组织-我们通常通过浏览源代码树-浏览源 代码的层次目录结构,来分析一个项目的组织方 式。源码树能反映出项目在软件和架构中的结构。 • 编译过程-大型项目需要一个复杂的编译系统。 这类过程通常能够处理配置选项,多种类型的数 据输入输出文件、错综复杂的相互依赖和多个编 译目标。 • 配置-配置可以控制软件系统,允许开发者编译、 维护和发展源代码的单一正式版本。 • 修订和控制-代码我们可以想象成是时间和空间 的延伸,代码,组织成文件和目录形式,占据空 间。同一代代码随着时间不断演化。修订和控制 可以用来追踪代码的演化过程,标记重大事件, 并记录更改的原因。CVS SVN
java项目经验总结
![java项目经验总结](https://img.taocdn.com/s3/m/dbfbc51bf011f18583d049649b6648d7c1c7083e.png)
java项目经验总结java项目经验总结java项目经验总结【1】这是一次比较完整的团队合作项目,它要求团队各成员对系统的主体设计搭成一定的共识,这包括数据库设计,需求分析,以及其它一些细节,因此在编码之前的准备工作一定要充分。
在设计之前,我们两组对于数据库的设计进行了激烈的讨论,最后在一些关键的问题上统一了意见。
接下来的工作便是需求分析,具体结构设计,并制订小组项目详细计划,项目的进行将严格按照所制订的计划执行。
然后小组成员对各自的数据库进行了设计,并且以数据字典的形式进行了共享。
企业级人力资源系统分为十个子系统:机构编制管理、人员信息管理、人事档案管理、考勤管理、薪资福利管理、社会保障管理、招聘管理、合同管理、查询统计管理、系统管理。
我负责人员信息管理子系统,这方面需要处理的业务逻辑比较少,表单比较多,要把握好与其它子系统的关联。
员工基本信息表是与其它子系统关联的桥梁,大部分表都涉及到与基本信息表的外键关联。
其中,职员编号(employeeId)是作为外键关联的字段,我给它设置了自增长。
有人认为在企业里,职员编号应该是有一定规律的数字,而不应该设置自增长。
这样的是想法很符合实际情况,后来我和两个组长讨论,认为自增长可以保证数据的唯一性,非自增长的主键在增加时可能遇到不可知的问题,并且其他组员的数据库已经设计好,改起来就麻烦了。
因此最终职员编号采用了自增长。
有了上面的共识,接下来的重要工作便是依次完成表的增删改查、数据校验。
其中,分页和批量删除是我计划最后完成的部分,并且一定要完成。
基本数据校验按各数据格式进行,例如手机号、e-mail等。
另一方面要对职员编号与姓名的一致性,职员编号的存进行验证,这些通过DAO里面的方法实现,针对出错,用JS给出友好的提示。
在做好基本功能的前提下,争取做出特色。
我尝试写了Hibernate分页、批量删除的代码,最后都测试成功。
同时加入了JS控件,对于一些有特殊格式要求的字段,防止用户填写错误(比如日期的填写格式为yyyy-mm-dd),使系统更加人性化。
如何使用反编译工具分析源代码(六)
![如何使用反编译工具分析源代码(六)](https://img.taocdn.com/s3/m/723937e932d4b14e852458fb770bf78a65293abc.png)
如何使用反编译工具分析源代码在软件开发和信息安全领域,反编译工具是一种常用的工具,它可以将编译后的可执行文件还原为源代码。
使用反编译工具分析源代码有助于理解软件的内部结构和逻辑,对于开发者和安全研究人员来说都具有重要意义。
本文将介绍如何正确地使用反编译工具来分析源代码,并提供一些实用的技巧和注意事项。
一、选择合适的反编译工具首先,我们需要选择适合自己需要的反编译工具。
目前市场上有很多不同的反编译工具,比如IDA Pro、Ghidra、Jeb等。
这些工具都有各自的特点和优缺点,我们需要根据自己的需求和实际情况来选择合适的工具。
二、导入目标文件在使用反编译工具之前,我们需要将目标文件(可执行文件、动态链接库等)导入到工具中。
一般来说,反编译工具都提供了导入文件的功能,我们只需要将目标文件拖拽到工具界面中即可。
导入完成后,工具会自动进行反编译,并将反编译结果展示给用户。
三、分析源代码结构在获得源代码之后,我们可以开始分析代码的结构和逻辑。
首先,我们可以查看函数和变量的定义和声明。
通过查看函数和变量的定义,我们可以了解软件的整体结构和模块关系。
接下来,我们可以深入分析函数的实现细节。
可以查看函数内部的代码逻辑、控制流程以及函数调用关系等信息。
这些信息对于理解软件的实现逻辑和功能起着重要作用。
此外,一些反编译工具还提供了图形化的展示功能,能够以图形的形式显示代码的结构和关系。
通过这种方式,我们可以更直观地理解代码的层次结构和模块间的依赖关系。
四、注意事项在使用反编译工具分析源代码时,我们需要注意以下几点:1. 版权和法律问题。
反编译工具的使用需要遵守版权和法律规定。
在分析他人代码的时候,尤其要注意不要侵犯他人的知识产权。
2. 代码的可读性。
由于反编译过程中会存在一些信息的丢失和变形,因此反编译出来的源代码可能不如原始代码可读。
在分析过程中,我们需要针对具体情况进行适当的推理和猜测,以还原原始代码的意图。
3. 代码的准确性。
网页的基础代码分析
![网页的基础代码分析](https://img.taocdn.com/s3/m/1a4d7e6e783e0912a2162a6b.png)
具体从三个角度来进行解析:1.网页是什么.2.网页的构成元素.3. 网页的真实面目.4.网页类型解读.5.一些与网页密切相关的技术.1.网页是什么现在你所打开的,出现在你面前的就是网页。
网页我们可以简单的理解成是一个文件,它通过你所放置的世界某台电脑与Internet实现互联。
网页通过域名解析,在我们输入网址时,经过域名解析系统,网页便可以快速出现在我们面前。
2.网页的构成元素其基本的构成大家都一目了然,如:文字、图片、视频等。
当然隐约中我们用视觉看不到的有很多程序。
3. 网页的真实面目当你打开一个网页,右键的是时候,点击“查看源文件”,你就会发现很多的英文字母,这就是网页最基本的构成:HTML代码每个网页基本的结构都是相似的<html><head><title> </title><body></body></head></html>4.网页类型解读网页源文件通常都是以htm 或html 后缀结尾的,简称HTML文件。
不同的后缀,分别代表不同类型的网页文件,例如以CGI、ASP、PHP、JSP甚至其他更多。
HTML其全称叫HyperText MarkupLanguage,我们称作超文本标记语言,通过标记(tag)用来对网页字体进行描述的语言,只要使用文本编辑器便可编辑,同VB、C++等编程语言有着本质上的区别。
的工作原理是必要的,懂得知道其标记的意思就可,因为有很多网页编辑软件为我们快速地生成HTML代码,例如Dreamweaver 和Frontpage ,再也不用一个个的编写HTML代码。
CGI:CGI 全称为Common Gateway Inte**ce它是一种编程标准,它规定了Web服务器调用其它可执行程序(CGI 程序)的接口协议标准。
CGI 程式通过读取使用者的输入请求从而产生HTML 网页。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如何看懂源代码--(分析源代码方法)
4
推
荐
由于今日计划着要看Struts 开源框架的源代码
昨天看了一个小时稍微有点头绪,可是这个速度本人表示非常不满意,先去找了下资
料, 觉得不错...
摘自(繁体中文
Traditional Chinese):http://203.208.39.132/translate_c?hl=zh-CN&sl=en&tl=zh-CN&u=http://ww /itadm/article.php%3Fc%3D47717&prev=hp&rurl=&usg=AL kJrhh4NPO-l6S3OZZlc5hOcEQGQ0nwKA 下文为经过Google翻译过的简体中文版:
我们在写程式时,有不少时间都是在看别人的代码。
例如看小组的代码,看小组整合的守则,若一开始没规划怎么看,就会“噜看噜苦(台语)”不管是参考也好,从开源抓下来研究也好,为了了解箇中含意,在有限的时间下,不免会对庞大的源代码解读感到压力。
网路上有一篇关于分析看代码的方法,做为程式设计师的您,不妨参考看看,换个角度来分析。
也能更有效率的解读你想要的程式码片段。
六个章节:
( 1 )读懂程式码,使心法皆为我所用。
( 2 )摸清架构,便可轻松掌握全貌。
( 3 )优质工具在手,读懂程式非难事。
( 4 )望文生义,进而推敲组件的作用。
( 5 )找到程式入口,再由上而下抽丝剥茧。
( 6 )阅读的乐趣,透过程式码认识作者。
程式码是别人写的,只有原作者才真的了解程式码的用途及涵义。
许多程式人心里都有一种不自觉的恐惧感,深怕被迫去碰触其他人所写的程式码。
但是,与其抗拒接收别人的程式码,不如彻底了解相关的语言和惯例,当成是培养自我实力的基石。
对大多数的程式人来说,撰写程式码或许是令人开心的一件事情,但我相信,有更多人视阅读他人所写成的程式码为畏途。
许多人宁可自己重新写过一遍程式码,也不愿意接收别人的程式码,进而修正错误,维护它们,甚至加强功能。
这其中的关键究竟在何处呢?若是一语道破,其实也很简单,程式码是别人写的,只有原作者才真的了解程式码的用途及涵义。
许多程式人心里都有一种不自觉的恐惧感,深怕被迫去碰触其他人所写的程式码。
这是来自于人类内心深处对于陌生事物的原始恐惧。
读懂别人写的程式码,让你收获满满
不过,基于许多现实的原因,程式人时常受迫要去接收别人的程式码。
例如,同事离职了,必须接手他遗留下来的工作,也有可能你是刚进部门的菜鸟,而同事经验值够了,升级了,风水轮流转,一代菜鸟换菜鸟。
甚至,你的公司所承接的专案,必须接手或是整合客户前一个厂商所遗留下来的系统,你们手上只有那套系统的原始码(运气好时,还有数量不等的文件)。
诸如此类的故事,其实时常在程式人身边或身上持续上演着。
许多程式人都将接手他人的程式码,当做一件悲惨的事情。
每个人都不想接手别人所撰写的程式码,因为不想花时间去探索,宁可将生产力花在产生新的程式码,而不是耗费在了解这些程式码上。
很遗憾的是,上述的情况对程式人来说很难避免。
我们总是必须碰触到其他人所写成的程式码,甚至必须了解它,加以修改。
对于这项需求,在现今开放原始码的风气如此盛行的今日,正如之前的“程式设计2.0 ”文中所提到的,你可以透过开放原始码学习到新的技术,学习到高手的架构设计,大幅提高学习的效率及效果。
你甚至可以直接自开放原始码专案中抽取,提炼出自己所需的程式码,站在巨人的肩膀上,直接由彼端获得所需的生产力。
从这个观点来看,读懂别人所写的程式码,就不再只是从负面观点的“被迫接收”,而是极具正面价值的“汲取养份。
”
先了解系统架构与行为模式,再细读
倘若撰写程式码是程式人的重要技艺之一,那么读懂别人的程式码,接着加以修改,也势必是另一个重要的技艺。
如果你不能熟悉这项工作,不仅在遭逢你所不愿面对的局面时,无法解决眼前接手他人程式码的难题,更重要的是,当你看着眼前现成的程式码,却不知如何从中撷取自己所需,导致最后只能入宝山空手回,望之兴叹。
接触他人的程式码,大致上可以分为三种程度:一,了解,二,修改,扩充,三,抽取,提炼。
了解别人的程式码是最基础的工作,倘若不能了解自己要处理的程式码,就甭论修改或扩充,更不可能去芜存菁,从中萃取出自己所需,回收再利用别人所撰写的程式码。
虽说是“阅读”,但程式码并不像文章或小说一样,透过这种做法,便能够获得一定程度的了解。
阅读文章或小说时,几乎都是循序地阅读,你只消翻开第一页,一行行阅读下去即可。
但是,有许多程式人在试着阅读其他人的程式码时,却往往有不知如何读起的困难。
或许找到系统的第一页(也就是程式码执行的启始点)并不难,但是复杂度高的系统,有时十分庞大,有时千头万绪。
从程式码的启始点开始读起,一来要循序读完所有的程式码旷日费时,二来透过这种方式来了解系统,很难在脑中构建出系统的面貌,进而了解到系统真正的行为。
所以,阅读程式码的重点,不在于读完每一行程式码,而是在于有效率地透过探索及阅读,从而了解系统的架构及行为模式。
以便在你需要了解任何片段的细节实作时,能够很快在脑上对映到具体的
程式码位置,直到那一刻,才是细读的时机。
熟悉沟通语言与惯例用语
不论如何,有些基本的准备,是阅读他人程式码时必须要有的。
首先,你最好得了解程式码写成的程式语言。
想要读懂法文写成的小说,总不能连法文都不懂吧。
有些情况则很特殊。
我们虽然不懂该程式码撰写所用的语言,但是因为现代语言的高阶化,而且流行的程式语言多半都是血统相近,所以即使不那么熟悉,有时也可勉力为之。
除了认识所用语言之外,再来就是要先确认程式码所用的命名惯例(命名惯例)。
了解命名惯例很重要,不同的程式人或开发团队,差异可能很大。
这命名惯例涵盖的范围通常包括了变数的名称,函式的名称,类别(如果是物件导向的话)的名称,原始码档案,甚至是专案建构目录的名称。
倘若使用了像设计模式之类的方法,这些名称更有一些具体的表述方式。
命名惯例有点像是程式人在程式语言之上,另行建构的一组沟通行话。
程式人会透过共通约束,遵守的命名惯例,来表达一些较高阶的概念。
例如,有名的匈牙利式命名法,便将变数名称以属性,型别,说明合并在一起描述。
对程式人来说,这种方式能够提供更丰富的资讯,以了解该变数的作用及性质。
对程式码阅读来说,熟悉这个做法之所以重要,是因为当你了解整个系统所采用的惯例时,
你便能试着以他们所共同操用的语汇来进行理解。
倘若,不能了解其所用的惯例,那么这些额外提供的资讯,就无法为你所用。
像以设计模式写成的程式码,同样处处充满着模式的名称,诸如:工厂,门面,代理等等。
以这些名称指涉的类别,也直接透过名称,表达了它们自身的作用。
对于懂得这命名惯例的读者来说,不需要深入探索,也能很快捕捉到这些类别的意义。
当你拿到一套必须阅读的程式码时,最好先取得命名惯例的说明文件。
然而,并不是每套程式码都附有此类的说明文件。
另一个方式,就是自己到程式码中,大略浏览一遍,有经验的程式人可以轻易发掘出该系统所用的命名惯例。
常见的命名方式不脱那几类,这时候经验就很重要,倘若你知道的惯例越多,就越能轻易识别他人所用的惯例。
如果运气很糟,程式码所用的惯例是前所未见的,那么你也得花点时间归纳,凭自己的力量找出这程式码命名上的规则。
掌握程式码撰写者的心态与习惯
大多数的程式码,基本上都依循一致的命名惯例。
不过运气更差的时候,一套系统中可能会充斥着多套命名惯例。
这有可能是因为开发团队由多组人马所构成,每组人马都有不同的文化,而在专案开发管理又没有管控得宜所造成。
最糟的情况,程式码完全没有明显的惯例可言,这时候阅读的难度就更高了。
想要阅读程式码,得先试着体会程式码作者的“心”。
想要这么做,就得多了解对方所使用的语言,以及惯常运用的语汇。
在下一回中,我们将继续探讨阅读程式码的相关议题。
阅读他人的程式码( 2 ) -摸清架构,便可轻松掌握全貌
在本文中,我们的重点放在:要了解一个系统,最好是采取由上至下的方式。
先试着捕捉系统架构性的观念,不要过早钻进细节,因为那通常对于你了解全貌,没有多大的帮助。
阅读程式码不需要从第一行读起,我们的目的并不是在于读遍每一段程式码。
基于许多原因,程式人需要阅读其他人所写成的程式码。
而对程式设计2.0时代的程式人来说,最正面的价值在于,能读懂别人程式的人,才有能力从中萃取自己所需的程式,借以提高生产力。