读别人写的代码 VS 自己写代码

2023-10-27

概述:专业程序员非常重要的一项技能是读别人写的代码,这项技能甚至比自己写代码更重要。

分析:

  这让我想到很多程序员讨厌去阅读代码,来接受它吧。人人都喜欢编写代码--写代码是很有乐趣的事。但阅读代码却是一种困难的工作。它不仅仅繁重,而且很无聊,让我们面对这个事实,任何不是自己写的代码都是差劲的(嘿嘿,虽然我们没有这样说过,但是其实我们都是这样想 的)。甚至当你写完代码后的仅仅几个小时之后,你的那些代码就开始变得越来越烂了,时间一长,你就会把它当作看起来的那种差劲作品。

  所以,你又何必要去花费时间来审视别人蹩脚的代码呢,这段时间你完全可以用来 自己去写一些非常优秀的代码,为什么不这样尝试一下,把自己写好的代码放上几个小时再回头看看,它是否依旧非常优秀呢?如果你不站在前辈们的肩膀上,你将没有可能成一个为技艺精湛的大师。其中一种途径就是亲自找到一个大师,让他把他所有的知识全部传授给你--当然这是有可能的,虽然可能性不高,你必须非常走运才能获到这种机会。然而你可以不用想着去碰运气, 我们很幸运的处在这样的一个职业里--大师们的经验和知识都在那里等着我们去吸收,这些都蕴涵在他们所写 的代码里。你所要做的事就是去阅读它,当然它可能会比找一个人坐在你旁边向你解释这些多占用一点时间,但是这是实现起来可能性较高,透视全局地思考下,若想成为优秀的木匠,你就必需观察大量的拥有优良结构的家具。

  ……

  【未完】更精彩的内容进作者的空间去看吧 >>> [译文]为何我喜爱读他人的代码,而你也应该去喜爱它

以下为两位笔者分享的一些经验,借来展示一下:

标题:说说我对阅读源代码的一些技巧方法,其实这并不难。
作者:afadgaeg
原文:http://afadgaeg.javaeye.com/blog/264490
正文:

  阅读源代码的利弊我不谈,我只说该如何读.

  首先是积累,当到了一定条件,你会迫不及待的想要去读,因为你想拥有程序的控制权 .

  我把一份陌生的源代码比做一个陌生的城市,你将在里面熟悉道路,你只要从一个大的标志开始进入(程序入口点)然后你面临很多分支,有的分支很明显的(依靠设计模式,oo,模块化,结构化,解耦,经验判断,当然还有文档,注释,别人的源码分析文章)与其它没有什么瓜葛,或者只有几个联系点,其实是一个模块化功能,就像你知道有一条路通向xx村,你先不管它,知道它通哪里就可以了,以后再专程访问xx村。

  一个设计优良的程序肯定是一个个通过乡村高速公路连接的村落,而不该是交杂在一起的钢筋水泥,至不济也该是用围墙围起来的一个个小区。

  当你知道并熟悉了城市的主干道之后,整个城市其实已经成竹在胸了

  你该学好模式,oo,模块化,结构化,解耦,接口,多态。。。。
广义来说就是oo

  写给初学的人,以让他们少走不成器的我走过的弯路。

  补充一条找源码分析文章的技巧>>> <b>在google中输入关键的源码片段</b>

  补充一点经验:

  当你读过一些模块之后,看到类似的模块就会下意识的去猜测该模块内部的代码结构,如果你读的够多,实践够丰富,模块就了然于胸了。

  比如看到一个方法名,根据方法的字面意思就能猜测出该方法的代码结构,看到类名,就可能会猜测出它该要有什么方法。 这时读代码的速度就快了。

  代码是一个有机体,当你具有把一份源代码解构成一个有机体的能力的时候,读代码其实并不痛苦。可是我还没有达到我想像的哪个层次。

标题:如何读代码?
作者:卢声远<michaellufhl@yahoo.com.cn>
原文:http://blog.csdn.net/michaellufhl/archive/2010/10/09/5930570.aspx
正文:

  有時候在察看开源項目的時候,如果你想參與其中,那項目的负責人基本上都是建议从bugfix開始了解程序,了解代码。所以第一个建议就是从bugfix和添加新功能入手 。事實上在公司參加一個新項目的开发或者维护也大多是從bugfix入手。這樣入手的好處在於可以集中精力去了解以小块代码的運作機制。显然這很符合人的思維規律-做简单的事情总比做复杂的事情來得容易和高效。当然這不是盲人摸象,要bugfix的話至少自己要知道整個軟件的功能和層次,这需要閲读文檔而不是代码。

  说到注释,这个时候就太有用了。不用说是别人写的代码,就是自己几个月前写的代码自己也需要仔细看一下才能搞懂。但是残酷的现实就是注释很少,更残酷的现实是越是低质量的代码,它的注释越是少。怎么办?只能猜 了。如果我们碰到一个很长的方法,但是我们需要跳过去看调它的代码,我们就需要猜测这个方法的功能了。然后再回过头来仔细看那个方法。我们可以运气好的话作者会取很合理的class名,method名和变量名。其实里面有个矛盾:很复杂,内聚很松散的method或者class,它们的名字就根本不可能取得合理。这个道理很简单,一个method里面做了很多事情,你就很难给它取一个合适的名字。像removeUserAndItsClientsAndUpdateTime(), 或者干脆来个缩写removeUCUpdateT()。 这样的名字基本没有可读性。

  还有就是读上层 和读下层 。读上层就是在代码的 高层阅读,碰到底层的API可以猜出它的作用。这样把一块高层的代码像读逻辑那样粗线条梳理清楚,其实就是一大块一大块地读代码。读下层就是把底层的代码if else一一读懂。这两者缺一不可。

  碰到很乱的代码几乎只能利用IDE debug, step by step 得一行一行执行。因为乱,所以没有仔细看整体结构的必要,而最有效的就是step by step了。当然有些时候程序逻辑必须依赖数据库或者外部数据,这样的话光看代码也不行。也只能step by step或者运行时log。

  在OO的时代design pattern也已经深入人心。在看高质量代码的时候会发现他们的代码有个特点就是相当抽象,或者说面向抽象。里面有很多interface, abstract class, 还有anonymous class, 很长的继承链。我认为既然作者写程序的时候面向抽象,那么我们读程序的时候也要面向抽象 。我们经常在读代码察看某个变量的时后用IDE的查看功能点进去,然后发现它是一个接口全无实现。很多时候我们的第一反应就是找到具体的实现类,我倒是认为可以关注这个接口先往下读代码,然后回过头来看实现。既然作者的意图就是让接口来工作,我们就可以先了解作者的意图来看代码。顺便说来,要读懂很抽象的代码,读者自己首先要有很好的OO概念和design pattern的知识。

  精彩文章推荐:今年程序员们解决问题的顺序

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

读别人写的代码 VS 自己写代码 的相关文章

  • 在搜索 List 时,为什么 Enumerable.Any(Func predicate) 比带有 if 语句的 foreach 慢

    最近有件事引起了我的好奇心 Why is the Enumerable Any Func
  • 使用具有现有访问令牌的 Google API .NET 客户端

    用例如下 移动应用程序正在通过 Google 对用户进行身份验证 并且在某些时候 我们需要将用户的视频发布到他的 YouTube 帐户 出于实际原因 实际发布应该由后端完成 已经存储在那里的大文件 由于用户已经通过应用程序的身份验证 因此应
  • C# 中的接口继承

    我试图解决我在编写应用程序时遇到的相当大的 对我来说 问题 请看这个 为了简单起见 我将尝试缩短代码 我有一个名为的根接口IRepository
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 如何从 C# 控制器重定向到外部 url

    我使用 C 控制器作为网络服务 在其中我想将用户重定向到外部网址 我该怎么做 Tried System Web HttpContext Current Response Redirect 但没有成功 使用控制器的重定向 http msdn
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 为什么我不应该对不是由 malloc() 分配的变量调用 free() ?

    我在某处读到 使用它是灾难性的free删除不是通过调用创建的对象malloc 这是真的 为什么 这是未定义的行为 永远不要尝试它 让我们看看当您尝试时会发生什么free 自动变量 堆管理器必须推断出如何获取内存块的所有权 为此 它要么必须使
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • 当我“绘制”线条时,如何将点平均分配到 LineRenderer 的宽度曲线?

    我正在使用线条渲染器创建一个 绘图 应用程序 现在我尝试使用线条渲染器上的宽度曲线启用笔压 问题在于 AnimationCurve 的 时间 值 水平轴 从 0 标准化为 1 因此我不能在每次添加位置时都在其末尾添加一个值 除非有一个我不知
  • 如何挤出平面 2D 网格并赋予其深度

    我有一组共面 连接的三角形 即二维网格 现在我需要将其在 z 轴上挤出几个单位 网格由一组顶点定义 渲染器通过与三角形数组匹配来理解这些顶点 网格示例 顶点 0 0 0 10 0 0 10 10 0 0 10 0 所以这里我们有一个二维正方
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • 为什么拆箱枚举会产生奇怪的结果?

    考虑以下 Object box 5 int int int box int 5 int nullableInt box as int nullableInt 5 StringComparison enum StringComparison
  • 剪贴板在 .NET 3.5 和 4 中的行为有所不同,但为什么呢?

    我们最近将一个非常大的项目从 NET Framework 3 5 升级到 4 最初一切似乎都工作正常 但现在复制粘贴操作开始出现错误 我已经成功制作了一个小型的可复制应用程序 它显示了 NET 3 5 和 4 中的不同行为 我还找到了一种解
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在

随机推荐

  • 【SSO单点登录】JWT续签问题 && OAuth2.0 中的refreshToken刷新机制

    本篇速览 JWT续签问题 快过期时返回新的token refreshToken 如何判断refreshToken的有效性 扩展 OAuth2 0 中的refreshToken刷新机制 其他需要刷新token的情况 用户修改了角色权限 删除了
  • SQL优化之 not in

    not in select from dic region old a where a region code not in select b region code from dic region b PL SQL 执行 选择17 行 耗
  • 通过liquibase将PostgreSQL数据库导入到H2数据库

    1 背景 项目中使用的数据库是PostgreSQL 在做测试时 想使用H2代替 2 问题 2 1 保留字 在PostgreSQL中使用了几个H2的保留字 例如 end offset foreign 这些保留字是不能作为表的字段名 2 2 字
  • Java加解密的基础

    在Java的安全包中 包括了三部分内容 1 JCA JCE Java Cryptography Architecture JavaCryptography Extensions 2 JSSE Java Secure Sockets Exte
  • Jenkins + NACOS + GATEWAY 实现微服务不停机部署

    Nacos 版本
  • 【第11篇】MobileNetV2:倒置残差和线性瓶颈

    MobileNetV2 倒置残差和线性瓶颈 文章目录 MobileNetV2 倒置残差和线性瓶颈 摘要 1 简介 2 相关工作 3 预备 讨论和直觉 3 1 深度可分离卷积 3 2 线性瓶颈 3 3 倒置残差 3 4 信息流解读 4 模型架
  • LCD和FSMC的那点事 和STM32F4 FSMC 34PIN 16位数据并口 TFTLCD,点亮屏幕步骤

    LCD和FSMC的那点事 A 先说一下几种LCD interface 包括但不限于以下三种 1 SPI 2 FSMC 就是常说的8080 或者称80并口 都是一个意思 参考 STM32 FSMC模拟8080时序 点亮 液晶屏 点亮显示屏的几
  • 复习向 C/C++ 编程语言简介和概括(C++复习向p1)

    文章目录 C 编程语言 C 和 C 关系 标准的 C 组成 ANSI 标准 比较重要的标准化时间 C 编程语言 是一种静态类型的 编译式的 通用式的 大小写敏感 不规则的编程语言 支持过程化编程 面向对象 泛型编程 C 和 C 关系 C 是
  • mybatis-plus Invalid bound statement (not found):

    1 若是使用了多数据源配置 请检查 DataSourceConfig配置类 将SqlSessionFactoryBean改为mybatis plus里面的MybatisSqlSessionFactoryBean Bean name test
  • 一键磨皮插件:DR5白金版(支持ps 2022)中文版

    Delicious Retouch 5简称DR5 这里为大家分享最新激活的DR5白金版 for mac 这是非常受欢迎的一款PS一键磨皮插件 dr5插件提供了人像磨皮 平滑皮肤 去除瑕疵 美白牙齿 美白皮肤 修饰眼部等功能 一键点击即可使用
  • win10+CPU+Anaconda3 环境下pytorch安装

    本文主要对win10环境下 仅CPU运行 Anaconda3中安装pytorch的步骤进行了记录 主要包括以下内容 1 conda 创建虚拟环境 2 conda 添加镜像源 3 pytorch 安装 4 pytorch 成功安装验证 con
  • Unity官网打不开,试试新地址吧!

    今年6月份发现unity官网进不去了 unity3d com unity com cn 下载历史版本的地址也打不开 网上也有很多人求助 新域名如下 不需要挂vpn 新地址 https unity cn 历史版本下载 https unity
  • Python多线程的理解和使用(一)Threading中join()函数的理解

    转载自 https blog csdn net zhuzuwei article details 80927554 多线程的概念 多线程类似于同时执行多个不同程序 多线程运行有如下优点 使用线程可以把占据长时间的程序中的任务放到后台去处理
  • python操作redis

    目录 python操作redis 安装redis模块 基本链接 连接池连接 redis字符串操作 redis hash操作 redis 列表操作 redis 其它操作 redis管道 django中集成redis python操作redis
  • 为本地项目配置git地址,并推送到远程仓库

    1 进入该项目文件夹 cd Users kk Desktop project k demo 将上面项目路径换成你自己的项目路径 2 初始化git 使用git init 将该项目变成一个可以通过git管理的项目 git init 3 通过gi
  • vue-cli使用指南

    目录 vue全家桶 技术栈 使用vue cli搭建Vue项目 单页的编写 axios的使用 vuex的使用 vuex中数据的保留时间 axios的全局拦截 axios的跨域问题 全局常量 使用Mock模拟后端接口返回数据 嵌套路由 路由守卫
  • 95-38-030-Buffer-Java NIO中-关于DirectBuffer,HeapBuffer的疑问

    文章目录 1 说明 2 疑问 3 RednaxelaFX 1 说明 本文摘要 https www zhihu com question 57374068 2 疑问 Java NIO中 关于DirectBuffer HeapBuffer的疑问
  • CUDA的几种Synchronize

    首先对这三个函数做一下解释 cudaDeviceSynchronize 等待所有线程都处理完成 kernel function处理完成 用在cpu的c code中 cudaThreadSynchronize 功能和cudaDeviceSyn
  • Pycharm的使用技巧与效率提升

    总第010篇 本文主要梳理了pycharm在使用过程中的一些技巧 便于提升工作效率 pycharm主要分为两个版本 一个是专业版本 此版本功能强大 主要是为python和web开发者准备的 需要付费 另一个是社区版本 比较轻量级 主要是为p
  • 读别人写的代码 VS 自己写代码

    概述 专业程序员非常重要的一项技能是读别人写的代码 这项技能甚至比自己写代码更重要 分析 这让我想到很多程序员讨厌去阅读代码 来接受它吧 人人都喜欢编写代码 写代码是很有乐趣的事 但阅读代码却是一种困难的工作 它不仅仅繁重 而且很无聊 让我