關注我就能達到大師級水平,這話我終於敢說了

扔物線發表於2017-10-23

這句話我真的憋了好久。Android 工程師只要關注我,我就能讓你達到大師級水平,不是面試時的吹牛逼水平,不是自我欺騙的瞭解皮毛的水平,是真正的開發實力。以前我有這個自信,沒這個證據。但現在,證據我也有了。

關注我的人都知道,我這三個多月來一直在網上分享關於 Android 自定義繪製的技術,並且在一週多前舉辦了一場線上的「仿寫酷應用」活動,讓我的粉絲仿寫即刻、薄荷健康、小米運動、Flipboard 這四個軟體中的幾個經典效果,來自我驗證一下這三個月來的學習成果。

簡單地說,這事兒很成功(臉紅)。

經過一週的投稿時間,共收到 97 份來自關注者的投稿(真的很多,出乎意料),而且做得都很棒。在四位原開發者的艱難篩選下,每個效果選出了一位優勝者。下面就是這四位優勝者的作品以及來自各位原開發者對他們的點評。

仿寫作品

仿寫一:即刻

二話不說,先看結果。

原效果:

仿寫效果:

仿得很細緻有沒有。而且,這個仿寫效果看似簡單,其實是假象。它右邊的數字跳動,是一個字元一個字元跳動替換的,而不是整個字串一起被替換掉,這個需要對文字繪製的 API 有足夠的熟悉才能做到。

這位仿寫者叫劉金偉。在通知劉金偉成為「被選中的人」後,我對他進行了一個簡短的微信採訪。關於這次仿寫的過程,劉金偉是這樣對我說的:

到這次仿寫活動為止,HenCoder專欄已經出了8篇View繪製相關的技術文章了,每篇文章認真閱讀之後我也根據例子進行實踐操作,學到的一些東西也在專案開發中得以應用,正如文章中所說,在自定義View相關方面更加自如了。

看到這次HenCoder的仿寫活動,就有點躍躍欲試,發現這幾個效果都挺不錯的,和朋友聊了聊之後就選了這個經常會用到的點贊功能進行實踐。這個點贊效果經過我分析發現雖然內部動畫挺多,但是所用到的技術點都是在HenCoder中講到過的,所以在簡單的分析之後就開始寫,大約花了大半天時間就基本完成了,整個過程也沒太多技術難點,做出來後還給朋友炫耀了一番。

最後再次由衷的感謝HenCoder專欄,為了提升大家技術水平而做的事,非常敬佩。

不謝不謝,哈哈。

原作者點評

對他的作品進行點評的是即刻的 Android Leader 羅瓊。他對這份仿寫的評價似乎還不錯:

仿寫效果的點評,主要針對以下幾點

  1. 對原創的還原程度
  • 示例的完備程度(可測試性)
  • 專案規範
  • 程式碼實現

對原創的還原程度

這位同學仔細觀察了即刻點贊效果

  • 使用的資源應該是反編譯即刻 apk 之後拿到的
  • 實現了點贊和取消點贊兩種效果
  • 實現了左邊圖片部分的動畫
  • 實現了右邊數字部分的動畫

未實現的部分

  • 點贊對 touch 操作的處理(只處理了 click 操作)
  • 點贊效果在圖片上的先放大後縮小
  • 散開的點的放大效果
  • 整體動畫的細節優化

示例的完備程度

這個是做得比較好的

  • 可以直接設定具體數字,這樣方便做邊界條件(進位退位)的測試。
  • 上傳了可以直接安裝的 app-release.apk ,方便先安裝看效果。
  • README 有對動畫實現的說明。

專案規範

  • 沒有 .idea 這種不該上傳的資料夾
  • .gitignore 也是專門修改過的

可以優化的部分

  • 對 android support 包的依賴,不要依賴 alpha 這種版本,儘量依賴穩定版
  • 程式碼檔案都需要進行格式化,包括 xml
  • mdpi 的資源不再需要了
  • 自定義 View 的 attr 的命名,需要有自己的名稱空間(字首)
  • 自定義 View 的變數命名不規範,一會兒有 m ,一會兒有下劃線

程式碼實現

作者把圖片和文字寫在一個類裡面了,這樣的話不太靈活,即刻 app 現在在某些主題下的點贊效果不是大拇指,比如逝者這個主題就是蠟燭,所以建議圖片和文字還是分成兩個類來搞。

對點選事件的防重處理好像有點問題,另外連續點選是否直接對之前動畫進行 cancel 也需要斟酌一下。

整體的實現程式碼上冗餘邏輯比較多,並且每一個函式內部每一行語句並沒有完全去考慮,如對 specMode 的 switch case ,沒有窮盡所有的可能值。

圖片這塊的實現,整體的思路是通過事先畫好各種元素,然後通過屬性動畫的方式,但自定義的屬性動畫的方法是通過反射呼叫的,整個類裡面並沒有顯示呼叫,對於> 此類不是很複雜的動畫,建議還是用系統自帶的屬性比較好。

文字這塊的實現,涉及到偏移、顏色、以及分離出變化和不變的部分(作者對文字的解剖分析得很好),但程式碼的複用程度不高。

總體而言,專案完成度比較高,恭喜獲得本次仿寫即刻點贊效果的冠軍,不過真正商用的話還是有不少需要考慮的,尤其是程式碼規範上需要加強,再好的實現和演算法,如果程式碼不夠規範,恐怕看得人也會比較累,希望再接再厲。

評價得好詳細啊,我在讀這份點評的過程中多次遇到「哇塞好細,如果是我的話這裡肯定要被扣分了」的情況。

仿寫二:薄荷健康

依然是先上效果:

原效果:

仿寫效果:

以假亂真了有沒有?

這份仿寫的作者叫嚴積楷。他對仿寫過程的回顧是這樣的:

我覺得仿寫,首先就是要了解清楚仿寫物件的細節,所以還是自己親自體驗一下比較好,所以就下載了薄荷健康APP,發現尺子UI已經改變了(這樣就提醒了我要做一個適合多變需求的控制元件),但是一些特性也是和效果圖差不多的:觸控滑動後是有慣性滾動的游標保持在中間,不隨尺子滾動游標選中的刻度只會是0.1整點讓觸控滑動、慣性滾動之後,尺子會回滾到最近的整點刻度,如最後滑動到66.5和66.6中間靠右,則回滾到66.6。

瞭解了特性之後,就是想著怎樣實現了:首先就是畫出刻度和數字,這裡是採用一下子就畫出所有刻度的方法,然後通過滑動方法scrollBy()來移動畫面(不知道這樣系統會不會對尺子那些不在螢幕顯示的部分進行繪畫計算的,我當時是加上滑動之後,發現很可以滑的流暢,所以就這樣了,現在想想還可以處理一下的)。觸控控制方面,因為之前分析過GestureDetector,瞭解了它的實現,所以這裡就試著直接重寫onTouchEvent()和OverScroller配合實現慣性滑動。對於刻度的計算,這裡通過滑動位置getScrollX()來計算當前刻度,而又通過把滑動結束後的刻度四捨五入之後,計算對應的ScrollX來讓尺子最近的整0.1點刻度。對於游標的繪製,由於這裡是採用了scrollBy()的方法移動畫面,所以也沒有找到一個好的方法讓游標不隨尺子移動,所以就外層加入一個ViewGroup重寫dispatchDraw()方法在這裡繪製(這個方法執行在onDraw()之後,在這裡繪製才不會被尺子的刻度覆蓋掉)。

主要的實現思路就是這樣了,還有一些細節,如程式碼封裝這些比較常見的就不詳細說了,大家可以看程式碼,已經寫好了註釋,歡迎指教小弟。

「歡迎指教小弟。」高仿到這種程度竟然還求指教,這謙虛的態度莫非是討打?有人想當面指教他一下嗎?

原作者點評

對這份作品進行點評,我請到的是薄荷健康的 Android 工程師 loody。

還原度

99分,多一分怕你驕傲。

實現思路

  1. 背景繪製
    頂部基準線+純色背景。
  2. 刻度繪製,包括長、短刻度及長刻度下的文字繪製
    這塊是整個捲尺最複雜的部分,整個捲尺有最大最小邊界,所以整個刻度的繪製會基於最大、最小值以及定義的最小刻度單位來從左往右依次繪製,同時要保證當前選中的位置位於螢幕中央。
  3. 基準線繪製
    位於螢幕中間、可以有多種樣式、以上繪製必須按照順序依次繪製。
  4. 手勢滑動處理、慣性滑動
    通過監測 MotionEvent 裡的 ACTION_DOWN、ACTION_MOVE、ACTION_UP、ACTION_CANCEL 事件來監測滑動距離來進行重繪,如果滿足Fling,則使用OverScroller來計算速度來進行慣性滑動。
  5. 智慧精準定位
    滑動完之後需要進行精準定位,必須回到基準線最近的刻度,用作者的話就是滑動到66.5和66.6中間靠右,則回滾到66.6。

優點

整個實現的非常好,所有的要點都實現了,特別是精準定位體驗做得很棒,在擴充性方面,也定義了很多自定義屬性,同時也上傳到 Maven 倉庫,方便其他人呼叫。

不足之處

  1. 背景和基準線的繪製和刻度的繪製進行了分離,其實沒必要,因為他們的繪製並沒有衝突;
  2. 在刻度繪製上,螢幕之外的刻度其實可以不用繪製;
  3. 捲尺的小刻度模式可以再豐富一些,一般兩個大刻度之間有10個小刻度,當然也有2個、5個情況;
  4. 對外開放的初始化方法應該更豐富一些,因為很多時候我們的邊界值並不是固定的。

薄荷的捲尺效果要實現起來是有非常多的細節的。loody 要從幾十份仿寫中選出這一份,還要寫出這麼細緻的點評,別的我不想說,我只想對他說一句:苦了你了。另外也更想回頭對上面的仿寫者嚴積楷說一句:你太苦了!

仿寫三:小米運動

原效果:

仿寫效果:

仿得也是超棒。這件仿寫作品的作者叫陳浩,他的仿寫過程回顧充滿了認真和辛酸:

之前沒有太多做UI的經驗,所以一開始我是比較樂觀的,但最後花了整整5個晚上才做完。

我程式設計屬於比較嚴謹(囉嗦)的那種,所以準備工作時我把gif下下來用電腦逐幀看了,還借了朋友的小米手環來看實際的動畫(最新版有點出入)。然後把動畫流程寫下來,沒有做什麼模組規劃,就開始程式設計了。

最開始動手時我只有動畫引數可配置和要做動畫狀態機的這兩個想法,後面整個程式碼結構都是在編寫的過程中多次重構產生的。畢竟程式碼是程式設計師的第二張臉(我說的),給別人看的時候還是想寫的更好一些。但這也存在一些過度設計的情況,導致完成的時間變長了不少。比如,我看到那個轉動的煙花圓環線條不是一成不變的,於是天馬行空設計出來一套的動畫運動公式:這個線條是橢圓的一段圓弧,其圓心,寬和高的偏移都是隨機引數,變化量d由變化速度v決定,變化速度v由外力1.衰減常量力,2.速度平方成正比的阻力,3.定時觸發的隨機力決定(戲真多)。結果導致動畫引數調整就花太多時間,也改了好幾版才穩定下來。。

寫得好的地方的話,因為工作原因會比較考慮封裝,可維護性,可擴充性這些,這些方面我覺得還是做到位了的。

說實話,在釋出仿寫徵稿文的時候我就知道,肯定每個效果都有人能完成,但陳浩的這份作品還是讓我有點意外:你仿得也太真了!但看了他的這份回顧,我覺得我知道為什麼他寫得這麼好了。

原作者評價

我很高興請到了這個效果的原作者,來自小米運動團隊的卜冬旭來點評這份作品:

總體評價

相當不錯。。。(本來想這四個字完結點評了的,因為模仿的效果相似度很高了,而且僅憑一個gif圖,在很短的時間做出這樣的效果,真的挺厲害的。同時up主提供的程式碼裡的註釋也很清晰,規範,可以很容易理解實現的原理。但是秉著認(wu)真(ren)負(zi)責(di)的態度, 還是來吹毛求疵一下。)

細節對比

這塊的動效是小米運動app首頁的效果。示例GIF圖中包含了2部分效果,一個是小米手環連線過程中效果,就是一大堆雜亂的白色漸變的圓圈在轉,圓圈的起始位置有一個往後發散的粒子效果。另一部分就是小米手環連線成功後的效果, 也就是幾個白色透明度不等的漸變的圓環疊加在一起,最外圈層次漸變的光暈效果圍繞圓環轉動。
下面具體分析對比下這幾塊動畫效果.

圓圈的疊加效果

我這邊用了8個圓圈,每個圓圈的centerX, centerY有微小的差別,半徑有微小的差別。通過SweepGradient來設定它的漸變,從純白到20%左右透明度的白色,每個圓圈canvas.rotate的角度也有微小的差別。當然以上所有引數都可以自己任意調節,來達到參差不齊的效果, 只要整體效果不離譜就可以了。我對於其中一些引數用的都是random, 這塊沒有個標準。雜而不亂, 達到這個效果就行. :D

粒子效果

比較麻煩的就是這塊粒子效果。一方面要實現功能,一方面效能也要滿足,不能卡頓。模仿的效果就這一塊有點小問題, 一個是半徑有點大了,然後透明度可以稍微降的快一點, 再聚攏一點效果會更好。(壞笑.jpg) 這塊調起來是相當的麻煩。 這塊粒子產生在第一個效果中圓圈的最亮的地方,也就是透明度最低的地方。具體位置可以從圖中看一下。

img
img

粒子產生的位置是豎著的線的位置, 也就是隨機在這條線上生成初始粒子。 發射的角度大概是左邊2個線之間。第一個不是水平線,這兩條線的角度可以慢慢的調整,從而找到合適的效果。 需要注意一點的就是, 粒子發射的角度需要比較精細的控制, 具體點說就是因為產生粒子的位置不是一個點,而是一條很短的線,所以儘量不要讓粒子發射的延長線在很短的位置相交, 如圖

img
img

關於粒子發生器的原理這裡就不贅述了,我這裡是通過距離超過一定數就重新生成一個粒子來控制的,當然也可以通過半徑大小或者透明度來控制。Up主是通過透明度來控制的,也是沒關係的。靠近發生器位置的粒子半徑稍微大一點,然後半徑是遞減的。透明度也是遞減的。至於效能問題,也不屬於這個文章的範圍內了。可以看下up主程式碼。

圓環效果

圓環主體是五個漸變的圓環疊加在一起,其實不能算作是圓環,應該是一個圓環和4個橢圓環。 繪製的時候,第一個漸變的圓環正常繪製,後面的橢圓環通過drawArc來繪製。保證它們五個環的left,right,`bottom一樣, top引數為依次遞增一定的大小。同時需要注意一點的就是顏色最深的圓環,也就是透明度最低的環,不是橢圓環放在最後繪製,這樣可以蓋住其他稍高透明度的環,這樣不會看出疊加部分因為用的SweapGradient導致的疊加的效果。而是會覺得主體是一個整個系統,光暈是獨立系統。不然能比較清楚的看出五個環的疊加效果。

多餘的效果

其實那個整體效果,帶有一點上下振動的這塊是因為程式的下拉上推導致的,不屬於這塊的動畫效果,沒想到也給做出來了。(捂臉.jpg)

這塊效果看著挺炫的,其實使用HenCoder裡繪圖的基礎知識就可以實現,麻煩的地方就在於細節的調整, 可能調個引數就要重新跑一下程式, 還是相當痛苦的。想了解完整的動畫效果,可以從仿寫的程式碼裡看到, 也可以來這裡看。

最後竟然被冬旭兄弟打了我一個猝不及防的廣告……

仿寫四:Flipboard

原效果:

仿寫效果:

這個效果可謂是人氣超高了。我在之前的幾篇文章或視訊中都展示過這個效果,但只是說「用我教的技術就能實現」,卻沒有展示過具體的實現程式碼。很多人找我要實現,我也都沒給過,為的就是這一天,讓我的讀者自己實現出來,我只幫你展示。

這個仿寫的作者叫賈元斌,它的仿寫過程回顧如下:

仿寫“翻頁效果(加強版)”這個動效的想法,源於凱哥講解幾何變換章節提到的一個動畫栗子,很炫酷,極大地激發了偶的好奇心。

做動畫的過程,其實就是一個典型的“發現問題,分析問題,解決問題”的過程。所以大概的流程就是,先拆解分析,動畫是怎麼“動”的,然後再去解決問題,想如何使用Android提供的Api實現“這麼動”。 把gif圖放在手機上一幀一幀地截圖,然後逐張觀察,可以發現這個動畫是由三個部分組成的: - 開始動畫,一個Y軸三維旋轉-45度動效 - 中間動畫,比較複雜,圖片右半邊三維旋轉,同時三維旋轉的“轉軸”平面內旋轉了-270度,左半邊圖不變 - 結束動畫,一個繞Y軸三維旋轉30度動效 開始和結束的動畫比較簡單,camera旋轉就能實現,重點分析中間的動畫: 右半邊三維旋轉的時候,canvas先旋轉,再裁切,再使用camera執行三維動效,然後儲存camera效果,最後再旋轉回來。問題分析清楚,具體到程式碼,拿canvas和camera的幾何變換+範圍裁切,就能實現了。

需要注意的坑:camera執行幾何變換時,我們會把canvas的中心點移動到原點,所以這個時候canvas再執行其他變換(比如範圍裁切),要用移動後的座標系計算。 最後一點,不要忘記做糊臉校正,不然圖片尺寸變大時,就沒法看了…

賈元斌在最後提到的「糊臉修正」是我自己造的詞,我覺得好形象啊,佩服自己。

另外,一直找我要實現的,請到文末自取賈兄的原始碼。

原作者評價

這個點評者我熟悉,我前同事,來自 Flipboard 的段建華(技術小黑屋),以前我在 Flipboard 的時候我倆挨著坐的。

總體點評

執行效果良好,思路比較清晰。總的來說不錯。

思路與實現

  • 在readme檔案中給出了具體的實現方案並進行逐步拆分,同時給出了需要的理論分析和一些注意事項
  • 提供了在佈局檔案中設定圖片資源的實現,同時也支援在程式碼中設定。可擴充套件性較強
  • 做到動畫的執行實現與View分離,便於在不修改程式碼的情況下,更改動畫的配置,比如duration和delay時間等

程式碼質量

  • 配合以必要的註釋,便於理解。
  • MainActivity中handler.postDelayed已經位於UI執行緒,無需在進行runOnUiThread呼叫
  • 對於degreeY等方法使用Keep來註解修飾,既解決了編譯器的報警提示也避免了一些因為Proguard優化刪除無用方法帶來的潛在的問題,這一點體現了作者很周全考慮。

其他

  • 祥雲圖示的Flipboard Logo很贊
  • 替代的google_map提供了三種dpi對應的資源,+1

改進與完善

  • MapView 類的javadoc寫成“整個動畫拆分成了三部分”有些不妥,一般為類的功能介紹
  • 每一個commit的提交資訊都需要概括修改的內容,不宜出現簡單的update來了事
  • View命名成MapView,可能存在繼續優化改善的空間
  • Repo的命名建議更加和參賽作品有關,這樣便於篩選人員更好的快速辨識並分發給對應的評委。

看了建華的評價,我最大的感受就是,他果然還是這麼認真,一些很細節的地方他也都提到了。另外可能是出於謹慎考慮,建華對於這份仿寫實現和 Flipboard 的內部程式碼實現沒有進行比對。而我作為一個已經離職的員工,我就……當然也不會洩露前公司的原始碼啦。但我要特別說明一下的是,賈元斌的仿寫程式碼中的實現雖然和 Flipboard 的內部實現不完全一樣,但執行效率和程式碼可讀性都不比 Flipboard 的實現差。

至於 Flipboard 的內部實現到底是怎樣的?我就不告訴你……

優勝者中的優勝者

上期內容我說過,由於贊助方爸爸 insight.io 的支援,這次活動的四位優勝者中,還會有一位特別優勝者,他獲得的獎品和另外三位不一樣,他將獲得一步 Google Clips 相機:

這位優勝者將通過微博投票得出,投票連結:vote.weibo.com/poll/138417…

資源連結

幾位仿寫者的仿寫程式碼連結在這裡。這裡貼的是 insight.io 從 github 同步的程式碼庫,用 insight.io 來讀原始碼超級爽(具體怎麼爽,你點開就知道了),真的感謝 insight.io 的在禮物支援之外還給予我的技術支援。

即刻仿寫insight.io/github.com/…
關於仿寫者劉金偉:
github: github.com/arvinljw
簡書: www.jianshu.com/u/8fcc3372b…

薄荷健康仿寫insight.io/github.com/…
關於仿寫者嚴積楷:
github: github.com/totond
CSDN: blog.csdn.net/totond
郵箱: yanzhikai_yjk@qq.com

小米運動仿寫insight.io/github.com/…
關於仿寫者陳浩:
github: github.com/SickWorm

Flipboard 仿寫insight.io/github.com/…
關於仿寫者賈元斌:
github: github.com/sunnyxibei
微博: weibo.com/812306989
微信: sun521xibei
個人部落格: timeriver.com.cn/

關於幾位點評者

想了解幾位點評者,想和他們一起工作?趕快看這裡。

即刻

羅瓊給了我一份超長的文案,我嫌長想給他刪點,可又覺得這份文案寫得已經超級棒,哪一句都刪不得,所以乾脆把這份文案最重要的關鍵詞提取了出來,被這些關鍵詞吸引了的可以點下面的連結進去看詳情:

即刻的關鍵詞:

流浪貓、400 平米、自帶 Gif 表情包文化、健身房、檯球桌、無人機、電玩裝置、足球隊、男女比例平衡、年輕、一年兩次免費國內外純玩 Outing、La Marzocco咖啡機 + Volcan 豆(這個看不懂)、咖啡師、Herman Miller人體工學座椅、公費參加 Google IO & WWDC

好吧我只提取了「福利」部分的關鍵詞,因為我最關心這個……其實即刻團隊做的事情更有意思,不過篇幅有限就不給它展示的機會啦(任性臉),有興趣的可以點連結去看詳情:

www.v2ex.com/t/388064

哦對了,工作地點上海。

小米運動

冬旭兄比較委婉地把招聘廣告插進了點評的最後(就是上面那句「想了解完整的動畫效果,可以從仿寫的程式碼裡看到, 也可以來這裡看」的「這裡」)。不過我還是要在這裡再貼一次他們的招聘連結,讓需要的人更清楚地看到:

www.huami.com/jobs

「華米科技」,又是一個米。你猜小米旗下到底有多少種米?

Flipboard

我的老同事建華給我發的「廣告」是這樣的:

此次仿寫的參考目標之一為 Flipboard 的摺頁效果,Flipboard 中國團隊目前進行了有史以來最特別、動作最大的一次產品升級改版,推出全新產品——紅板報,它將帶來更對味的個性化內容推薦、更廣闊的全球化新聞視野、更生動的雜誌化瀏覽體驗。通過紅板報,要將全球最優質的新聞內容用最好看的方式呈現,精簡產品功能迴歸到閱讀最核心使命:新聞可以很好看。

嗯,Flipboard 中國改為名紅板報之後,作為開發者之一的建華很自豪,也很希望推薦給大家用。至於招聘連結……建華表示「什麼招聘連結?」

Flipboard 北京辦公室暫時沒有 Android 職位空缺,所以建華其實是在給他自己打廣告(哈哈哈我寫了個好 App),大家快去打他呀。

薄荷健康

關於招聘,loody 和建華一樣對我表示目前沒有需求,只是告訴我「能提到薄荷健康就最好了」。

只付出不求回報的好同志。好吧,那我就來負責他們的文案吧:

薄荷健康,真呀真健康,裝了薄荷健康,又瘦又健康。耶。

感謝

最後非常感謝四位點評者的幫助,這次活動的響應度比我的預期大很多,各位點評者光是審閱投稿就花了一天的時間,審完還要來幫我寫點評語,寫得短的還要被我打回去重寫……真的辛苦了,你們。謝謝!

另外,還要感謝 insight.io 的兩位聯合創始人李崇哲、趙扶搖,在物質和技術上給我提供支援,讓我這第一次自己主持的線上活動少了許多手忙腳亂。當然,也得感謝介紹我與 insight.io 相識的程式碼家(怎麼哪兒都有你)。

下期預告

到這期位置,HenCoder 的自定義 View 系列的繪製部分就結束了,從下期開始,就要開始佈區域性分了。按照慣例,官方洩露一點截圖吧:

佈區域性分由於技術的概念比繪製要大得多,所以掌握起來也會難一些,這個各位做好思想準備吧。不過你依然可以相信一點:就像之前的繪製部分一樣,雖然有很多人已經嘗試過通過看部落格、看文件、讀原始碼的方式來學習 Android 的佈局(有很多甚至嘗試過多次),最終都以「太難了實在學不會」告終,但只要你跟著我走,幾期內容之後,你會發現,同樣的技術,只要到 HenCoder 來學,它怎麼就變得那麼的簡單。

就像本文標題和開頭我說的,關注我,你就能達到大師級水平,這話我憋了好久,現在終於敢說了。因為,我做到了。

相關文章