拉勾课堂--代码优化法则

开源ISP实战(1)——基于Zynq7020的Vivado工程移植与调试 本文详细介绍了将开源ISP项目移植到正点原子Zynq7020开发板的实战过程。重点阐述了在Vivado中进行工程创建、IP核导入、Block Design框架搭建、时钟配置与管脚约束修改等关键步骤,并提供了系统联调与常见问题的排查思路,为FPGA图像处理开发者提供了完整的移植与调试指南。 阅读详情

代码优化法则

1.使用局部变量可避免在堆上分配

由于堆资源是多线程共享的,是垃圾回收器工作的主要区域,过多的对象会造成 GC 压力。可以通过局部变量的方式,将变量在栈上分配。这种方式变量会随着方法执行的完毕而销毁,能够减轻 GC 的压力。

2.减少变量的作用范围

注意变量的作用范围,尽量减少对象的创建。如下面的代码,变量 a 每次进入方法都会创建,可以将它移动到 if 语句内部。

public void test1(String str) {
    final int a = 100;
    if (!StringUtils.isEmpty(str)) {
        int b = a * a;
    }
}

3.访问静态变量直接使用类名

有的同学习惯使用对象访问静态变量,这种方式多了一步寻址操作,需要先找到变量对应的类,再找到类对应的变量,如下面的代码:

public class StaticCall {
    public static final int A = 1;
​
    void test() {
        System.out.println(this.A);
        System.out.println(StaticCall.A);
    }
}

对应的字节码为:

void test();
    descriptor: ()V
    flags:
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: aload_0
         4: pop
         5: iconst_1
         6: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
         9: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        12: iconst_1
        13: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        16: return
      LineNumberTable:
        line 5: 0
        line 6: 9
        line 7: 16

可以看到使用 this 的方式多了一个步骤。

4.字符串拼接使用 StringBuilder

字符串拼接,使用 StringBuilder 或者 StringBuffer,不要使用 + 号。比如下面这段代码,在循环中拼接了字符串。

public String test() {
    String str = "-1";
    for (int i = 0; i < 10; i++) {
        str += i;
    }
    return str;
}

从下面对应的字节码内容可以看出,它在每个循环里都创建了一个 StringBuilder 对象。所以,我们在平常的编码中,显式地创建一次即可。

 5: iload_2
 6: bipush        10
 8: if_icmpge     36
11: new           #3                  // class java/lang/StringBuilder
14: dup
15: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
18: aload_1
19: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: iload_2
23: invokevirtual #6                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
26: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: astore_1
30: iinc          2, 1
33: goto          5

5.重写对象的 HashCode,不要简单地返回固定值

在代码 review 的时候,我发现有开发重写 HashCode 和 Equals 方法时,会把 HashCode 的值返回固定的 0,而这样做是不恰当的。

当这些对象存入 HashMap 时,性能就会非常低,因为 HashMap 是通过 HashCode 定位到 Hash 槽,有冲突的时候,才会使用链表或者红黑树组织节点。固定地返回 0,相当于把 Hash 寻址功能给废除了。

6.HashMap 等集合初始化的时候,指定初始值大小

这个原则参见 “10 | 案例分析:大对象复用的目标和注意点”,这样的对象有很多,比如 ArrayList,StringBuilder 等,通过指定初始值大小可减少扩容造成的性能损耗。

7.遍历 Map 的时候,使用 EntrySet 方法

使用 EntrySet 方法,可以直接返回 set 对象,直接拿来用即可;而使用 KeySet 方法,获得的是key 的集合,需要再进行一次 get 操作,多了一个操作步骤。所以更推荐使用 EntrySet 方式遍历 Map。

8.不要在多线程下使用同一个 Random

Random 类的 seed 会在并发访问的情况下发生竞争,造成性能降低,建议在多线程环境下使用 ThreadLocalRandom 类。

在 Linux 上,通过加入 JVM 配置 -Djava.security.egd=file:/dev/./urandom,使用 urandom 随机生成器,在进行随机数获取时,速度会更快。

9.自增推荐使用 LongAddr

自增运算可以通过 synchronized 和 volatile 的组合,或者也可以使用原子类(比如 AtomicLong)。

后者的速度比前者要高一些,AtomicLong 使用 CAS 进行比较替换,在线程多的情况下会造成过多无效自旋,所以可以使用 LongAdder 替换 AtomicLong 进行进一步的性能提升。

10.不要使用异常控制程序流程

异常,是用来了解并解决程序中遇到的各种不正常的情况,它的实现方式比较昂贵,比平常的条件判断语句效率要低很多。

这是因为异常在字节码层面,需要生成一个如下所示的异常表(Exception table),多了很多判断步骤。

Exception table:
    from    to  target type
    7    17    20   any
    20    23    20   any

11.不要在循环中使用 try catch

道理与上面类似,很多文章介绍,不要把异常处理放在循环里,而应该把它放在最外层,但实际测试情况表明这两种方式性能相差并不大。

既然性能没什么差别,那么就推荐根据业务的需求进行编码。比如,循环遇到异常时,不允许中断,也就是允许在发生异常的时候能够继续运行下去,那么异常就只能在 for 循环里进行处理。

12.不要捕捉 RuntimeException

Java 异常分为两种,一种是可以通过预检查机制避免的 RuntimeException;另外一种就是普通异常。

其中,RuntimeException 不应该通过 catch 语句去捕捉,而应该使用编码手段进行规避。

如下面的代码,list 可能会出现数组越界异常。是否越界是可以通过代码提前判断的,而不是等到发生异常时去捕捉。提前判断这种方式,代码会更优雅,效率也更高。

//BAD
public String test1(List<String> list, int index) {
    try {
        return list.get(index);
    } catch (IndexOutOfBoundsException ex) {
        return null;
    }
}
​
//GOOD
public String test2(List<String> list, int index) {
    if (index >= list.size() || index < 0) {
        return null;
    }
    return list.get(index);
}

13.合理使用 PreparedStatement

PreparedStatement 使用预编译对 SQL 的执行进行提速,大多数数据库都会努力对这些能够复用的查询语句进行预编译优化,并能够将这些编译结果缓存起来。

这样等到下次用到的时候,就可以很快进行执行,也就少了一步对 SQL 的解析动作。

PreparedStatement 还能提高程序的安全性,能够有效防止 SQL 注入。

但如果你的程序每次 SQL 都会变化,不得不手工拼接一些数据,那么 PreparedStatement 就失去了它的作用,反而使用普通的 Statement 速度会更快一些。

14.日志打印的注意事项

我们在“06 | 案例分析:缓冲区如何让代码加速”中了解了 logback 的异步日志,日志打印还有一些其他要注意的事情。

我们平常会使用 debug 输出一些调试信息,然后在线上关掉它。如下代码:

logger.debug("xjjdog:"+ topic + "  is  awesome"  );

程序每次运行到这里,都会构造一个字符串,不管你是否把日志级别调试到 INFO 还是 WARN,这样效率就会很低。
可以在每次打印之前都使用 isDebugEnabled 方法判断一下日志级别,代码如下:

if(logger.isDebugEnabled()) { 
    logger.debug("xjjdog:"+ topic + "  is  awesome"  );
}

使用占位符的方式,也可以达到相同的效果,就不用手动添加 isDebugEnabled 方法了,代码也优雅得多。

logger.debug("xjjdog:{}  is  awesome"  ,topic);

对于业务系统来说,日志对系统的性能影响非常大,不需要的日志,尽量不要打印,避免占用 I/O 资源。

15.减少事务的作用范围

如果的程序使用了事务,那一定要注意事务的作用范围,尽量以最快的速度完成事务操作。这是因为,事务的隔离性是使用锁实现的,可以类比使用 “13 | 案例分析:多线程锁的优化” 中的多线程锁进行优化。

@Transactional 
public void test(String id){
    String value = rpc.getValue(id); //高耗时
    testDao.update(sql,value);
}

如上面的代码,由于 rpc 服务耗时高且不稳定,就应该把它移出到事务之外,改造如下:

public void test(String id){
    String value = rpc.getValue(id); //高耗时
    testDao(value);
}
@Transactional 
public void testDao(String value){
    testDao.update(value);
}

这里有一点需要注意的地方,由于 SpringAOP 的原因,@Transactional 注解只能用到 public 方法上,如果用到 private 方法上,将会被忽略,这也是面试经常问的考点之一。

16.使用位移操作替代乘除法

计算机是使用二进制表示的,位移操作会极大地提高性能。

<< 左移相当于乘以 2;

>> 右移相当于除以 2;

>>> 无符号右移相当于除以 2,但它会忽略符号位,空位都以 0 补齐。
int a = 2;
int b = (a++) << (++a) + (++a);
System.out.println(b);

注意:位移操作的优先级非常低,所以上面的代码,输出是 1024。

17.不要打印大集合或者使用大集合的 toString 方法

有的开发喜欢将集合作为字符串输出到日志文件中,这个习惯是非常不好的。
拿 ArrayList 来说,它需要遍历所有的元素来迭代生成字符串。在集合中元素非常多的情况下,这不仅会占用大量的内存空间,执行效率也非常慢。我曾经就遇到过这种批量打印方式造成系统性能直线下降的实际案例。
下面这段代码,就是 ArrayList 的 toString 方法。它需要生成一个迭代器,然后把所有的元素内容拼接成一个字符串,非常浪费空间。

public String toString() {
    Iterator<E> it = iterator();
    if (! it.hasNext())
        return "[]";
​
    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = it.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! it.hasNext())
            return sb.append(']').toString();
        sb.append(',').append(' ');
    }
}

18.程序中少用反射

反射的功能很强大,但它是通过解析字节码实现的,性能就不是很理想。

现实中有很多对反射的优化方法,比如把反射执行的过程(比如 Method)缓存起来,使用复用来加快反射速度。

Java 7.0 之后,加入了新的包 java.lang.invoke,同时加入了新的 JVM 字节码指令 invokedynamic,用来支持从 JVM 层面,直接通过字符串对目标方法进行调用。

如果你对性能有非常苛刻的要求,则使用 invoke 包下的 MethodHandle 对代码进行着重优化,但它的编程不如反射方便,在平常的编码中,反射依然是首选。

下面是一个使用 MethodHandle 编写的代码实现类。它可以完成一些动态语言的特性,通过方法名称和传入的对象主体,进行不同的调用,而 Bike 和 Man 类,可以是没有任何关系的。

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
​
public class MethodHandleDemo {
    static class Bike {
        String sound() {
            return "ding ding";
        }
    }
​
    static class Animal {
        String sound() {
            return "wow wow";
        }
    }
​
​
    static class Man extends Animal {
        @Override
        String sound() {
            return "hou hou";
        }
    }
​
​
    String sound(Object o) throws Throwable {
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodType methodType = MethodType.methodType(String.class);
        MethodHandle methodHandle = lookup.findVirtual(o.getClass(), "sound", methodType);
​
        String obj = (String) methodHandle.invoke(o);
        return obj;
    }
​
    public static void main(String[] args) throws Throwable {
        String str = new MethodHandleDemo().sound(new Bike());
        System.out.println(str);
        str = new MethodHandleDemo().sound(new Animal());
        System.out.println(str);
        str = new MethodHandleDemo().sound(new Man());
        System.out.println(str);
    }
}

19.正则表达式可以预先编译,加快速度

Java 的正则表达式需要先编译再使用。

典型代码如下:

Pattern pattern = Pattern.compile({pattern});
Matcher pattern = pattern.matcher({content});

Pattern 编译非常耗时,它的 Matcher 方法是线程安全的,每次调用方法这个方法都会生成一个新的 Matcher 对象。所以,一般 Pattern 初始化一次即可,可以作为类的静态成员变量。

参考自:拉勾教育

win11 使用 QEMU 配置龙芯 3A5000 虚拟环境 阅读详情

相关推荐

VScode利用EIDE和cortex-debug进行stm32开发(也适用51)

你是否因为keil页面太丑而烦恼,你是否因为keil编译太慢而恼怒,ok阿,今天也是给大家带来怎么在vscode上进行stm32的编程(我不会告诉你,我搞了好几天才搞好的💔💔💔)为什么是简单介绍?因为太啰嗦了,我嫌麻烦😋,大家可以去EIDE的官方文档去看。

weixin_73952614的博客 9382

百度某新员工吐槽:前人代码写得像一坨屎,颠覆了对大厂的认知

黑客技术点击右侧关注,了解黑客的世界!Linux编程点击右侧关注,免费入门到精通!程序员严选甄选正品好物,程序员生活指南!代码,最是神秘莫测。自己写的代码,总感觉就是世界...

iOS_开发 776

matebookego win11 arm 系统安装安卓子系统

一般的x86电脑如果安装android子系统,运行安卓子系统,由于要将android arm代码转译为x86代码,所以效率不一定高,但是如果电脑是arm架构的,通过安卓子系统运行android的程序执行效率就会 高不少,本文参考,都是在win11 home版本下的。两者跑分在cpu上差不太多了,大约是枭龙855的水平了,这个水平的子系统就有一定的实用性了,玩个一般游戏,刷个抖音都很流畅的。启动子系统后,点击左上角的设置,启用 “开发人员模式”。然后就可以再通运运行华为应用商店来进行安装其它应用了。

babytiger的专栏 1万+

这代码写的跟狗屎一样!怎么优化?

点击上方“朱小厮的博客”,选择“设为星标”回复”1024“获取独家整理的学习资料1.导读随着软件项目代码的日积月累,系统维护成本变得越来越高,是所有软件团队面临的共同问题...

朱小厮的博客 751

Honeywell EPKS 核心功能块组态与执行调度实战解析

本文深入解析Honeywell EPKS系统的核心功能块组态与执行调度技术,涵盖控制模块(CM)、顺序控制模块(SCM)和输入输出模块(IOM)的配置方法。通过实战案例分享执行顺序(ORDERINCM)和CEE执行周期的优化策略,帮助工程师提升工业自动化系统的控制精度和运行效率。

weixin_28724319的博客 414

从零配置EtherCAT IGH主站:手把手教你处理内核版本与实时性优化的那些坑

本文详细指导如何从零配置EtherCAT IGH主站,涵盖内核版本适配、实时性优化及常见问题解决方案。通过精确匹配内核头文件、应用实时补丁和优化网卡驱动,帮助开发者实现微秒级响应,适用于工业自动化、机器人控制等高精度场景。

weixin_30790841的博客 382

guava缓存使用不当导致的FullGC

java使用guava cache不当,导致的fullgc研究

码农无双的博客 4236

SAP开发顾问简历模板范文(精选篇)

SAP开发顾问简历该怎么写呢?

Huanzhucv的博客 1568

[缓存-Caffeine] 使用 弱引用key weakKeys 导致 无法命中值 问题

使用Caffeine作为本地缓存: public void initRoleCaches() { CacheConfig cacheConfig = cacheConfig(); roleCaches = Caffeine.newBuilder() // 数量上限 .maximumSize(cacheConfig. getRoleMaxSize())...

zj380475045的博客 1951

深入解析五大ADC芯片架构及其应用场景

本文深入解析了五大ADC芯片架构及其应用场景,包括逐次逼近型ADC、Σ-Δ型ADC、流水线型ADC、闪存型ADC和积分型ADC。通过详细的架构分析和实际应用案例,帮助工程师理解不同ADC芯片的特点和适用场景,提升电路设计效率。

weixin_28702105的博客 354

基于Linux的PCIe设备驱动开发入门到精通-- 11.2 锁机制与并发控制 (自旋锁、互斥锁) 11.3 性能瓶颈分析与优化建议

本文探讨Linux驱动开发中的性能优化方法论,重点聚焦并发控制与性能瓶颈分析。从锁机制选择(自旋锁、互斥锁等)到工具使用(ftrace、perf),详细介绍了定位锁竞争和CPU热点的实战步骤,包括ftrace事件跟踪和perf火焰图分析。针对常见性能瓶颈(CPU/内存/I/O/锁竞争),提出了锁粒度优化、无锁结构替换、中断处理优化等解决方案。强调性能优化需要理论结合实践,通过"假设-测量-验证"的循环持续迭代。为开发者提供了一套从问题定位到解决的完整方法论,助力开发高性能工业级驱动。

MHD0815的博客 126

删除java速度变慢_Java正则表达式运行速度很慢

我试图在Java中使用Daring Fireball Regular Expression for matching URLs,并且我发现一个URL,导致评估永远.我修改了原来的正则表达式以使用Java语法.private final static String pattern ="\\b" +"(" + // Capture 1: entir...

weixin_30716641的博客 245

【YOLOv11】087、YOLOv11多任务学习:检测、分割、分类联合学习

摘要: 工业质检场景中,多任务模型(检测、分类、分割)的需求日益增长。针对边缘设备部署的挑战,本文提出基于YOLOv11的多任务学习方案。通过共享主干网络和设计分支头(检测、分割、分类),实现高效推理;采用动态权重平衡策略解决多任务损失不平衡问题;并优化数据流处理(支持部分标注)和推理剪裁(按需启用分支)。实验表明,该方法在Jetson Orin上帧率提升3倍,内存占用减少40%,为工业质检提供了轻量高效的解决方案。

企鹅码农的专属播客,分享10多年的实战案例和经验解读,包含YOLO、RT-DETR、AI等各个工作领域。 445

我的代码和注释都写的像坨屎,那又怎么样?

题图: 摄于2019年 - 绍兴东湖一周前,我的朋友圈被一篇 #百度某新员工发飙:前人代码写得像一坨屎,颠覆了对大厂的认知# 的文章刷屏了,评论区也非常热闹。但让我惊讶的是,几乎所有的声音里都充满着嘲笑与讥讽,有的剑指百度的价值...

cuihuang0047的博客 410

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java 性能优化之—— 常见 Java 代码优化法则

代码优化法则 1.使用局部变量可避免在堆上分配 由于堆资源是多线程共享的,是垃圾回收器工作的主要区域,过多的对象会造成 GC 压力。可以通过局部变量的方式,将变量在栈上分配。这种方式变量会随着方法执行的完毕而销毁,能够减轻 GC 的压力 2.减少变量的作用范围 注意变量的作用范围,尽量减少对象的创建。如下面的代码,变量 a 每次进入方法都会创建,可以将它移动到 if 语句内部 public void test1(String str) { final int a = 100; i...

vincent_wen0766的博客 876

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

java正则表达式Pattern和Matcher

java正则表达式Pattern和Matcher

weixin_37799575的博客 570

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java 性能优化实战案例分析:常见 Java 代码优化法则

回顾一下 06 课时到 15 课时,我们分别了解缓冲、缓存、池化对象、大对象复用、并行计算、锁优化、NIO 等优化方法,它们对性能的提升往往是质的飞跃。但语言本身对性能也是有影响的,比如就有很多公司就因为语言的特性由 Java 切换到 Golang。对于 Java 语言来说,也有它的一套优化法则,这些细微的性能差异,经过多次调用和迭代,会产生越来越大的影响。本课时将集中讲解一些常用的代码优化法则,从而在编码中保持好的习惯,让代码保持最优状态。

fegus的博客 1511

Java 本地缓存选它就对了:Caffeine 永远的王者!

Guava Cache,他的优点是封装了get,put操作;提供线程安全的缓存操作;提供过期策略;提供回收策略;缓存监控。当缓存的数据超过最大值时,使用LRU算法替换。这一篇我们将要谈到一个新的本地缓存框架:Caffeine Cache。它也是站在巨人的肩膀上-Guava Cache,借着他的思想优化了算法发展而来。本文主要介绍Caffine Cache 的使用方式,以及Caffine Cache...

Java知音 849

java中的pattern.compile

在Java中,正则表达式编译是一个比较耗时的操作,所以如果我们需要多次使用同一个正则表达式进行匹配操作时,建议我们先使用Pattern.compile 进行编译,再使用 Matcher 进行匹配操作,这样可以提高程序的效率和性能。Pattern对象可以用于匹配字符串。compile方法有两个参数,第一个参数是一个正则表达式字符串,第二个参数是一个表示正则表达式行为的位标志(flag),通常情况下我们不需要设置第二个参数,使用默认值即可,如果你有特殊需求,可以使用相应的位标志设置来使用compile方法。

qq_32752773的博客 3418

祖传代码为何是屎山

可能使用单个字母作为变量名,如“i”“j”“k”等,这在短代码片段中或许还能勉强理解,但在大型复杂的程序中,根本无法清晰地传达变量的实际含义。当需要添加新的功能时,可能需要在现有的代码中进行大量的修改,而不是通过添加新的模块来实现。祖传代码可能在新的软件环境下出现兼容性问题,例如无法在新的操作系统上正常运行,或者与新的数据库版本不兼容。没有测试用例的支持,你很难确定修改后的代码是否会引入新的错误。全局变量的使用会增加代码的复杂性和不确定性,因为任何地方都可以修改全局变量的值,这使得代码的行为难以预测。

chinansa的博客 1876

编写代码像屎,用英雄联盟例子学习设计模式原则

java设计原则,有很多小伙伴都不知道这个学了可以干什么,我现在来详细解释一下:比如说在学习或者工作中明明已经用代码实现了功能但是还是会给批评”你这代码写的和一坨屎一样“。为什么呢?因为你的代码太耦合了。可是什么是耦合呢?

nido的博客 3026

你以为大厂的代码就不烂了?烂成一坨屎...

点击“开发者技术前线”,选择“星标????”在看|星标|留言, 真爱来自:开发者技术前线作者:可可最近有一位朋友进入梦寐以求的某大公司,入职没多久就和我抱怨了下,他们公司代码写的也不怎么好,连...

开发者技术前线-DevolperFront 4967

接手了屎一样的代码 怎么办?

文/北妈仅需1.9分钟就能读完今天的文,带点味儿北鼻们大家好,我是北妈。1、今天刷知乎看到一个这个话题回答这个问题前,先来看一个真实的故事,它每天在你身边发生。一个哥们撸码时忽然怒气冲...

小北哥哥和北妈 1900

告别狗屎一样的优快云 Blog系统

由于无法忍受优快云的狗屎一样的Blog系统:·乌龟般的打开和更新速度·上传图片巨慢和麻烦· 插入代码经常失败·经常来个“应用程序错误”和“Service Unvaluable”最神奇的是我在修改一篇文章后提交更新失败后,居然连我之前写的旧的内容都一并没有了。真不知道优快云的人是怎么搞的。怪不得这几年优快云的人气越来越下降,除了搞成四不像之外,对于用户的需求没有一次能够认真对待的。Blog的几

pengpenglin的专栏 3541

优快云就是国产技术社区之耻!!!

不做好内容管理,垃圾内容横行也就算了,我就想问问谁给你的权力不经过作者的同意就擅自把人家的文章设置成VIP可见的?你的吃相能再难看一点不?技术圈本就是需要开源精神,乐于分享,互帮互助才能推动技术的快速进步,怎么现在变成你优快云圈钱的工具了?以后再在优快云发布一篇文章我就是狗!

qq_44081639的博客 1082

如何避免把 Python 代码写得跟屎一样?

同样的功能,你可以使用不同的代码方式来实现,它们,都可以跑的起来,而在背后的那些「跳动」着的代码,有的美如诗,有的丑如屎...如果说,代码是有生命的,那么你希望它是温柔的天仙,还是抠脚的大...

小詹学python的博客 353
上一篇: 算法--寻找两个正序数组的中位数
下一篇: 算法--翻转二叉树
CodersCoder
博客等级 码龄10年 90粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值