如何提高阅读代码的能力?

一.对于偏 算法 代码的阅读

  1. 学习编程基础知识:了解编程语言、数据结构、算法和设计模式等基础知识,可以帮助你更好地理解代码的逻辑和实现方式。这些基础知识也是评估代码质量、可维护性和可扩展性的关键。

  2. 熟悉代码规范和约定:每种编程语言都有自己的代码规范和约定,例如命名规则、缩进、注释等。了解这些规范和约定可以让你更好地理解代码的组织和结构,并且能够更快地适应不同的项目和代码库。

  3. 使用合适的工具:使用合适的工具可以显著提高阅读代码的效率和质量。例如,使用集成开发环境(IDE)可以提供代码高亮、自动完成和代码导航等功能,能够帮助你更快地理解代码结构;使用版本控制系统可以让你更好地跟踪代码变更和分支,以便更好地管理代码版本;使用调试器可以让你逐步执行代码并观察变量的值,以便更好地理解代码的行为。

  4. 阅读最佳实践和设计模式:了解编程最佳实践和设计模式可以帮助你更好地理解代码的结构和组织,以及如何优化代码的可读性和可维护性。通过学习不同的设计模式和算法,你可以更好地理解代码中使用的模式和策略,并更好地评估其优劣。

  5. 练习阅读代码:最重要的是,多练习阅读代码。可以尝试阅读一些开源项目、自己的项目、或者一些在线的代码阅读练习。通过不断地练习,你可以逐渐提高阅读代码的能力,并更好地理解代码的组织和逻辑。

  6. 参与编程社区:参与编程社区可以让你接触到更多的代码和编程经验,并学习到其他人的编程技巧和方法。通过与其他开发者交流和讨论,你可以更好地理解不同的编程思路和策略,并学习如何解决常见问题。

  7. 培养代码阅读能力:除了以上几点,还需要培养以下几个方面的能力:

    • 理解代码结构和逻辑的能力:需要了解代码的层次结构和逻辑关系,例如函数、类、模块之间的关系等。
    • 分析代码性能的能力:了解代码的性能瓶颈并对其进行优化,可以帮助你更好地评估代码的质量和可维护性。
    • 掌握调试技巧的能力:调试是提高代码质量的重要手段之一。掌握调试技巧可以帮助你快速定位和解决问题,并更好地理解代码的行为。
    • 评估代码质量的能力:了解代码的质量标准,例如可读性、可维护性、可扩展性等,可以帮助你更好地评估代码的价值和使用价值。

二.对于偏 工程 代码的阅读

1.运行代码——这是阅读代码的第一步。这可能不会给你过多关于项目的细节,但是,你将知道如何构建它并运行它,你将了解它使用的库、它所依赖的开发框架等等,这是提高你对某个特定项目理解的好方法。如果你想编写与你正在探究的特定项目类似的自己的软件,你可能会对你应该使用的框架或库有一些想法

2.找到高层次的逻辑——当你开始阅读一个项目的代码时,你可能会陷入到每一个细节当中。这是有问题的,相反的,你应该专注于高层次的结构。要找到切入点,并从那里开始,大部分的软件项目都有一个主要的方法,就从那里开始。此外,如果这是一个web应用程序,请开始查看不同的包,比如业务逻辑存放在何处、UI代码保存在哪里、控制器在何处等等。大致来说,就是浏览整个项目并获得一个基本的想法,然后问自己想专注于什么地方,就先从那个部分读起。你可以不读完整的代码库,而只是读它可能会引起你兴趣的一部分。当你找到你的切入点,你可以通过方法调用,看它引领你到何处,从而了解项目的业务逻辑。

3.使用/了解工具——有很多工具可以用来阅读和探究源代码,有助于可视化代码。例如,IntelliJIdea工具具有导航源代码的功能,允许你通过单词、单词的一部分,甚至是单词的缩写来搜索。你也应该学习键盘快捷键。用鼠标导航源代码可能会相当枯燥和缓慢,用键盘快捷键可以更快地跳转。你可以快速地从源代码的一部分跳转到另外一部分。

还有一个阅读代码的好软件,叫Sourcegraph,这是由两个斯坦福大学的毕业生创建的,他们是Quinn Slack 和 Beyang Liu,他们在花费时间去查看缺少文档说明的代码以后,决定开发一个工具来帮助他们更好地阅读和理解代码。

4.了解语言/约定——深入了解某个特定语言有助于提高代码阅读技能。每种语言都有自己的一套约定、样式和语法。这些知识帮助你快速地熟悉一个特定的代码。例如,在java语言中,方法名以小写字母开头,而在C#语言中,方法名以一个大写字母开头。知道这个区别可以帮助你从源代码中识别方法。

5.阅读最佳实践/设计模式——你正在阅读的代码,或者它的某个结构,可能看起来很晦涩,或者你可能不熟悉它,这是很自然的。有许多良好的实践和设计模式,人们用它来正确地和最佳地做事。例如,有一种模式称为Singleton,它的构造函数保持私有。你可能会问,究竟为什么有人想保持构造函数私有呢。我一直认为它是公有的,否则,我如何创建一个类的实例。嗯,这背后有一个原因。Singleton模式防止你不止一次地实例化一个类,其中有许多实际的应用案例。如果你了解这种模式,你就不会为此而头撞南墙了。因此,对于某些模式的了解,例如,Gang of Four(Erich Gamma, Richard Helm, Ralph Johnson,John Vlissides软件设计领域的四位世界顶级大师.)有23种有文档说明的设计模式,可以显著地帮助你提高代码阅读能力。

6.代码审查——软件开发是一个非常讲究协作的工作。没有人可以单独构建一个大型的或重要的软件。每个软件都是由一个团队构建的。在一个团队中,每个人都贡献自己的一份力量去塑造这个项目。在项目结束的那一天,每个人的贡献都会合并成一份对用户真正有价值的工作。除了做实际的编码以外,现在每一个团队都有另外一种做法,那就是在进行观察、建议和相互学习时,互相审查对方的代码。这是一个构建代码库知识的强有力的工具,在团队中建立牢固的纽带,提高代码质量,从而减少系统中的错误,并使客户满意。

做代码检查,你不得不阅读团队中其他人的代码,最终会提高你的代码阅读能力。

7.临时重构——临时重构也可以帮助您提高代码阅读技能。你可以找取一段长的方法代码,然后不断地把方法细分成多个部分。持续分解,直到你了解这一大段方法代码背后真正的意义。之后,你可以对这些方法做些注释,然后回滚这些更改。

这可以帮助你理解方法的架构,也可以增加你代码重构的知识。

举个例子(偏算法)


题面
(高精度计算)由于计算机运算的数据范围表示有一定限制,如整型int表达范围是(-2^31~2^31-1),unsigned long(无符号整数)是(0~2^32-1),都约为几十亿,因此在计算位数超过十几位的数时,不能采用现有类型,只能自己编程计算。
高精度计算通用方法:高精度计算时一般用一个数组存储一个数,数组的一个元素对应于数的一位,将数由低位到高位依次存储在数组下标对应的由低到高的位置上。另外,申请数组大小时,一般考虑了最大的情况,在很多情况下表示有富裕,即高位有很多0,可能造成无效的运算和判断,因此一般利用一个整型数据存储该数的位数。下面的程序是一个高精度整数的加法运算,请补充完整程序。

 1 


 1   #include <iostream>
 2   #include <cstring>
 3   using namespace std;
 4
 5   struct HugeInt{
 6       int len; 
 7 	 int num[100001]; 
 8   };
 9   HugeInt a, b, w;
10   char c[100001],d[100001];
11   void Scan_HugeInt(){
12        cin>>c; 
13        cin>>d; 
14        a.len=strlen(c);
15        b.len=strlen(d);
16        for(int i=0: i<a.len; i++)
17                 ①; 
18        for(int i=0; i<b.len; i++)
19                 ②;
20    }
21    void Plus(){
22         w.len=max(a.len,b.len);
23         for(int i=1; i<=w.len; i++) ( 
24                  w.num[i] +=③; 
25                  w.num[i+1] +=④; 
26                  w.num[i]%=10; 
27         }
28         if(⑤) 
29                  w.len ++; 
30   }
31
32 int main() {
33    Scan_HugeInt();
34    Plus(); 
35    for(int i=w.len; i>=1; i--) 
36             cout <<w.num[i]; 
37    cout <<endl; 
38    return 0; 
39 }

(1)①处应填()。
A.a.num[i]=c[i]-‘0’
B.a.num[a.len-i]=c[i]-‘0’
C.a.num[a.len门=c[i]
D.a.num[门=c[i]

(2)②处应填( )。
A.b.num[i]=d[i]
B.b.num[b.len-i]=d[i]
C.b.num[b.len-i]=d[i]-‘0’
D.b.num[i]=d[i]-‘0’

(3)③处应填( )。
A.(a.num[i]+b.num[i])
B.(a.num[i]+b.num[i])%10
C.(a.num[i]%10+b.num[i]%10)
D.(a.num[i]+b.num[i]-10)

(4)④处应填( )。
A.w.num[i]/10
B.w.num[i]
C.w.num[i]%10
D.w.num[i]-10

(5)⑤处应填( )。
A.w.num[w.len+1]>=0
B.w.num[w.len+1]==0
C.w.num[w.len+1]!=0
D.w.num[w.len +1]>1

关于高精度算法,我曾经在一篇文章里提到过:高精度运算(加减乘除和乘方)

不想看那篇文章的,可以看我下面的解释。如果已经会了,可以跳过,直接进入本题的第三部分:答案解释。

知识讲解
所谓高精度,就是大数的运算,这个大数可能是要远远超过现有数据类型的最大范围。如果我们想进行这样的运算,就要掌握计算的原理——竖式运算。`

我们这里先简单考虑非负数的加法,竖式这么列对吧:

①逆序存储
我们如何储存过长的数呢?可以用数组存储。怎么才能将各个数位上的数放到数组里面呢?这里,我们可以使用字符串。
我们使用逆序储存,这样会比较方便,后面可以在result数组中反向输出。

 
int a[241]=,b[241],result[242],l1=0,l2=0;
string c,d;
cin>>c>>d;
// 第一步读取整数
for(int i=c.size()-1;i>=0;i--){
    a[l1++]=c[i]-'0';
}
for(int i=d.size()-1;i>=0;i--){
    b[l2++]=d[i]-'0';
}
同时,这里l1表示第一个加数的长度,l2表示第二个加数的长度。

②模拟加法运算
接着,模拟运算:

    // 第二步加法计算
    int l=max(l1,l2)
    for(int i=0;i<l;i++){
        result[i]+=(a[i]+b[i])%10;
        result[i+1]+=(a[i]+b[i])/10;
    }
当我们进行加法运算时,每一位的结果是由两个部分组成的:当前位的数字和从低位“进”来的数字。例如,当我们计算23 + 18时,个位的结果是1,这个1就是从低位“进”来的,而2和3相加的结果是5,这个5就是当前位的数字。

在计算机中,当我们进行高精度计算时,通常会把每个数字拆分成多个位(如一个8位数字可以拆分成个位、十位、百位等),然后逐位进行加法运算。为了得到每个位的正确结果,我们需要考虑从低位“进”来的数字。

例如,如果我们有两个8位数字1234和5678,我们不能直接把它们相加,因为结果会超过8位。正确的做法是逐位进行加法运算:

1 + 6 = 7,没有进位,所以结果的个位就是7
2 + 7 = 9,进位1,所以结果的十位就是9 + 1 = 09
3 + 8 = 11,进位1,所以百位的结果是11 + 1 = 01
4 + 5 = 9,进位1,所以千位的结果是09 + 1 = 009

这样,我们就可以得到最终的结果:0097。

在上面的程序中,“进位”的思想体现在每次加法运算时都考虑了前一位的进位。通过这种方式,我们可以得到正确的高精度结果。

③反向输出:
for(int i=(x>y?x:y);i>=0;i--){
    cout<<result[i];
}
完整代码:
#include <iostream>
using namespace std;
int main(){
    // 高精度加法 240位内,调整数组大小可以扩大位数 
    int a[241]={},b[241]={},result[242]={},l1=0,l2=0;
    string c,d;
    cin>>c>>d;
    // 第一步读取整数
    for(int i=c.size()-1;i>=0;i--){
        a[l1++]=c[i]-'0';
    }
    for(int i=d.size()-1;i>=0;i--){
        b[l2++]=d[i]-'0';
    }
    int l=max(l1,l2); 
    // 第二步加法计算
    for(int i=0;i<l;i++){
        result[i]+=(a[i]+b[i])%10;
        result[i+1]+=(a[i]+b[i])/10;
    }
    for(int i=l;i>=0;i--){
        cout<<result[i];
    }
    return 0;
}

 答案讲解
这样,我们就可以做题了。

因为是逆序输入的,因此(1(2两题分别选B,C.

对于(3,常理来说,第三道题应该选B。但可以注意到,在这条语句进行之后,会进行mod 10 操作,因此这不就不需要mod 10了。所以,这里就只能选A或C了。但C冗余,因此选A。

根据公式,(4选A。

而(5,观察可知,下面的内容是 在 和的位数超过较大加数的位数的 情况下所执行的。所以这里的判断条件应该是,和的下一位数大于零。所以选C。

综上所述,此题答案应为 BCAAC

上面是一个实例,由上可知,阅读代码的实际操作一般分为:理解知识点、查看题目等步骤。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lyh不会打代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值