资讯动态

Python深拷贝和浅拷贝有什么区别?一文讲透内存机制与避坑指南

发布时间:2026/10/9 6:48:25 来源:尧图企业网站定制
Python里那句赋值不等于拷贝我踩了整整两天才真正想明白。当时处理一份嵌套了好几层的配置字典为了不改动原始数据我小心翼翼地写了个new_data old_data然后对着new_data一顿操作猛如虎回头一查原始数据早就被改得面目全非了。更诡异的是明明用了copy.copy()内层列表却还是被悄悄动过。那会儿还以为是代码有 bug排查到半夜才发现问题出在拷贝这个基本概念上。这篇文章想跟你彻底讲透深拷贝和浅拷贝它们到底在内存层面做了什么、各自的适用场景、开发中因为误用导致的神坑以及几个用起来很顺手但很多人都没注意到的进阶技巧。无论你是刚开始学 Python 的新手还是已经在项目里被引用别名坑过的老手搞清楚这三个字背后的机制能帮你省掉大量调 bug 的时间。后面我用的所有代码都基于 Python 3.8新版 Python 行为完全一致放心用。1. 深拷贝与浅拷贝到底在解决什么问题先别急着看 API想理解拷贝得先理解 Python 里变量的本质。很多初学者有一个根深蒂固的误解觉得a [1, 2, 3]就是把数据装进变量 a 里。但实际上a 里存的不是一个列表本体而是列表对象在内存中的地址。你拿a去做运算、传参、赋值全程都是拿着这个地址在操作。这意味着什么意味着b a这个写法并没有创建新的列表它只是复制了一份地址给 b。此时 a 和 b 指向同一块内存区域你用任何一个名字修改内容另一个名字看到的结果都会同步变化。这就是我开头那个 bug 的根源——不是代码逻辑错了是我对基本语义的认知有缺口。拷贝要解决的问题就是帮你建立起一块独立的、可自由修改而不影响原对象的新内存区域。但问题来了一个对象内部可能还嵌套着别的对象比如列表里有字典字典里又有列表拷贝到哪一层才算够深于是 Python 把拷贝分成了两档浅拷贝创建新容器对象但容器内的元素还是引用原容器里的元素对象。如果元素是可变对象修改它依然会穿透到原始数据。深拷贝从外到内把所有层级的可变对象全部重建一份新旧数据完完全全脱离关系。这里有几个很容易混淆的点我展开说一下。copy.copy()是浅拷贝copy.deepcopy()是深拷贝。另外注意直接赋值b a连浅拷贝都算不上它只是多了一个别名这个区分极其重要面试和自测里经常考。还有一个隐藏的坑列表的[:]切片语法和list()工厂函数它们都是浅拷贝不是深拷贝很多人第一反应拿切片来做独立副本结果在内层数据结构上照样翻车。理解了要解决的问题下一步就是去看 Python 内部到底怎么识别的可拷贝对象以及它对不同数据类型为什么会给出不同的默认行为。2. 不可不知的内存机制可变对象与不可变对象的博弈Python 里的所有数据类型按创建后能否修改内容可以分成两类。不可变对象包括 int、float、str、tuple、frozenset 这些创建之后内容就锁死了。可变对象包括 list、dict、set以及大部分自定义类的实例。这一区分直接影响拷贝的行为。拿元组举例t (1, 2, [3, 4])你看着它是不可变的但里面的列表元素是可变对象。浅拷贝这个元组时外层元组虽然是新建的但内层列表还是同一个引用。你若通过t_copy[2].append(5)原始元组里的列表也会跟着多出一个 5。这就构成一个很有意思的假不可变陷阱——很多人在 dict 的 key 或集合元素里放 tuple以为绝对安全tuple 本身确实不能增删元素但它内部可能引用着可变对象一旦被改动哈希值就会变化整个数据结构就乱了。再说说 Python 内部的优化机制。对于不可变对象Python 有个叫驻留interning的优化某些小整数和短字符串在内存中可能是同一个对象。这就导致一个现象a 1; b 1; a is b的结果是 True。但注意这是解释器层面的优化不是拷贝逻辑的一部分。更深层的意义在于对不可变对象做浅拷贝Python 发现内容无法被修改干脆直接返回原对象引用不浪费多余内存。这就是为什么你看到copy.copy(5)返回的 5 和原 5is为 True 的原因。内存布局上可变对象通常包含三个部分对象头含类型指针和引用计数、具体的数据缓冲区、以及维护元素索引的辅助结构。浅拷贝需要新建对象头和数据缓冲区但元素区只是指针数组的复制。深拷贝则是走完全独立的递归路径逐层调用拷贝逻辑连元素指向的内层对象地址都不一样了。理解这点后你就明白为什么深拷贝慢且费内存而浅拷贝快且省——因为它俩的工作量根本不在一个量级。Python 里在背后做拷贝工作的实际上是copy模块里的两个函数它们与对象类型无关走的是统一的协议机制。下一节我会直接放代码对比让你直观看到内存地址和内容的变化。3. 直接上手赋值、浅拷贝、深拷贝的代码级对比与其背概念不如把三种操作摆在一起看结果。我写了个小实验核心是看两个变量之间的id()内存地址和嵌套内容的变化这是理解拷贝最直观的方式强烈建议你自己跑一遍。import copy original { name: blog_demo, tags: [python, copy], meta: {level: 3, author: admin} } # 1. 直接赋值只是多了一个名字 alias original # 2. 浅拷贝外层是新的内层元素还是原对象 shallow copy.copy(original) # 3. 深拷贝全链路复制 deep copy.deepcopy(original) print(original id:, id(original)) print(alias id: , id(alias)) print(shallow id: , id(shallow)) print(deep id: , id(deep))跑出来的结果大概率是alias 和 original 的 id 完全相同shallow 和 deep 则是新的内存地址。接着去验证内层元素的独立性print(original[tags] id:, id(original[tags])) print(shallow[tags] id: , id(shallow[tags])) print(deep[tags] id: , id(deep[tags]))这轮的输出非常关键shallow 的 tags 列表 id 和 original 一样deep 的 tags 列表 id 是全新的。现在做一次修改实验观察影响范围shallow[tags].append(shallow_append) shallow[meta][level] 99 print(original[tags]) # 会看到 shallow_append因为内层列表是同一个 print(original[meta]) # 会看到 level 变成 99因为内层 dict 也是同一个 deep[tags].append(deep_append) print(original[tags]) # 不受影响仍然是 [python, copy] print(deep[meta]) # 不受影响这里有几个容易看花眼的地方我提醒一下。copy.copy()对外层的 dict 确实创建了新对象所以你给shallow[new_key] 1不会影响 original。但shallow[tags]和original[tags]是同一个列表对象改列表的内容增删改元素就会穿透。同理deep[meta][level] 99完全改的是新 dict原数据毫发无损。另外还有列表切片这个高频写法arr [[1, 2], [3, 4]] arr_slice arr[:] arr_slice[0].append(99) print(arr) # [[1, 2, 99], [3, 4]]内层被影响了这个例子说明切片拷贝只复制最外层的壳里面还是共享的。如果你想让内层完全独立得老老实实用copy.deepcopy(arr)。现在三个操作的边界已经清晰了浅拷贝适合只需要修改容器本身的结构增删键、增删元素而内层元素保持共享的场景深拷贝适合需要完全隔离、每个层级都独立改写的场景。但选择拷贝方式之前还得先搞清楚copy模块内部是怎么工作的以及哪些对象不能简单粗暴地深拷贝。4. 核心机制拆解copy 模块的工作原理与协议copy.copy()和copy.deepcopy()并不是对所有类型都用一套通用逻辑它们是按协议驱动的。一个对象想参与拷贝需要实现或者能匹配到特定的方法这个机制有点像序列化和反序列化的定制入口理解它能帮你写出行为可控的自定义类。先看浅拷贝的流程大致是如果对象实现了__copy__()直接调用它把返回值作为拷贝结果。否则尝试用copyreg.__reduce_ex__()去重建对象这个过程会用到__reduce_ex__或旧式的__reduce__相当于记录了一条怎么创建这个对象的指令再在空对象上把属性填充进去。对于 list、dict、set 这些内建容器类型走的是_copy_dispatch里的专用逻辑比如列表用obj[:]字典用obj.copy()集合用obj.__copy__()。这些底层操作对用户不可见但表现结果等效于浅拷贝。深拷贝的核心实现是deepcopy这个函数它内部维护了一张memo字典作用是记录哪些对象已经复制过了。这个机制我展开说一下因为很多诡异行为都源于它。深拷贝走的是递归逻辑遇到一个对象先查 memo如果发现该对象已经处理过直接用之前的拷贝结果避免重复拷贝。这个 memo 地图有两个直接效果。第一是解决循环引用问题。比如一个列表a []然后a.append(a)列表里套了自己。如果深拷贝不记录 memo递归会陷入无限循环栈直接爆掉。有了 memo第二次遇到自己时直接返回已经拷贝好的新列表整个过程平稳结束。这个特性在实际业务里非常有价值比如处理图结构、链表有环、缓存对象相互引用时deepcopy 不会卡死。第二是保证引用关系的一致性。举个例子两个列表x [1, 2]和y [x, x]y 里有两个元素都指向同一个 x。深拷贝 y 时如果没有 memo第二个元素可能被复制成一个新对象导致拷贝结果里两个元素不再是同一个对象这违反了拷贝应该保持原结构关系的语义。有 memo 之后第二个元素直接复用第一次拷贝的结果连引用指向都一模一样只是整体换了一块内存。再看__copy__和__deepcopy__协议的具体写法import copy class Config: def __init__(self, level, tags): self.level level self.tags tags def __copy__(self): return type(self)(self.level, self.tags.copy()) def __deepcopy__(self, memo): new_tags copy.deepcopy(self.tags, memo) return type(self)(self.level, new_tags)实现__copy__时注意浅拷贝协议约定默认复制外层内层可变对象保持共享。如果内层有 list 这样的可变对象通常在浅拷贝里直接copy.copy(self.tags)或self.tags.copy()就够了。实现__deepcopy__时必收memo参数所有递归深拷贝内部的嵌套对象都要尝试copy.deepcopy(inner, memo)把 memo 传进去这样循环引用和共享引用才能在自定义类里继续被正确处理。新手写协议时最容易漏掉的就是 memo 参数传递一旦漏了遇到自引用或共享引用结果就会跟预期不一致。还有一个值得了解的知识点pickle和copy在机制上有亲密关系。copy模块在重建对象时会优先检查是否可以用copyreg注册的还原函数本质上和 pickle 的序列化逻辑类似。所以某些不能 pickle 的对象比如打开的文件句柄、数据库连接往往也不能深拷贝。另外默认情况下深拷贝会递归复制内部所有可 copy 对象包括函数、类对象、模块对象——这些对象在大多数情况下是共享的因为copy.deepcopy对它们不做复制而是直接返回引用。这样设计是合理的函数和类是全局的复制一份一模一样的函数对象没有意义反而破坏模块间的共享契约。协议讲完趁热打铁看看实际开发里哪些场景最容易踩坑又该怎么用这些机制写出稳妥的代码。5. 实战场景嵌套结构、自定义类和特殊对象处理先聊一个最常见的需求处理嵌套字典比如从 API 拿到的 JSON 配置。你经常需要基于默认配置生成一份带覆盖的副本此时如果图省事用浅拷贝就会面临某个内层字段被意外改写的风险。我的习惯是这样的先deepcopy一次默认配置得到独立副本再对副本逐项覆盖。这样后续不管嵌套多深改动都只落在副本上。一个容易忽略的点json.loads(json.dumps(data))这种JSON 序列化大法确实也是一种深拷贝手段但它有几个致命局限。其一它只能处理 JSON 原生类型dict、list、str、int、float、bool、None遇到 tuple、set、自定义对象就会强制转换或直接报错。其二它对数字和字符串之外的 Python 对象完全无能为力。所以除非你的数据一定可以被 JSON 规范化表示否则别拿它当通用深拷贝方案。再看一个我实际处理过的业务例子。有个项目要维护一份用户权限表结构是用户ID - 项目 - 操作列表其中操作列表是可变的。每次为新用户创建权限时直接用浅拷贝dict.copy()复制默认权限结果共享了操作列表。后来管理员给 A 用户添加了 read 权限B 用户的 read 权限也莫名其妙出现了排查了半天才发现是浅拷贝导致的。这类配置覆盖场景几乎是深拷贝的高频使用区间项目里处理这种结构时建议默认深拷贝除非你明确知道内层不可变。自定义类的拷贝需要额外上心。默认情况下copy.copy和copy.deepcopy会尝试直接复制__dict__里的内容但不会调用__init__。这意味着如果你的__init__里做了特殊初始化建立连接、生成临时文件、注册回调默认拷贝不会执行这些逻辑。来看一个反直觉的例子import copy class Worker: def __init__(self, name): self.name name self.tasks [] self._init_extra() def _init_extra(self): print(finit extra for {self.name}) w Worker(alice) w2 copy.copy(w) # 不会触发 _init_extra这种默认行为对某些场景很糟糕。比如类持有文件句柄、线程锁、socket直接拷贝状态后两个副本共享同一个操作系统级资源极易引发越界读写、死锁等诡异问题。解决办法是实现__copy__/__deepcopy__协议在协议里主动执行安全的重建逻辑只拷贝能被安全复制的部分资源属性要么重建要么共享。另外还有几种类型深拷贝会直接绕道返回原引用。函数、方法、类对象、模块对象、re.Pattern编译后的正则表达式copy.deepcopy都不会复制而是原样引用。这其实是合理设计这些对象通常被设计为全局单例复制一份没有任何意义。但如果你是新手看到深拷贝后a is b为 True 时别慌先看看类型是不是上述几类。有一个场景让我对 deepcopy 的底层细节印象极深处理 Excel 数据生成报表模板时模板里嵌着单元格样式、公式对象和引用关系。我最初拿deepcopy去复制整个 workbook 对象瞬间内存暴涨最后 4G 内存都被吃光了。原因就是嵌套层级太深、对象数量太多deepcopy 的递归开销和中间状态激增。后来我改为只复制当前工作表的结构化数据单元格的值和坐标样式引用直接用索引记录内存占用直接降了一个数量级。这里给个实战建议能用浅拷贝就浅拷贝不得不用深拷贝时先评估对象体积和嵌套深度。6. 性能与陷阱什么时候该深拷贝什么时候该绕开深拷贝听着全能但性能账必须算清楚。deepcopy本质是深度优先遍历 映射记录 重建它的时间复杂度接近 O(对象节点数)空间上除了产出新对象还要维护 memo 字典。一个包含 100 万元素的嵌套列表浅拷贝耗时可能在几毫秒深拷贝可能要几百毫秒甚至更多具体取决于嵌套深度和每层的对象创建成本。我做过一组简单测试数据是一个嵌套 5 层的列表每个叶子节点是整数import copy, time def build_nested(depth, width): if depth 0: return [0] * width return [build_nested(depth - 1, width) for _ in range(width)] big build_nested(5, 6) # 造一个中等规模的嵌套结构 print(嵌套总数:, count_nodes(big)) # 大致在几千个节点 start time.perf_counter() shallow_copy copy.copy(big) shallow_time time.perf_counter() - start start time.perf_counter() deep_copy copy.deepcopy(big) deep_time time.perf_counter() - start print(f浅拷贝耗时 {shallow_time:.6f} 秒) print(f深拷贝耗时 {deep_time:.6f} 秒)在我的机器上深拷贝耗时大概是浅拷贝的 30~50 倍。如果你在循环里对一个大对象反复深拷贝比如每处理一行数据就复制一次全量配置那性能就完全没法看了。优化思路一般有三个缓存深拷贝结果。如果配置数据不常变更那就一次性 deepcopy 出几个固定副本后续反复使用而不是每次都从头复制。只深拷贝真正变化的子结构。比如只需要改配置里某个 dict 的某个字段就只对那条路径做深拷贝其他部分仍然共享引用——这与按需复制的思路一致很多框架的结构化克隆就是这么做的。实现自定义__deepcopy__只复制业务相关的核心状态跳过大字段比如日志缓冲区、缓存字典、连接池这样能大幅降低拷贝体积。还有一类隐性问题值得警惕深拷贝和线程安全。如果你的对象包含多个线程共享的可变状态深拷贝只是复制了某个时刻的状态快照拷贝完成后原对象可能在别的线程里继续突变。所以压根不存在深拷贝就能高枕无忧的说法——共享状态永远需要锁或不可变设计来兜底。另外很多库提供了自己的复制方法比如 pandas 的DataFrame.copy(deepTrue/False)、numpy 数组的np.copy()、collections.deque的copy()。这些方法的默认行为和 Python 标准库的 copy 模块未必完全一致用的时候一定要读文档确认。尤其是 pandasdf.copy()默认其实执行的是深拷贝但复制的是 DataFrame 内部的数据缓冲区不是 Python 层面逐对象递归所以性能特征跟copy.deepcopy(df)完全不同。遇到框架自带容器优先用框架方法别乱套 copy 模块。最后再补一个可变默认参数衍生出来的坑。有的人图省事在函数定义里写def func(data[])然后在函数内部copy.copy(data)以为拷贝了就安全。实际上默认参数在定义时只创建一次后续每次调用拿到的都是同一个列表对象浅拷贝之后内层列表共享照样容易出问题。正确的姿势是用None做默认值函数内部按需创建。这就是为什么我的代码规范里明确规定任何需要默认可变容器的函数一律以 None 占位内部再初始化。7. 常见问题与排查实录我在开发环境里遇到过不少和拷贝相关的疑难杂症挑几个典型的列出来给你当速查手册用。问题一浅拷贝后修改内层列表原数据居然跟着变了这是最经典的问题。原因就是内层元素仍是同一个引用。排查方法分别打印id(original[key])和id(copy[key])如果相同说明确实共享。解决办法内层也需要独立时改用copy.deepcopy或者手动对每个内层可变对象单独.copy()。问题二深拷贝跑着跑着报 RecursionError深拷贝递归深度受 Python 递归限制影响当嵌套层级超过sys.getrecursionlimit()默认 1000时控制台就会弹出RecursionError: maximum recursion depth exceeded。碰到这种先确认数据里有没有深层嵌套比如树结构遍历太深。临时解决可以调高递归上限import sys sys.setrecursionlimit(5000)但注意这只是把锅往后挪了挪数据真正达到几万层时照样崩。更稳的做法是改造数据结构让它扁平化或者干脆绕开 deepcopy 去手动处理。问题三自定义类深拷贝后初始化的资源连接没建立前面已经说了deepcopy默认不执行__init__它直接从已有状态复制。如果 rebuild 过程依赖__init__里的逻辑结果就不对。解决办法是实现__deepcopy__协议在协议里显式调用自己的初始化流程或者重建连接对象。问题四明明深拷贝了但内存占用还是翻倍膨胀深拷贝不可避免会复制所有可达对象一个对象在对象图里出现 N 次因为 memo 机制它只被复制一次所以内存膨胀一般是每个独立对象都要一份状态导致的合理代价。如果膨胀异常检查有没有意外的大缓存对象混入可拷贝属性把它在__deepcopy__里排除掉即可。问题五copy.deepcopy 对某些第三方库对象无效有些对象如 PyTorch 的 Tensor、数据库游标、matplotlib 的 figure没有实现 copy 协议甚至注册了禁止复制的逻辑深度拷贝会直接抛异常或复制出一个无法使用的空壳。这类对象应该自己实现转移逻辑或提取核心数据再重建别指望 deepcopy 通吃所有类型。问题六deepcopy 结果里对象顺序变了或数据丢了一半这个极其罕见但如果你的对象极其复杂内部状态持有多个弱引用并且 weakref 回调在 copy 过程中触发结果是不可控的。这种情况建议查一下对象内部是不是用了弱引用做缓存提前把关键数据抽出来再重建。排查经验总结下来一句话先用id()确认内存地址再谈拷贝策略。任何两个对象之间的关系打印一次地址就能看清是共享还是独立这是最直接的证据链。8. 到底该用哪种拷贝方式一个可复用的决策清单写代码时不能每次都在脑子里临时算该浅还是该深我整理了一套判断流程套上就能决策特别适合团队里统一规范。如果只是给对象取个新名字不准备改内容——直接赋值。如果要改的是外层容器本身增删 key、增删元素且内层元素全是不可变类型——浅拷贝就够了。如果内层存在可变对象而且你可能会通过拷贝后的路径去修改内层内容——必须深拷贝。如果对象结构只有一层不存在嵌套——浅拷贝和深拷贝效果几乎等价优先浅拷贝。如果对象嵌套深、配置复杂但数据量巨大——优先考虑按需复制或自定义__deepcopy__别无脑 deepcopy。如果对象内部持有不可长期共享的外部资源文件、连接、锁——不能直接深拷贝得实现协议自定义重建逻辑。这套清单在大多数业务代码里都能直接用。还有一个辅助决策信息尽量让项目里的配置类、状态类实现__copy__/__deepcopy__协议。这样调用方不需要关心内部结构是否复杂一份拷贝调用背后就是语义正确的逻辑。拿我自己的项目举例子。我维护过一套多租户的缓存系统每个租户有独立的配置 dict 和缓存 dict。缓存 dict 里存的是内存对象绝不能被拷贝配置 dict 需要全量隔离。我的做法是给租户对象实现__deepcopy__只复制配置字段缓存字段直接返回引用并重新初始化。这样既能保证隔离性又能避免无意义的缓存复制。使用中还有两个细节想强调。一是deepcopy对元组的处理如果元组内部全是不可变对象深拷贝会直接原样返回该元组对象不会新建但如果元组内部含有可变对象它就会重建元组并深拷贝内部元素。二是set的浅拷贝直接copy.copy(a_set)会返回一个新 set成员元素共享引用所以如果你只增删 set 成员而成员本身是不可变对象浅拷贝足够。9. 多一层理解浅拷贝在并发与函数式编程里的价值聊到这有人可能会问既然浅拷贝对内层无能为力那它存在的意义到底是什么很多时候它就是性能与安全的平衡点。我在做数据管道时经常要对一批 DataFrame 做多步骤处理每一步都要基于原始表推导新列。用 pandas 的话df.copy(deepFalse)可以创建一个视图副本底层数据共用但索引和结构独立。这样既能避免修改原始结构又能让内存占用保持一个低位。你如果不管三七二十一每步都 deepcopy大数据集的复制开销很可能直接拖垮调度任务。同样的思路也适用于函数式编程。很多函数签名要求不修改入参但内部需要临时组装一个带额外字段的结构浅拷贝就足够——外层容器独立内层字段共享引用既没破坏入参的容器结构又避免了不必要的深层复制。内层如果确实要被修改再把修改动作收敛到明确标记出来的显式深拷贝点让代码审核者一眼就能看到哪些路径出现了真正的复制。这个思路还有个进阶玩法共享不可变数据 按路径复制可变数据。有些现代框架做状态管理时就是这么干的——状态树的不可变部分全量共享只有需要更新的路径才复制一份新结构。你的 Python 代码也可以模仿这个思路把配置拆成基础配置不可变和运行时覆盖可变两层基础配置做一次深拷贝运行时覆盖只对变更路径单独复制。很多所谓高性能拷贝方案底层都是这种懒拷贝 路径复制的组合拳。10. 从深拷贝到对象图理解一轮查 bug 后的个人体会深拷贝和浅拷贝这个知识点表面上只是一个小小的 API 选择但实际上它牵扯到 Python 变量语义、对象内存布局、递归协议、序列化机制好几层知识。我最终能把这套东西用得顺手靠的不是背 API而是真正明白了赋值、拷贝、引用三者之间的本质区别。这里分享一个非常实用的排查习惯遇到跟数据被莫名修改相关的 bug先别急着怀疑并发或逻辑先把涉及的对象 id 全部打出来看它们在赋值、拷贝、修改的每个阶段是否还指向同一块内存。这个习惯帮我定位了不少隐蔽问题包括前阵子一个同事写的配置合并逻辑就是因为在某层误用了浅拷贝导致不同环境配置互相污染。我在实际项目中采用的两个规矩你可以直接抄走凡是跨模块传参并且不希望被改动的数据一律深拷贝后交出。比如配置、默认值、模板数据这一类数据最怕被调用方悄悄改坏。凡是能确认内层不可变或线程安全的数据放心用浅拷贝。减少无意义的深拷贝项目性能会好很多。最后再分享一个小技巧给要处理 Pandas 或 NumPy 数据的朋友。df.copy(deepFalse)虽然名为浅拷贝但它和copy.copy(df)的语义有差别df.copy(deepFalse)是共享底层数据但独立索引结构而 NumPy 的arr.copy()默认是深拷贝arr[:]切片视图才是浅拷贝。不同库之间的命名差异很大动手前一定要确认你调用的到底是什么语义。遇到不确定的时候直接打印id()或者用一个小的测试用例验证一下比读文档更快更稳。深浅拷贝这个事表面上只是copy模块的两个函数但吃透它之后你会对 Python 的内存管理和对象模型有一个质的认知提升。这个理解会渗透到你后续所有代码设计里从函数参数传递到缓存设计再到序列化处处都能用上。希望这篇总结能帮你少踩几个我当年踩过的坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑