偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Karpathy力薦博客:寫代碼的時(shí)候,請(qǐng)心疼一下讀代碼的同事

人工智能 新聞
著名 AI 科學(xué)家 Andrej Karpathy 在 X 上分享的一篇文章引起了廣泛關(guān)注和討論。這篇文章的核心論點(diǎn)是「認(rèn)知負(fù)荷很重要」,即在寫代碼時(shí),應(yīng)該考慮之后閱讀者和維護(hù)者能否更輕松地理解這些代碼。

今天上午,著名 AI 科學(xué)家 Andrej Karpathy 在 X 上分享的一篇文章引起了廣泛關(guān)注和討論。這篇文章的核心論點(diǎn)是「認(rèn)知負(fù)荷很重要」,即在寫代碼時(shí),應(yīng)該考慮之后閱讀者和維護(hù)者能否更輕松地理解這些代碼。Karpathy 認(rèn)為「這可能是最真實(shí),但最少被實(shí)踐的觀點(diǎn)?!巩吘瓜喈?dāng)多開發(fā)者都樂于在自己的項(xiàng)目或工作中「炫技」,甚至以花哨復(fù)雜、難以理解為榮。

圖片

很多讀者對(duì)此表示了認(rèn)同,并分享了自己的觀點(diǎn)和經(jīng)歷。

Hyperbolic 聯(lián)合創(chuàng)始人及 CTO Yuchen Jin 順勢(shì)分享了一本書《軟件設(shè)計(jì)的哲學(xué)》。他指出:「復(fù)雜性是軟件的主要敵人。」這本書將復(fù)雜性定義為:軟件系統(tǒng)結(jié)構(gòu)中任何會(huì)使系統(tǒng)難以理解和修改的東西。而認(rèn)知負(fù)荷是復(fù)雜性的一個(gè)重要因素。

圖片

開發(fā)者 Aryan Agal 給出了一個(gè)更為具體的建議:避免循環(huán)代碼調(diào)用,讓代碼的結(jié)構(gòu)像樹一樣。

圖片

langwatch.ai 開發(fā)者 Rogerio Chaves 則吐嘈說:最喜歡增加別人認(rèn)知負(fù)荷的是中級(jí)開發(fā)者,初級(jí)和高級(jí)開發(fā)者都會(huì)盡力讓自己的代碼清晰明白,目標(biāo)就僅僅是解決問題。

圖片

也有人思考 AI 編程中的認(rèn)知負(fù)荷問題。

圖片

不過,也有人表示,聰明開發(fā)者在代碼中炫的技其實(shí)很有趣。

圖片

以下是這篇文章的中文版。文章作者為軟件開發(fā)與服務(wù)公司 Inktech 的 CTO Artem Zakirullin,他同時(shí)也是一位資深開發(fā)者。

圖片

認(rèn)知負(fù)荷很重要

在軟件開發(fā)領(lǐng)域,有太多的流行詞和最佳實(shí)踐了,但讓我們關(guān)注一些最基本的東西吧。真正重要的東西是開發(fā)者在處理代碼時(shí)感到的困惑度。

困惑會(huì)浪費(fèi)時(shí)間和金錢。困惑是由高認(rèn)知負(fù)荷(cognitive load)引起的。這不是一些花哨的抽象概念,而是一種基本的人類約束。

認(rèn)知負(fù)荷

認(rèn)知負(fù)荷是開發(fā)者為了完成一項(xiàng)任務(wù)所需的思考量。

閱讀代碼時(shí),你會(huì)將變量值、控制流邏輯和調(diào)用序列等內(nèi)容放入頭腦中。普通人的工作記憶中大約可以容納四個(gè)這樣的塊。

相關(guān)討論:https://github.com/zakirullin/cognitive-load/issues/16

一旦認(rèn)知負(fù)荷達(dá)到這個(gè)閾值,就很難再理解各種事情。

假設(shè)我們的任務(wù)是修復(fù)一個(gè)完全不熟悉的項(xiàng)目。我們被告知該項(xiàng)目的貢獻(xiàn)者包括一個(gè)非常聰明的開發(fā)者,他使用了很多炫酷的架構(gòu)、花哨的軟件庫和時(shí)髦的技術(shù)。也就是說,那位開發(fā)者給我們?cè)斐闪烁哒J(rèn)知負(fù)荷。

圖片

我們應(yīng)該盡可能減少項(xiàng)目中的認(rèn)知負(fù)荷。

認(rèn)知負(fù)荷的類型

內(nèi)在型:來自任務(wù)本身固有的難度。這種認(rèn)知負(fù)荷無法減少,并且也正是軟件開發(fā)的核心。

外來型:源自信息呈現(xiàn)的方式。這種認(rèn)知負(fù)荷的產(chǎn)生因素與任務(wù)并不直接相關(guān),比如某個(gè)聰明開發(fā)者的奇怪癖好。這種認(rèn)知負(fù)荷可以大幅減少。這也是本文關(guān)注的認(rèn)知負(fù)荷。

圖片

復(fù)雜條件

if val > someConstant // ??+
    && (condition2 || condition3) // ??+++, 上一個(gè)條件應(yīng)該為真,c2 或 c3 之一必須為真
    && (condition4 && !condition5) { // ??, 這個(gè)會(huì)讓我們的頭腦混亂不清
    ...
}

引入一些名稱有意義的中間變量

isValid = val > someConstant
isAllowed = condition2 || condition3
isSecure = condition4 && !condition5// ??, 我們不需要記住這些條件,這里存在描述性變量
if isValid && isAllowed && isSecure {
    ...
}

繼承的噩夢(mèng)

當(dāng)我們需要為我們的管理員用戶更改一些內(nèi)容時(shí):??

AdminController extends UserController extends GuestController extends BaseController

哦,一部分功能在 BaseController 中,讓我們看看:??+

GuestController 中引入了基本的角色機(jī)制:??++

UserController 中一部分內(nèi)容被修改了:??+++

最后,AdminController,讓我們編寫代碼吧!??++++(認(rèn)知負(fù)荷越來越高)

哦,等等,還有個(gè) SuperuserController 是對(duì) AdminController 的擴(kuò)展。如果修改 AdminController,我們會(huì)破壞繼承類中的某些東西,所以讓我們首先研究下 SuperuserController:??

優(yōu)先使用組合而不是繼承。這里不會(huì)深入詳情,但這個(gè)視頻《繼承的缺陷》值得一看:https://www.youtube.com/watch?v=hxGOiiR9ZKg

小方法、類或模塊太多了

在這里,方法、類和模塊的含義是可以互換的。

事實(shí)證明,「方法應(yīng)該少于 15 行代碼」或「類應(yīng)該很小」之類所謂的警句是有些錯(cuò)誤的。

  • 深模塊(Deep module)—— 接口簡(jiǎn)單,功能復(fù)雜
  • 淺模塊(Shallow module)—— 相對(duì)于它提供的小功能而言,接口相對(duì)復(fù)雜

圖片

淺模塊太多會(huì)使項(xiàng)目難以理解。我們不僅要記住每個(gè)模塊的功能,還要記住它們的所有交互。要了解淺模塊的目的,我們首先需要查看所有相關(guān)模塊的功能。??

信息隱藏至關(guān)重要,并且我們不會(huì)在淺模塊中隱藏太多復(fù)雜性。

我有兩個(gè)實(shí)驗(yàn)性項(xiàng)目,差不多都有 5K 行代碼。第一個(gè)有 80 個(gè)淺類,而第二個(gè)只有 7 個(gè)深類。我已經(jīng)一年半沒有維護(hù)過這些項(xiàng)目了。

當(dāng)我回頭進(jìn)行維護(hù)時(shí),我意識(shí)到很難理清第一個(gè)項(xiàng)目中這 80 個(gè)類之間的所有交互。我必須重建大量的認(rèn)知負(fù)荷才能開始寫代碼。另一方面,我能夠快速掌握第二個(gè)項(xiàng)目,因?yàn)樗挥袔讉€(gè)深類和一個(gè)簡(jiǎn)單的接口。

正如《軟件設(shè)計(jì)的哲學(xué)》的作者、斯坦福計(jì)算機(jī)科學(xué)教授 John K. Ousterhout 說的那樣:「最好的組件是那些提供強(qiáng)大功能但接口簡(jiǎn)單的組件。

UNIX I/O 的接口就非常簡(jiǎn)單。它只有五個(gè)基本調(diào)用:

圖片

此接口的現(xiàn)代實(shí)現(xiàn)有數(shù)十萬行代碼。許多復(fù)雜性都隱藏在了引擎蓋下。但由于其接口簡(jiǎn)單,因此非常易于使用。這個(gè)深模塊示例取自《軟件設(shè)計(jì)哲學(xué)》一書。

特性豐富的語言

當(dāng)我們最喜歡的編程語言發(fā)布了新特性時(shí),我們會(huì)感到興奮。我們會(huì)花一些時(shí)間學(xué)習(xí)這些特性,并在此基礎(chǔ)上構(gòu)建代碼。

如果新特性很多,我們可能會(huì)花半小時(shí)玩幾行代碼,以使用這個(gè)或那個(gè)特性。這有點(diǎn)浪費(fèi)時(shí)間。但更糟糕的是,當(dāng)你稍后回來時(shí),你得重新構(gòu)建那個(gè)思考過程!

你不僅要理解這個(gè)復(fù)雜的程序,你還得理解為什么程序員決定從可用的特性中選擇這種方式來解決問題。

此處引用 Rob Pike 說的一句話:


通過限制選擇的數(shù)量來減少認(rèn)知負(fù)荷。


只要語言特性彼此正交,它們就是可以接受的。 

來自一位有 20 年 C++ 經(jīng)驗(yàn)的工程師的想法

前幾天,我在看我的 RSS 閱讀器時(shí)發(fā)現(xiàn),我的「C++」標(biāo)簽下有三百多篇未讀文章。從去年夏天到現(xiàn)在,我一篇關(guān)于 C++ 語言的文章都沒讀過,感覺好極了!

我使用 C++ 已經(jīng)有 20 年了,它幾乎占了我生命的三分之二。我的大部分經(jīng)驗(yàn)都是在處理這種語言最陰暗的角落(比如各種未定義的行為)。這些經(jīng)驗(yàn)并不能重復(fù)使用,而且現(xiàn)在全部扔掉還真有點(diǎn)讓人毛骨悚然。

比如,你能想象嗎,在 requires ((!P<T> || !Q<T>)) 和 requires (!(P<T> || Q<T>)) 中,標(biāo)記 || 的含義是不同的。前者是約束析取,后者是古老的邏輯或運(yùn)算符,它們的行為是不同的。

你不能為一個(gè)瑣碎的類型分配空間,然后不費(fèi)吹灰之力就在那里 memcpy 一組字節(jié) —— 這不會(huì)啟動(dòng)對(duì)象的生命周期。在 C++20 之前就是這種情況。C++20 解決了這個(gè)問題,但這門語言的認(rèn)知負(fù)荷卻有增無減。

盡管問題得到了解決,但認(rèn)知負(fù)荷卻在不斷增加。我應(yīng)該知道修復(fù)了什么,什么時(shí)候修復(fù)的,以及修復(fù)前的情況。畢竟我是專業(yè)人士。當(dāng)然,C++ 擅長(zhǎng)遺留問題支持,這也意味著你將面對(duì)遺留問題。例如,上個(gè)月我的一位同事向我詢問 C++03 中的一些行為。??

有 20 種初始化方式。增加了統(tǒng)一初始化語法?,F(xiàn)在我們有 21 種初始化方式。順便問一下,有人還記得從初始化列表中選擇構(gòu)造函數(shù)的規(guī)則嗎?關(guān)于隱式轉(zhuǎn)換,信息損失最小,但如果值是靜態(tài)已知的,那么...... ??

這種認(rèn)知負(fù)荷的增加并不是由手頭的業(yè)務(wù)任務(wù)造成的。它不是領(lǐng)域的內(nèi)在復(fù)雜性。它只是由于歷史原因而存在(外在認(rèn)知負(fù)荷)。

我不得不想出一些規(guī)則。比如,如果那行代碼不那么明顯,而我又必須記住標(biāo)準(zhǔn),那我最好不要那樣寫。順便說一句,該標(biāo)準(zhǔn)長(zhǎng)達(dá) 1500 頁。

我絕不是在指責(zé) C++。我喜歡這門語言。只是我現(xiàn)在累了。

分層架構(gòu)

抽象本應(yīng)隱藏復(fù)雜性,但在這里它只是增加了間接性。從一個(gè)調(diào)用跳轉(zhuǎn)到另一個(gè)調(diào)用,以便讀取并找出出錯(cuò)和遺漏的地方,這是快速解決問題的重要要求。由于這種架構(gòu)的層解耦(uncoupling),需要指數(shù)級(jí)的額外跟蹤(通常是不連貫的)才能找到故障發(fā)生點(diǎn)。每一個(gè)這樣的跟蹤都會(huì)占用我們有限的工作記憶空間。??

這種架構(gòu)起初很有直覺意義,但每次我們嘗試將其應(yīng)用到項(xiàng)目中時(shí),都是弊大于利。最后,我們放棄了這一切,轉(zhuǎn)而采用古老的依賴倒置原則。沒有需要學(xué)習(xí)的端口 / 適配器術(shù)語,沒有不必要的水平抽象層,沒有無關(guān)的認(rèn)知負(fù)擔(dān)。

如果你認(rèn)為這樣的分層可以讓你快速替換數(shù)據(jù)庫或其他依賴關(guān)系,那就大錯(cuò)特錯(cuò)了。改變存儲(chǔ)會(huì)帶來很多問題,相信我們,對(duì)數(shù)據(jù)訪問層進(jìn)行抽象是最不需要擔(dān)心的事情。抽象最多只能節(jié)省 10% 的遷移時(shí)間(如果有的話),真正的痛苦在于數(shù)據(jù)模型不兼容、通信協(xié)議、分布式系統(tǒng)挑戰(zhàn)和隱式接口。

因此,如果將來沒有回報(bào),為什么要為這種分層架構(gòu)付出高認(rèn)知負(fù)荷的代價(jià)呢?

不要為了架構(gòu)而增加抽象層。只要出于實(shí)際原因需要擴(kuò)展點(diǎn),就應(yīng)該添加抽象層。抽象層不是免費(fèi)的,它們需要占用我們有限的工作記憶。

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)有一些很好的觀點(diǎn),盡管它經(jīng)常被曲解。人們說「我們用領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)來寫代碼」,這有點(diǎn)奇怪,因?yàn)轭I(lǐng)域驅(qū)動(dòng)設(shè)計(jì)是關(guān)于問題空間的,而不是關(guān)于解決方案空間的。

無處不在的語言、領(lǐng)域、有邊界的上下文、聚合、事件風(fēng)暴都是關(guān)于問題空間的。它們旨在幫助我們了解有關(guān)領(lǐng)域的見解并抽象出邊界。DDD 使開發(fā)人員、領(lǐng)域?qū)<液蜆I(yè)務(wù)人員能夠使用統(tǒng)一的語言進(jìn)行有效溝通。我們往往不關(guān)注 DDD 的這些問題空間方面,而是強(qiáng)調(diào)特定的文件夾結(jié)構(gòu)、服務(wù)、資源庫和其他解決方案空間技術(shù)。

我們解釋 DDD 的方式很可能是獨(dú)特而主觀的。如果我們?cè)谶@種理解的基礎(chǔ)上構(gòu)建代碼,也就是說,如果我們創(chuàng)造了大量無關(guān)的認(rèn)知負(fù)荷,那么未來的開發(fā)人員就注定要失敗。

示例

這些架構(gòu)非常枯燥,也很容易理解。任何人都可以輕松掌握。

讓初級(jí)開發(fā)人員參與架構(gòu)審查。他們會(huì)幫助你找出需要花費(fèi)腦力的地方。

熟悉項(xiàng)目中的認(rèn)知負(fù)荷

如果你已經(jīng)將項(xiàng)目的心智模型內(nèi)化到了你的長(zhǎng)期記憶中,你就不會(huì)體驗(yàn)到高認(rèn)知負(fù)荷。

圖片


需要學(xué)習(xí)的心智模型越多,新開發(fā)人員實(shí)現(xiàn)價(jià)值所需的時(shí)間就越長(zhǎng)。

新人加入項(xiàng)目后,請(qǐng)嘗試衡量他們的困惑程度(結(jié)對(duì)編程可能會(huì)有所幫助)。如果他們的困惑時(shí)間連續(xù)超過 40 分鐘,那么你的代碼中就有需要改進(jìn)的地方。

如果你能保持較低的認(rèn)知負(fù)荷,新人就能在加入公司的幾個(gè)小時(shí)內(nèi)為你的代碼庫做出貢獻(xiàn)。

結(jié)論

試想一下,我們?cè)诘诙轮械耐普搶?shí)際上并不正確。如果是這樣的話,那么我們剛剛否定的結(jié)論,以及前一章中我們認(rèn)為有效的結(jié)論,可能也不正確。

你感覺到了嗎?你不僅要在文章中跳來跳去才能理解其中的意思(淺模塊),而且整個(gè)段落也很難理解。我們剛剛給你的大腦造成了不必要的認(rèn)知負(fù)擔(dān)。不要這樣對(duì)待你的同事。

我們應(yīng)該減少任何超出工作本身的認(rèn)知負(fù)荷。

對(duì)于認(rèn)知負(fù)荷,你有什么看法呢?

責(zé)任編輯:張燕妮 來源: 機(jī)器之心
相關(guān)推薦

2022-03-23 08:01:04

Python語言代碼

2019-11-18 14:45:13

代碼開發(fā)工具

2016-12-09 15:02:02

云計(jì)算

2021-07-06 07:21:17

橋接模式組合

2020-09-27 10:55:10

代碼Java字符串

2020-03-20 08:00:32

代碼程序員追求

2020-02-20 10:45:57

代碼JS開發(fā)

2025-04-02 12:20:00

開發(fā)代碼函數(shù)

2025-02-27 09:06:34

2022-04-30 08:09:37

面試開發(fā)閱讀源碼

2014-07-21 13:04:34

代碼

2022-05-09 14:33:20

代碼設(shè)計(jì)設(shè)計(jì)模式

2020-05-15 09:30:12

代碼函數(shù)語言

2020-09-26 21:23:26

程序員代碼編程

2012-07-03 09:59:03

程序員

2022-10-19 11:17:35

2012-11-30 11:26:00

代碼注釋

2019-04-15 10:45:13

pingICMP協(xié)議

2019-06-24 10:26:15

代碼程序注釋

2021-12-03 11:57:27

代碼##語言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)