編程語言雖說跟自然語言類似,但有一些本質(zhì)的區(qū)別,如果不理解這些區(qū)別,編程的檻始終過不去。這篇文章嘗試把幾個(gè)最要緊的概念提取出來咀嚼消化。
一、變量 vs 替身
例如:想要寫個(gè)程序,實(shí)現(xiàn):周一至至周日顯示不同的早餐菜單。
我們需要有一個(gè)東西來代表“今天是周幾”。可能性有 7 種,但是活在當(dāng)下的只有 1 個(gè),于是需要一個(gè)“替身”,框定它的“變身”范圍是周一至周日,然后讓它根據(jù)條件變變變……
這是對(duì)編程思維的第一個(gè)訓(xùn)練:【抽象】將某種類型、某個(gè)范圍內(nèi)變化的“實(shí)例”,抽象為一個(gè)“代號(hào)”。
坑:
-
變量命名
大媽在上周的 QA 里面提過,這幾乎是一個(gè)終極問題…… 我的理解是,這個(gè)命名同時(shí)承載了占位符、運(yùn)算對(duì)象、功能解釋、類型暗示、作用域暗示 等等的使命,于是短了燒腦,長(zhǎng)了燒眼……
-
理解成本
雖然程序是自己寫的,變量是自己命名的,但是每一次回看程序時(shí),都存在“翻譯”變量名的隱性步驟,這個(gè)步驟消耗了很多認(rèn)知資源,相當(dāng)于腦子里面得有很多對(duì)牽線木偶,運(yùn)行前是一個(gè),運(yùn)行后是另一個(gè)……相信這是老手感受不到/回憶不起的一種狀態(tài)。尤其當(dāng)程序長(zhǎng)了以后,變量越來越多,記憶變量和管理變量都成問題,還容易犯看錯(cuò)變量名的錯(cuò)誤。
填坑:
- 定義函數(shù)時(shí)想想丫的用途和變化范圍,加注釋
- 避免用三個(gè)字母以內(nèi)的命名,使用一個(gè)月后再來仍然能快速理解的命名
- 變量多的話,分一下組,或者動(dòng)手畫一下它們的關(guān)系幫助理清思路
二、數(shù)組 vs 分格抽屜
替身雖好,但是有時(shí)候還是不好管理,執(zhí)行命令起來效率有點(diǎn)兒低,因?yàn)橥|(zhì)性不夠高(雖然替身都是人,但可能年齡、愛好、性取向、左撇右撇、甜豆花派咸豆花派等等都不盡相同)、以及沒有按順序排列。
于是我們需要一個(gè)更“軍事化”的組織——數(shù)組。數(shù)組就像一個(gè)分格抽屜:
從外面看來,一個(gè)抽屜就是一個(gè)東西(里面能裝很多東西);打開抽屜,里面是按照順序放置的同一類東西,每一格都有位置編號(hào)(指針)。
這是對(duì)編程思維的第二個(gè)訓(xùn)練:【壓縮】對(duì)同樣的東西,折疊再折疊,收納再收納。
坑:
-
抽象
因?yàn)槌橄螅菀滓姵閷隙灰姼褡印懴聰?shù)組太輕松
array[]
,但是一旦加入到運(yùn)算中(尤其是循環(huán)),腦內(nèi)演化就容易一團(tuán)漿糊。 -
抽屜里面的抽屜
復(fù)雜性上升一維,需要先辨別是哪個(gè)抽屜,然后再定位到抽屜內(nèi)的單元。
小抽屜為大抽屜增加了多樣性,一個(gè)抽屜放馬卡龍,一個(gè)放銅鑼燒,一個(gè)放...益力多…………
至于N維數(shù)組……
填坑:
- 克服對(duì)數(shù)組的心理恐懼,多使用這么簡(jiǎn)潔高效的工具,嗯
- 為對(duì)抗數(shù)組高濃縮占位符的假象,見到數(shù)組自動(dòng)腦補(bǔ)幾個(gè)空行給它
- 對(duì)循環(huán)語句中的數(shù)組尤其警惕,試著畫一畫?
數(shù)組一直是我的檻,回頭需要再補(bǔ)看視頻和笨方法,專門寫寫數(shù)組的筆記。
三、判斷+循環(huán) vs 防偽點(diǎn)鈔機(jī)
嗯?點(diǎn)鈔機(jī)?
點(diǎn)鈔機(jī)工作特點(diǎn):根據(jù)設(shè)定的條件,重復(fù)同一步驟。這正是 “判斷+循環(huán)”的精髓。感謝它將我們從機(jī)械勞動(dòng)中解放出來。
下面的代碼雖然只有幾行,但是綜合了變量、運(yùn)算、循環(huán)判斷、數(shù)組等等,濃縮是濃縮,坑也很多……
for shapes in shape_list:
if shapes[1] == "circle":
canvas.draw_circle(shapes[0],Radius, 1, "Black",shapes[2])
else:
canvas.draw_polygon(shapes[0], 1, "Black",shapes[2])
以上對(duì)編程思維的第三個(gè)訓(xùn)練:【自動(dòng)化】找出條件,識(shí)別共同步驟,循環(huán)處理,實(shí)現(xiàn)量變到質(zhì)變。
坑:
- 抽象
循環(huán)里面如果有個(gè)函數(shù)調(diào)用,再來個(gè)二維數(shù)組,腦子馬上就漿糊了
填坑:
- 用 viz mode 這類的可視化工具幫助理解,訓(xùn)練循環(huán)折疊思維…… 推薦偶像Bret Victor的一篇文章:LEARNABLE PROGRAM — Designing a programming system for understanding programs ,中文版 易學(xué)編程:一個(gè)幫助理解程序的編程系統(tǒng)的設(shè)計(jì)
四、函數(shù) vs 百寶袋
每個(gè)函數(shù),都是哆啦A夢(mèng)百寶袋里面的一件寶物!
寶物的特點(diǎn)是什么?實(shí)現(xiàn)大雄的一個(gè)愿望。至于怎么實(shí)現(xiàn)的,大雄并不用擔(dān)心。當(dāng)然,想實(shí)現(xiàn)多個(gè)愿望,最好不要指望于一件寶物,那樣往往會(huì)出bug……
說回最開始一周早餐菜單的例子。要 print 不同的菜單,我們需要先判斷今天是周幾,這件事可以寫到一個(gè)函數(shù) whatIsTheDay()
中。以后一旦要做這件事,就 call 一下這個(gè)函數(shù),外包這項(xiàng)任務(wù)給它,自己就翹著二郎腿等著它給出結(jié)果。一個(gè)程序中有多個(gè)函數(shù),也就成了一個(gè)百寶袋。
函數(shù)的強(qiáng)大之處還在于,可以通過參數(shù)實(shí)現(xiàn)定制化需求。比如我們?cè)诤瘮?shù) whatIsTheDay(year,month,date)
加入三個(gè)參數(shù) year 、month 和 date ,告訴函數(shù):“我想知道 某年、某月、某日 是周幾 ”
以上是對(duì)編程思維的第四個(gè)訓(xùn)練:【模塊化】分產(chǎn)承包,責(zé)任到戶;結(jié)果導(dǎo)向,過程自理。
坑:
-
貴圈太亂
函數(shù)的調(diào)用關(guān)系復(fù)雜,你調(diào)我,它調(diào)你,你調(diào)你自己……
-
參數(shù)傳遞和返回結(jié)果
參數(shù)傳遞引入了新變量(認(rèn)知內(nèi)存中又要處理多一套對(duì)應(yīng)關(guān)系 >_<),容易跟全局變量、函數(shù)內(nèi)的局部變量混淆。而返回結(jié)果又是一個(gè)隱式的變量,不可見但影響重大。
-
交叉并行路徑
如果只有一個(gè)明確起點(diǎn),調(diào)用關(guān)系也單純的程序就很好辦。但事實(shí)往往是有多個(gè)起點(diǎn)入口,調(diào)用關(guān)系也復(fù)雜,偏偏程序是線性寫下來的,不能按照從頭到尾的順序去讀。于是到底程序從哪里開始,zeng 地躥到了哪里,很讓人頭疼……
-
自定義函數(shù)和內(nèi)置函數(shù)
內(nèi)置函數(shù)的說法不對(duì),因?yàn)槟菚r(shí)還沒有了解類,所以覺得類似
frame.start()
這種東西從哪來的,就把丫們看成內(nèi)置函數(shù)。因?yàn)檠緜儾皇亲约河H生的,所以經(jīng)常覺得陌生,尤其搞不清楚丫們之間的關(guān)系。
填坑:
- 明確函數(shù)功能,加注釋
- 牢記函數(shù)的輸入(函數(shù)參數(shù))和輸出(返回值)
- 多進(jìn)行局部調(diào)試,print 函數(shù)返回值
- 函數(shù)之間的調(diào)用關(guān)系,通過可視化幫助理解
五、類 vs 招聘職位
每一個(gè)類都包含屬性(變量和值)和行為(函數(shù))。對(duì)比一下:
JD(招聘職位描述):
WXG01-微信高級(jí)交互設(shè)計(jì)師(廣州)
工作職責(zé):
- 參與微信相關(guān)產(chǎn)品從概念到原型的設(shè)計(jì)過程,輸出相關(guān)設(shè)計(jì)文檔;
- 對(duì)產(chǎn)品持續(xù)進(jìn)行設(shè)計(jì)優(yōu)化,提升用戶體驗(yàn);
- 協(xié)調(diào)和推動(dòng)可用性測(cè)試及用戶研究,以驗(yàn)證現(xiàn)有和將來的功能設(shè)計(jì);
- 負(fù)責(zé)設(shè)計(jì)前瞻性的相關(guān)研究。
工作要求:
- 工業(yè)設(shè)計(jì)、心理學(xué)、計(jì)算機(jī)、視覺傳達(dá)相關(guān)背景,本科及以上學(xué)歷;
- 3年以上工作經(jīng)驗(yàn),主導(dǎo)過1000萬+用戶的移動(dòng)互聯(lián)網(wǎng)產(chǎn)品的設(shè)計(jì),具備多領(lǐng)域設(shè)計(jì)工作相關(guān)經(jīng)驗(yàn),如產(chǎn)品設(shè)計(jì)、硬件設(shè)計(jì)、視覺設(shè)計(jì)等;
- 對(duì)互聯(lián)網(wǎng)交互設(shè)計(jì)有深刻理解,具備完整的理論和技術(shù)體系;
- 優(yōu)秀的產(chǎn)品意識(shí),良好的全局觀、前瞻性和判斷力;
- 同理心強(qiáng)烈,擅長(zhǎng)換位及獨(dú)立思考,卓越的情景還原能力;
- 優(yōu)秀的溝通、組織和項(xiàng)目管理能力;
- 性格樂觀向上,興趣愛好廣泛。
類:
class Character:
def __init__(self, name, initial_health): # __int__ 初始化對(duì)象
self.name = name # self 是新的對(duì)象的引用
self.health = initial_health # name 和 health 是self對(duì)象中的域(field)
self.inventory = []
def __str__(self):
s = "Name: " + self.name
s += " Health: " + str(self.health)
s += " Inventory: " + str(self.inventory)
return s
def grab(self, item): # methond defines the behaviors of objects
self.inventory.append(item)
def get_health(self): # method 所有方法的第一個(gè)參數(shù)都是self
return self.health
工作要求其實(shí)就相當(dāng)于類的“屬性”,作為這類人,本身需要具備什么樣的條件和素質(zhì);工作職責(zé)相當(dāng)于類的“行為”,這類人要干什么事情。
類和函數(shù)的區(qū)別在于,類只能操作某個(gè)類型的對(duì)象,而不能通過其他方法直接被調(diào)用。
面向?qū)ο缶幊痰膹?qiáng)大之處,對(duì)于一個(gè)類,理解其接口和已實(shí)現(xiàn)的方法,就可以使用了。
**這是對(duì)編程思維的第五個(gè)訓(xùn)練:【面向?qū)ο蟆浚捍虬尚停庋b上架 **
坑:還沒有真正練習(xí)過 囧,待踩。
今天先到這~ 可能有很多不恰當(dāng)?shù)念悇e,請(qǐng)各位程序猿輕拍~