主頁 >  其他 > 性能優化 = 改改代碼?

性能優化 = 改改代碼?

2020-09-21 07:45:39 其他

如果第二次看到我的文章,歡迎右側掃碼訂閱我喲~  ??

每周五11:45 按時送達,當然了,也會時不時加個餐~

我的第「124」篇原創敬上

?

 

大家好,我是Z哥,


好久沒寫技術文章了,最近正好有進行一些思考,順手寫出來分享給大家,

 

上了一定規模的系統,特別是To C的系統,性能優化或多或少都會被逼著去做一下,否則,系統便無法支撐業務的發展,技術成了拖后腿,不是引領業務了,

 

一旦線上出現了性能問題,就會很棘手,因為它和業務功能上的Bug不同,后者的分析和解決思路更清晰,只要日志記錄到位,沿著一條已知的業務邏輯線,很容易就能找到問題根源,

 

而性能問題就會復雜的多,導致的因素有很多,甚至會是多種因素共同作用下的結果,比如,代碼質量低下、業務發展太快、架構設計不合理等等,

 

而且一般情況下,性能問題處理起來比較耗時,涉及到的分析鏈路可能會很長,特別是自己小組之外的上下游系統,很多人不愿意干,或者說有心無力,最多采用一些臨時性的補救手段,碰碰運氣,比如,擴容增加機器、重啟大招、……,

 

 

有些臨時性的補救措施,有時候不但不能解決問題,還會埋下新的隱患,

 

比如,從表象上看到某個程式因為給的資源不足導致產生性能問題,臨時增加更多資源給它,可能從表面上看,問題是解決了,但是實則可能是因為程式內部對資源的使用上存在不合理的地方,增加資源只是延緩問題發作的時間,而且還可能會侵占其它程式的運行資源,

 

為了避免陷入如此的窘境,我們應當盡量提前進行性能優化,未雨綢繆,甚至最好是將它作為一個周期性的作業來進行,
接下去就來分享一下我對做性能優化的思路,

 

 

/01 明確優化目的/


很多人優化優化著慢慢變成了為了優化而優化,目的丟了,或者甚至一開始就沒考慮過,如此會陷入到無意義的性能黑洞中,無法自拔,只是不斷追求更好看的性能指標,

 

優化的目的可以是增強用戶體驗,比如消除一些有明顯卡頓的頁面和操作,還可以是節省服務器帶寬流量、減少服務器壓力這些,無論如何,你需要有一個目的,

 

 

/02 定標準,做到什么程度/


優化這事是永無止境的,為了避免陷入到前面說的無意義的性能黑洞中,我們最好能夠根據實際的業務情況定義出一個相對客觀的標準,代表優化到什么程度,
我自己慣用的標準是確保比預期高50%,如果條件允許則爭取到100%,

 

比如,根據當下的性能指標與業務量對比,發現最大并發數可能會超過當前的2倍,那么此時優化到爭取優化提升3倍,至少保證能提升2.5倍,是一個比較合理的標準,
之前專門寫過一篇關于容量預估的文章《做「容量預估」可沒有true和false》,可以在文末跳轉過去看下,這里就不展開了,

 

 

/03 找到瓶頸點/


很多人做優化的時候,逮著代碼就開始改,的確,只要有一定的知識積累,很容易就能從代碼中發現,寫法A不如寫法B這樣的代碼,

 

但其實大部分情況下,「流程上的優化遠勝于語法級別的優化」,比如將每一個字串拼接改成用StringBuilder來實作,大多數情況下帶來的成果其實很小,甚至在某些情況下還不如不改,
所以,我們最好還是能夠借助一些客觀資料,以獲得更多的運行環境相關的資訊,來找到整個“木桶”上最短的一塊“板”,如整個系統的總體架構、服務器的資訊等,便于定位到底性能的瓶頸點在哪,

 

「流程上的優化遠勝于語法級別的優化」中的“流程”除了業務流程之外,還包括技術層面的流程,比如資料在網路中的流轉程序,

 

 

/04 著手優化/


最后才是著手優化,

 

做優化的時候需要避免兩個常見的誤區,

 

第一,不要過度追求應用的單機性能,如果單機表現良好,還應該從整體的角度去思考,

 

第二,要過度追求單一維度上的極致優化,比如過度追求 CPU 的性能而忽略了記憶體方面的瓶頸,

 

 

正確的思路一般符合下面兩個方向,

 

第一,空間換性能,一個節點頂不住就多復制一個節點出來,獨一份的資料導致資源競爭得厲害,就多復制一份資料出來,

 

第二,距離換性能,資料從服務端經過層層處理回傳到客戶端覺得慢的話,那么能不能直接保存在客戶端,或者至少是離客戶端盡可能近的地方,

 

好了,思路清楚了,具體在做的時候我建議你根據下面小標題的順序進行,不管是主動地性能優化,還是被動地排查性能問題都一樣,

 

 

/01 應用程式層面/

 

不管你愿不愿意承認,現實中的大部分性能問題皆是應用程式自身部分的代碼導致的,
我們總是不太愿意承認自己的錯誤,我見過太多程式員總是習慣性的將問題先歸結于硬體問題,網路問題等等,然后最終排查下來的根源往往還是在coding的應用程式上,

 

所以,我們更應該先從應用程式本身入手進行分析,而且,應用程式所處的位置更「上游」,可操作性更強,讓我們可以有更多的手段進行優化

 


01  快取

 

首先,最常見的便是「快取」,這是用空間換性能的經典,

 

資料必然是存盤在非易失性的資料庫中的,但是一些會被高頻訪問的資料,將它從資料庫中復制一份,存盤在易失性的記憶體上做快取,可以大大提高被訪問的性能,這個道理大家都懂,就不多說了,

 

但是值得提醒的一點是,快取資料的資料結構設計很重要,沒有一種資料結構是萬能的,需要更多的權衡,因為資料結構設計的越簡單、單一,快取資料的二次運算就越多;反之,所有都存盤「結果資料」的話,需要冗余的資料量又過大(快取資料更新還麻煩),

 

還得提醒一點,如果快取的資料量不小,還得考慮增加一個快取淘汰演算法,否則快取命中率不堪入目,白白浪費大量記憶體資源,

 

之前的《分布式系統系列》中有幾篇快取相關的聊了很多細節,可以在文末跳過去查閱,

 

 

02  異步

 

舉個現實生活中的例子,如果你在手機上點了一杯奶茶,去店里拿的時候發現前面還有20個號,你會在這干等半小時么?

 

我想大部分人都不會吧,寧愿去別的地方溜溜,異步就是通過避免“干等著”來提升性能的手段,

 

做異步主要是以下兩種方式,

 

  • 通過執行緒進行異步,這主要用于涉及到I/O的地方,像磁盤I/O和網路I/O,一旦產生I/O其實就意味著背后的操作是由另外一個程式在進行,此時CPU就不用空著了,讓它忙別的去吧,

     

  • 通過中間件異步,比如MQ,這用于更大的場景里,比如在某些流程中、上下游系統的銜接中,如果有些結果并不需要實時收到,那么通過MQ進行異步就可以大大提高性能,畢竟MQ的性能更接近NoSQL,性能自然比關系型資料庫高的多,更何況,還將一些業務邏輯的預算給滯后了,當下的性能會更好,

 

 


03  多執行緒&分布式

 

這兩點都是「分治」思想的體現,一個快遞員送1000個包裹比較慢,那么讓10個快遞員同時各送100個自然就快了,

 

但是切勿分的太狠,畢竟,多起一個執行緒相當于多一個放養的娃,放出去太多的話,管理成本很高,可能反而會更慢,這就是執行緒切換的成本,分布式系統中也存在類似的管理成本,

 

不過,一個小建議送給你,不到迫不得已,能通過「單機多執行緒」應付的,就不要引入分布式了,因為,網路這個東西實在太不靠譜了,你得為它做大量的額外作業,

 

 

04  延后運算

 

這個和快取的思路相反,將一些運算盡可能的延后到用的時候,適用的場景也和快取相反,適用于一些低頻的、運算耗時的資料上,

 

延遲加載、插件化等等就是該思想的體現,

 

 

05  批量,合并

 

如果你需要在短時間內頻繁的傳遞多個資料給同一個目的地,那么盡量考慮將他們打包到一起,一次性傳輸,特別是涉及到I/O的場景,

 

如果手頭的系統還是一個單點系統,這招的性價比就非常高,在避開分布式系統的復雜性的前提下,獲得性能提升,

 

資料庫的bulk操作,前端的sprite圖,都是該思想的體現,

 

 

應用程式層面的其它優化方式還有很多,比如,用長鏈接代替頻繁打開關閉的短鏈接、壓縮、重用等等,這些相對比較簡單和好理解,就不多說了,

 

應用程式層面的事情做到位了之后,我們再來考慮組件層面的優化,

 

 

/02 組件層面/

 

組件是指那些非業務性的東西,比如一些中間件、資料庫、運行時的環境(JVM、WebServer)等,

 

資料庫的調優,總的來說分為以下三部分:

 

  • SQL陳述句,

  • 索引,

  • 連接池,


其它的一些,比如JVM的調優最主要的就是對「GC」相關的配置調優,WebServer的調優主要是針對「連接」相關的調優,這些細節就不贅述了,資料多到看不過來,

 

/03 系統層面/

 

系統層面的一些調優作業,涉及到運維工程師的一些作業,我不是很擅長就不誤人子弟了,但是我們可以借助系統層面的一些技術指標來觀測并判斷我們的程式是否正常,比如,CPU、執行緒、網路、磁盤、記憶體,

 

 

01  CPU

 

判斷CPU是否正常,大多數情況下關注這三個指標就夠了,CPU利用率、CPU平均負載、CPU背景關系切換,CPU利用率大家基本上都知道,就不多說了,那就說說后面兩個,

 

關注CPU平均負載的時候,特別需要注意趨勢的變化,如果 1 分鐘/5 分鐘/15 分鐘的三個值相差不大,那說明系統負載很平穩,則不用關注,如果這三個值逐漸降低,說明負載在漸漸升高,需要排查具體的原因,

 

CPU背景關系切換,背景關系切換的次數越多,就意味著更多的CPU時間消耗在暫存器、內核堆疊以及虛擬記憶體等資料的保存和恢復上,真正進行你所期望的運算作業的時間就越少,系統的整體性能自然就會下降,導致這個情況的原因主要有兩點,

 

  1. 程式內的磁盤I/O、網路I/O比較多,

     

     

  2. 程式內啟動的執行緒過多,

 


02  執行緒

 

執行緒方面除了關注執行緒數之外,還需要關注一下處于「掛起」狀態的執行緒數量有多少,

 

掛起狀態的執行緒數過多,意味著程式里鎖競爭激烈,需要考慮通過其它的方案來縮小鎖的粒度、級別,甚至是避免用鎖,

 

 

03  網路

 

通常在硬體層面內網帶寬會遠大于外網的帶寬,所以,外網帶寬被吃滿的情況更加常見,特別是多圖、多流媒體型別的可對外訪問系統,關于流量大小相關的問題一般大家都能想到,就不多說了,

 

但是,Z哥提醒你要特別關注埠的使用和每個埠上的連接狀態情況,比較常見的問題是,連接用完有沒有及時釋放,導致埠被占滿,后續新的網路請求無法建立連接通道,(可以通過netstat、ss獲取網路相關的資訊,)

 

 

 04  磁盤

 

除非是規模非常大的系統,否則一般情況下,從磁盤的指標上看不出啥問題,
平時看的時候,除了看看利用率、吞吐量和請求數量之外,有兩個容易被忽略的點可以多關注下,

 

第一點,如果I/O利用率很高,但是吞吐量很小,則意味著存在較多的磁盤隨機讀寫,最好把隨機讀寫優化成順序讀寫,(可以通過 strace 或者 blktrace 觀察 I/O 是否連續判斷是否是順序的讀寫行為)

 

其次,如果I/O等待佇列的長度比較大,則該磁盤存在 I/O 性能問題,一般來說,如果佇列長度持續超過2就可以這么認為,

 

 

05  記憶體

 

關注記憶體的時候除了記憶體消耗之外,有一個Swap換入和換出的記憶體大小需要特別注意一下,因為Swap需要讀寫磁盤,所以性能不是很高,如果GC的時候遍歷到的物件恰巧被Swap 出去了,便會有磁盤I/O產生,性能自然會下降,所以這個指標不應該太高,

 

大多數記憶體問題,都和物件常駐記憶體不及時釋放有關,有很多工具可以觀察物件的記憶體分配情況,如,jmap、VisualVM、heap dump等,

 

 

如果你的程式部署在linux系統上的話,不得不錯過Brendan Gregg的大神整理的精華,下面就參考一張圖,給大家感受一下,具體可以去 http://www.brendangregg.com/linuxperf.html 自行查閱更多相關的內容,

 

▲圖片來自于brendangregg.com

 

最后,雖然性能優化是一件大家都知道的好事,但是再好的事做起來都有成本,所以,如非必要,不要過早、過度進行性能優化哦,

 

 

好了,總結一下,

 

這篇呢,Z哥和你聊了一下非常讓程式員們頭疼的程式性能問題,想要避免受這個問題困擾的前提是事前做好性能優化作業,

 

做性能優化不能走一步算一步,事先需要做三件事「明確優化目的」、「定標準」、「找到瓶頸點」

 

具體做優化的時候建議從應用程式層面開始,再到組件層面,最后才是系統層面,從上往下,層層深入,順帶分享了每個層面的常用一些方法和思路,

 

希望對你有所啟發,

 

 

在一個大系統中,資料就像水,整個系統就像是一個漏斗,漏斗的每一層代表每個子程式,上層的子程式對性能的損耗越低,能流下去的水就越多,直到最后一層「資料庫」處,也可以理解為是存盤,


所以,趕緊行動起來,開啟保衛資料庫之戰吧,

 

 

推薦閱讀:

  • 8個月打磨,一份送給程式員的「分布式系統」合集

  • 做「容量預估」可沒有true和false

 

作者:Zachary

出處:https://zacharyfan.com/archives/1051.html

 

 


 

如果你喜歡這篇文章,可以點一下右下角的「推薦」, 

這樣可以給我一點反饋,: )

謝謝你的舉手之勞,

 

既然看到這了,送我一個「贊同」吧,支持我的創作,

想更進一步和我一起玩耍,歡迎「搜索微信公號:跨界架構師」或者在「右側掃描」,

內容包括:架構設計丨分布式系統丨產品丨運營丨個人深度思考,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/95230.html

標籤:其他

上一篇:shell攜帶附件,Linux下的自解壓檔案誕生了

下一篇:850. Dijkstra求最短路 II(堆優化模板)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more