寫在前面1:
部分是我沒接觸過但是聽說的,絕大部分是我個人遇到的并且解決的,還有一部分是看的其他人寫的感覺之后能用到的.如果有看到錯誤的地方逆日,希望能指明嵌巷,感激不盡
寫在前面2
這篇是個人在工作了兩年多之后的一些開發(fā)感悟。有關(guān)于工具使用的室抽,有關(guān)于引擎使用的搪哪,有關(guān)于
每個人都有各自不同的開發(fā)特點,但是我這篇所說的能囊括大部分的通用技巧坪圾。希望大家在開發(fā)過程中能去粗取精晓折,合理應用。
寫在前面3:
上一家的公司雖然只有兩三個開發(fā)兽泄,但是無論是在工具的使用上漓概,還是代碼的開發(fā)整潔程度抑或是辦事效率以及解決問題的效率都是我迄今為止遇到的最先進的。而新進的公司是一家大公司病梢,雖然開發(fā)人員很多胃珍,但是和上一家小公司比起來對代碼框架的使用以及業(yè)務(wù)的開發(fā)還有辦事效率上,都是一坨狗屎蜓陌。也因此產(chǎn)生了寫這篇的沖動觅彰。
1. 代碼風格:
(1)如果是剛畢業(yè)的實習生,最好有事沒事讀一下代碼命名規(guī)則方面的書钮热。記住了填抬,代碼是給人看的,然后才是給機器看的(當然使用匯編語言或者更底層語言的可以忽略)隧期,所以首先要保證你的函數(shù)
飒责、成員變量
、類型名稱
仆潮、命名空間
要能簡介易看懂宏蛉,如果無法做到簡潔明了,那么就選擇寫注釋鸵闪,要去寫明這個名稱所代表的意義以及方法所要做的事情的簡述。
(2)如果使用C++暑诸、C#等使用強類型語言開發(fā)程序蚌讼,那么大家肯定使用的是Virsual Studio(裝逼的也不會看這種文章),所以在寫完之后最好 Ctrl+K,D
整理一下代碼个榕,使其符合VS的排版規(guī)則篡石。用什么語言就要像什么語言(比如在Java/JavaScript/TypeScript中,方法后面的左括號不用換行西采,這是人家Java的排版規(guī)則)凰萨,但是一旦你使用C系列語言進行開發(fā),那么請一定換行,不要覺著無所謂胖眷,Python的創(chuàng)始人嫌棄人家的括號才讓Python面世武通,但是我不覺得大部分資深程序員覺著這是個好的想法。括號的作用是為了讓代碼塊狀化珊搀,也就是為了更清晰冶忱,Python 雖然有 def
和空格配合,但是誰用誰知道境析。當然現(xiàn)在的VS Code很方便囚枪。
(3)在字符串的使用上,如果是常量劳淆,能不能將其歸到單獨的靜態(tài)類或者寫成靜態(tài)變量链沼,最好再加上限定符(比如const[編譯時常量C++/C#中都有]
, readonly [運行時常量僅在C#中]
)。不要再代碼中到處留種沛鸵,看上去像大姨媽一樣括勺。我是一個有超級強迫癥的人,絕對看不慣一片紅的這種代碼存在(當然有人改變了編輯器的主題就另說)谒臼。
(4)不要在代碼中使用各種魔術(shù)數(shù)朝刊,所謂魔術(shù)數(shù)就是指不知道上下文還不知道這個數(shù)值代表的啥意思的數(shù)值,如果有大量的代碼中用到同一個意思的數(shù)值蜈缤,最好創(chuàng)建個成員變量或者局部變量拾氓,創(chuàng)建方式同字符串的方式。如果代碼從頭到尾都是你一人開發(fā)一人維護底哥,那你也要考慮將來你不維護了別人也要能看得到咙鞍。做人留一線,免得被鞭尸趾徽。
(5)設(shè)計層面一定要遵循一個類只保留與這個類相關(guān)的方法和變量(這個也決定于你使用的什么設(shè)計模式续滋,以及開發(fā)方式,所以仁者見仁智者見智吧)孵奶,一個方法只做一件事疲酌,這個是慢慢培養(yǎng)起來的習慣,這個習慣養(yǎng)成之后了袁,你會發(fā)現(xiàn)寫代碼朗恳,查BUG真的很爽。
2. 其他雜七雜八整合:
Unity
-- Unity運行時庫是定制版的Mono载绿,只和.net framework在一定程度上兼容粥诫,參考Unity3D引擎簡介
-- Unity3D 不要多人同時修改Unity中的場景文件,一旦沖突將很難合并
-- Unity3D中的資源引用是靠和文件名相同的meta文件來實現(xiàn)的崭庸,只有用到的文件才會打包到最終的產(chǎn)品中怀浆。但所有Resources目錄中的資源(包括子目錄中的Resources目錄)都會不分青紅皂白的全部打包到最終產(chǎn)品谊囚,以供Resouces.Load這樣的接口通過路徑來在運行時動態(tài)加載。所有沒有運行時動態(tài)加載需求的資源都不要放到Resouces目錄中
-- Unity中的Invoke不能調(diào)用自己所在的方法
void test()
{
Invoke("test",1);
}
替換為:
void test()
{
Invoke("test1",1);
}
void test1()
{
test();
}
-- Unity修改好腳本之后最好用Ctrl+Shift+B編譯一下执赡,有時候就算是save但運行的還是原來的邏輯
-- Unity工程里面文件路徑的'/'和''有區(qū)別镰踏,加載文件的路徑是/,創(chuàng)建文件最后是用'',用Path.Combine拼接創(chuàng)建文件的路徑是''
-- Unity 在Windows環(huán)境下大小寫不敏感搀玖,截取字符串要注意
-- Unity里面Resources.Load加載prefab的時候不能包含文件的擴展名
-- Unity中不要用Debug.LogError打印普通日志
-- 采用PrefabLoader加載預設(shè)余境,設(shè)置父節(jié)點時,預設(shè)中所有子節(jié)點的Depth會自動適配灌诅,但是active=false的節(jié)點芳来,不會自適應。
-- Unity重命名腳本導致掛載其預設(shè)腳本丟失問題猜拾,將腳本從預設(shè)上卸載保存即舌,重命名腳本保存后再掛上去,再從預設(shè)上卸載該腳本保存挎袜,再將該腳本重命名回去顽聂,再重新掛到預設(shè)上去;
-- Unity5的運行時在解析utf-8編碼的xml時會把前面的BOM直接當文本解析而報錯盯仪,此時應采用無BOM版本的utf-8編碼
-- Unity3D性能優(yōu)化:DrawCall優(yōu)化
-- Unity設(shè)置自定義RBG顏色是0-1
的float
值
-- Unity粒子中的IsAlive(withChildren = true)
會對下級gameObject
進行遍歷并且遞歸結(jié)束之后又對返回列表做一次元素復制List.ToArray()
,然后再以transform.gameObject.GetComponent<>()
紊搪,而不是transform.GetComponent<>()
來獲取子級組件,在Update
中使用極其消耗性能全景,有實驗對一個帶2個子ParticleSystem
共3個ParticleSystem
組件的游戲?qū)ο筮M行IsAlive(true)
判斷810241024次用時為3900ms耀石,而單獨取出判斷僅為65ms.好的解決辦法是對所有的particlesystem
建一個鏈表進行統(tǒng)一的處理;次一些的方法是對該粒子的帶particlesystem
的祖先對象建一個鏈表進行處理爸黄,然后以IsAlive(false)
進行判斷滞伟,當它死亡時認為其次級粒子也應全部死亡
-- NGUI中多個Grid或Table組件嵌套著并且動態(tài)更新節(jié)點時掏愁,不能在同一個渲染幀更新养涮,這會引起位置錯誤讽坏,應該從子組件往父組件逐幀更新
-- JSON .NET For Unity具有比JsonFx For Unity3D更好的平臺兼容性
-- Unity Native2D中的Collider點選射線是從屏幕點擊點開始的一條直線组民,而3D Collider中的點選射線是從攝像機發(fā)出的射線
-- Unity在Animator里面只有一個動畫的情況,如果想要重復播放這個動畫需要添加一個空白動畫與該動畫銜接起來嫡良,這樣每次調(diào)用播放動畫的時候可以從頭開始播放搓侄,因為Animator會記錄當前動畫的狀態(tài)牲剃,如果不切換動畫狀態(tài)就會出現(xiàn)動畫一直停留在該狀態(tài)的最后一幀
-- Unity GetComponent是一個比較消耗時間的操作鳖轰,對于頻繁調(diào)用的地方清酥,應該在Start方法中獲取并緩存,否則可能會造成嚴重的性能損傷
Lua/Cocos
-- lua中table.sort要求table的下標從1開始且連續(xù)脆霎,否則會報錯
-- cocos lua中的json解析器對"/"這樣的字符串轉(zhuǎn)義無法正常識別总处。
-- cocos android編譯報錯時狈惫,可考慮刪除proj.android/obj目錄修復
Android NDK: WARNING:D:\gxtime\code4\appbuilder\gcmd\cocos2d-x/cocos2dx/Android.mk:cocos2dx_static: LOCAL_LDLIBS is always ignored for static libraries
make.exe: Entering directory `D:/gxtime/code4/appbuilder/gcmd/cocos2d-x/projects/zlsg/proj.android'
make.exe: *** No rule to make target `D:\gxtime\code4\gamecmd\gcmd\cocos2d-x/projects/zlsg/Classes/AppDelegate.cpp', needed by `obj/local/armeabi/objs-debug/zlsg_logic/Classes/AppDelegate.o'. Stop.
-- cocos Android編譯如果出現(xiàn)如下報錯睛蛛,請確保Resources目錄下沒有中文目錄或文件:
BUILD FAILED
C:\android\sdk\tools\ant\build.xml:932: The following error occurred while executing this line:
C:\android\sdk\tools\ant\build.xml:950: null returned: 1
-- cocos中可采用CCDirector:sharedDirector():getScheduler():setTimeScale(2)
整體加快游戲時鐘速度
-- cocos的音量控制鹦马,在Android系統(tǒng)上正常。在pc和wp上忆肾,只有0/1的區(qū)別荸频,沒有音量大小的區(qū)別。音量函數(shù):引擎底層客冈,setBackgroundMusicVolume()旭从;需要自己封裝。
-- Android平臺不支持路徑中的""
-- cocos中的FreeType字體如果加載不正常场仲,可以先用其他字體替代檢測和悦,有可能是字體文件本身和cocos不兼容
-- cocos不支持按鈕長按時間,需要通過定時器手工檢測觸發(fā)
-- cocos.splitUTF8返回utf8字串的字(英文或者中文)個數(shù)渠缕,并返回每個字列表鸽素,返回相對英文的個數(shù)(中文算兩個英文)
-- 實現(xiàn)cocos用的富文本排版算法/控件cocos.formatOneLine
-- cocos在Windows和Android上會啟用luajit,如果發(fā)現(xiàn)一些邊緣性的lua特性有差異可能與此相關(guān)
-- 使用cocos制作時亦鳞,界面顯示的CCLayer和界面上堆積的CCNode最好是建立父子關(guān)系馍忽,這樣不管是在模擬器還是在手機上都不會出現(xiàn)位置偏移
-- cocos跨平臺游戲需要注意cocos線程
和主UI線程
以及平臺線程
之間的沖突,否則會出現(xiàn)莫名其妙的Crash
-- cocos中ScrollView是以左下角為原點排版的
-- cocos多個Action同時運行最好能保證相互正交
-- cocos使用replaceScene()
替換場景后燕差,在同一幀內(nèi)使用getRunningScene()
獲取到的還是老場景遭笋。 解決方法: 1. 將新場景傳出去。 2. 使用CCDirector::mainLoop()
強制刷新一幀
-- lua里面的require一定要寫全路徑(獲取路徑+相對路徑)徒探,否則在非devmode下加載會出問題
-- lua中創(chuàng)建cocos中的結(jié)構(gòu)體后瓦呼,需要手工釋放,否則會有內(nèi)存泄漏刹帕。比如ccp
-- lua中謹慎使用new
吵血,否則必須手工采用release
以避免內(nèi)存泄漏;推薦使用new_local
偷溺,lua會自動處理回收蹋辅。
-- lua中謹慎使用retain,否則很難保證C++對象被正確的release挫掏,會造成內(nèi)存泄漏
-- lua是為單線程設(shè)計的侦另,多線程訪問lua虛擬機需要加鎖。開多個lua虛擬機會造成過多的資源損耗尉共,另外不同虛擬機之間如何通信也是一個復雜的問題褒傅。
-- tolua++使用時,盡量將C++類的析構(gòu)函數(shù)導出給lua袄友,以避免被作為原生內(nèi)存暴力free殿托,而未調(diào)用析構(gòu)函數(shù)。傳送門
-- lua的變量插入符剧蚣。在字符串中加入支竹,可以將其后的一個英文單詞解釋成變量旋廷。使用string.gsub()函數(shù)替換變量,并返回替換后的字符串礼搁。 如:
local from = "我想做一個$goodman饶碘,請$leave我。"
local t =
{
goodman = "好人",
leave = "放過"
}
local to = string.gsub(from馒吴,"%$(%w+)"扎运,t)
print(to)
-> 我想做一個好人,請放過我
-- lua中除法運算時除數(shù)為0饮戳,運算結(jié)果的值為NaN
-- lua數(shù)組索引的時候注意存的時候存的是數(shù)字還是字符串數(shù)字
-- lua require一個腳本文件script.lua
后package.loaded["script"]
會被設(shè)置一個非nil
值豪治,如果script.lua
以module
封裝過,package.loaded["ScriptModule"]
也會被設(shè)置一個非nil
值扯罐,那么腳本文件script.lua
已經(jīng)require過了想重新require鬼吵,就需要設(shè)置package.loaded["script"] = nil
以及package.loaded["ScriptModule"] = nil
-- lua遍歷,如果很清楚目標容器是致密數(shù)組篮赢,就用ipairs齿椅,而不是pairs。一方面是性能問題启泣,另外也是在明示所用容器的類型涣脚。而且這個在后期調(diào)整會比較難,需要根據(jù)代碼去仔細推敲類型寥茫,建議編碼時就明確搞定
-- lua里#(T)
和table.getn(T)
等價遣蚀,得到的是數(shù)組中元素的數(shù)量,所謂數(shù)組意味著key值從1開始的連續(xù)性數(shù)據(jù)結(jié)構(gòu)纱耻,而T={[2]=1}
這樣的結(jié)構(gòu)在使用table.getn(T)
時芭梯,得到的值只能是0
-- lua math.random(0)
會crash
,math.random(float)
的用法也會有問題
-- lua中一定要注意標識符的正確拼寫
-- lua代碼要比C++更嚴格的控制編碼風格和代碼質(zhì)量
-- lua中l(wèi)ocal函數(shù)調(diào)用應該在定義之后弄喘,可通過提前聲明一個變量解決玖喘,module函數(shù)不受此限制。lua的解析上是完全的流模型蘑志。所謂的解釋型語言的稱呼在這兒得到了很好的詮釋
-- lua中的函數(shù)可以通過閉包傳遞額外的參數(shù)
-- utf-8的中文字占三個字節(jié)累奈,luastring.sub截斷中文時要注意,截取不對時Windows上和Android上都會報錯急但,但是由于BMFont(cocos)在兩個平臺上的實現(xiàn)不一樣澎媒,所以錯誤的表現(xiàn)會不一樣
-- HttpRequest:new之后應該及時進行release以避免內(nèi)存泄漏,參考
-- Visual Leak Detector是VC下非常不錯的內(nèi)存泄漏檢測工具
Python
-- Python對空白敏感波桩〗渑縮進時,空格和tab不能混用镐躲。
C#(讀Sharp)
-- C# string.Format格式化的時需要對{和}進行轉(zhuǎn)義
-- C#中的容器都是引用類型储玫,和C++ STL中的值類型容器是不一樣的冬三,傳參的時候不會有拷貝性能損傷
-- C++/Unity中的C#采用Pascal的命名規(guī)則,js/TypeScript采用camel的命名規(guī)則
-- C#中enum不要當成int的用缘缚,enum本身是專有的類型,和C/C++中的區(qū)別很大
-- if (npc == null) return;
類似的判空不要放在一行敌蚜,視覺不敏感桥滨,并且無法打斷點
-- 《The Swift Programming Language》中文版;和C#語言很像
C++
-- C++中的對象弛车,不能直接用memcpy的方式進行序列化齐媒。只有C struct的POD類型才可采用memcpy的方式“序列化”
-- C#會默認對所有字段進行初始化,這個和C/C++有重大區(qū)別
-- 不要在C++頭文件中采用using namespace ...
纷跛,這會引起全局namespace
污染
-- nullptr可以作為std::function的默認值喻括,operator== as default value for std::function
-- C++中的const修飾對復雜代碼的理解和維護很有幫助
Type Script/Egret
-- Egret中為了避免resource.json資源文件沖突,請務(wù)必在修改資源前pull贫奠,修改之后立刻push
-- TS類的成員函數(shù)中使用this指針并不總是能夠取到類本身唬血,有時取到的是該成員函數(shù)本身
-- Egret模板定義的json中,ts文件的順序標明依賴關(guān)系
-- Egret添加新資源(圖唤崭,特效拷恨,字體,聲音)后谢肾,都要清除瀏覽器緩存腕侄,否則資源無法正常加載
-- Egret中很多情況下確認程序沒有問題但運行總報錯,就清理一下IE的緩存芦疏,特別是涉及渲染的時候
-- 在Egret/egretProperties.json中增加新的模塊時冕杠,注意文件路徑不能直接從windows目錄直接拷貝否則本應是"/"粘過來的目錄是""會導致引擎編譯失敗
-- 新導入字體文件時,要更改Egret/web.config文件增加<mimeMap fileExtension=".fnt" mimeType="text/plain" />否則引擎無法正常識別font類型文件
-- Egret引擎的TextureMerger默認勾選切除透明邊界酸茴,這個可能導致合圖后的幀動畫中心點偏移
-- Egret性能優(yōu)化
-- TypeScript得到類名稱的方法在代碼混淆后會將方法作為字符串返回分预,而不是方法執(zhí)行后的結(jié)果。 方法:
private getClassName():string {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec(this["constructor"].toString());
return (results && results.length > 1) ? results[1] : "";
}
-- js的pretty-print工具: js-beautify
Git (管理工具)使用總結(jié)
-- git一定要把autocrlf和safecrlf都設(shè)置為false薪捍,坑爹的設(shè)計會讓同一個文件在不同的機器上有不同的MD5碼
-- git一次commit/push最好不要超過G的級別噪舀,否則工具支持可能會有問題
-- git的子樹合并
-- git merge時如果有沖突,不要在解決沖突后只提交“屬于自己的部分“飘诗,否則其他人的代碼就會被覆蓋丟失
-- git配置必須用Git Bash生成ssh的key与倡;必須采用ssh的終端而不是默認的認證方式; 需要設(shè)置環(huán)境變量HOME
=用戶文件夾根目錄
-- 在cmd命令行中用生成ssh key昆稿,發(fā)現(xiàn)git的用戶文件目錄和命令行開頭顯示的不一樣時纺座,就用git bash操作
-- git/svn提交日志,請確保足夠的人類可讀性
-- 游戲發(fā)布后如果有多個分支溉潭。改bug的時候如果只在分支改就是給自己埋坑
-- 在代碼/提交記錄中最好采用真實的身份標識净响,包括:姓名少欺、email等
工作總結(jié)和感悟
-- 代碼表格在提交前自己測一下,不要出現(xiàn)太明顯的bug馋贤。
-- 要善用電話赞别,緊急
的事情不要靠打字解決,節(jié)奏配乓、溝通質(zhì)量和對應對此事的重視程度都會打折扣仿滔。
-- 對同一概念、同一物品犹芹,溝通時叫法要統(tǒng)一崎页。如果是大型項目一定一定一定要寫文檔,并且隨時維護腰埂,當然維護這個文檔可能會很費時間飒焦,也可能會忘掉,但是想起來的時候一定要去同步相關(guān)的修改屿笼,否則等項目開發(fā)開發(fā)到一定程度之后牺荠,你會發(fā)現(xiàn)末日降臨了。
-- 對待變量命名驴一、編碼風格志电、代碼組織一定要嚴肅嚴謹,這樣才能在做重構(gòu)蛔趴、設(shè)計挑辆、架構(gòu)時也保持嚴肅和嚴謹?shù)膽B(tài)度
-- 有意義的消息是最終把游戲邏輯串起來的關(guān)鍵。建議消息定義時孝情、客戶端/服務(wù)器消息處理時都加上必要的注釋鱼蝉,方便維護。
-- 復現(xiàn)步驟復雜的bug箫荡,要嘗試搭建能快速復現(xiàn)的腳手架魁亦。bug的快速穩(wěn)定反復復現(xiàn)對于解決問題非常關(guān)鍵
-- 開發(fā)過程中,主干負責游戲本身相關(guān)的功能線羔挡。所有和游戲主體無關(guān)的洁奈,非平臺中立的內(nèi)容均不應該在主干中開發(fā),比如支付绞灼、廣告或者某具體平臺/運營商相關(guān)的功能玩法特化利术。分支開發(fā)的過程中,發(fā)現(xiàn)游戲本身的bug低矮,修復后需要及時將該條修改合并(cherry pick)到主干印叁。這樣后面再有新產(chǎn)品的發(fā)布時就不會踩同樣的坑了。
-- 文件名是一件非常嚴肅的事情,包括空格轮蜕、大小寫及其命名規(guī)則
-- 復雜的操作流程最好有記錄昨悼,只是看別人操作一遍很容易隨后忘記
-- 對于按照文件名和路徑作為資源引用的引擎,第一次把資源加入到游戲中時跃洛,一定要特別注意整理好文件名
-- 注釋在寫的時候需要注重實用性率触,不要講廢話
-- 盡量不要敲代碼到很晚,睡前敲代碼影響睡眠
-- 問題想不明白就先緩緩汇竭,比如喝個茶或者咖啡或者開個小差
-- 使用移位操作描述狀態(tài)時葱蝗,要注意移位操作的可擴展性,避免溢出
-- 如非必要韩玩,謹慎采用bit位去表示數(shù)據(jù),復雜的移位計算容易引起混亂
-- 所有的文件擴展名均采用小寫陆馁,從美術(shù)接手資源時需要留意
-- 建議在每個文件/類前面添加簡單的描述信息或關(guān)鍵字找颓,這對于通過搜索來維護非常重要,特別是應用層的邏輯模塊或者界面
-- 在接手/介入新功能開發(fā)點時叮贩,切記不要從第一行代碼開始通讀击狮,要以要解決的問題為主線去看。只了解應該了解的信息量益老,但同時要能有效的解決問題彪蓬。
-- 考慮“短路”寫法,把大量的前件預先處理捺萌,可以讓代碼實現(xiàn)邏輯更清晰档冬,并能有效縮減代碼嵌套深度.例如:
void Func()
{
if(a == true)
if(b== true)
ExcuteFunc()
}
可簡化為
void Func()
{
if(a == false)
return;
if(b == false)
return;
ExcuteFunc();
}
-- 函數(shù)大量的傳出參數(shù)可能在暗示設(shè)計問題,除非必須這么用桃纯,否則違反直覺和思維習慣酷誓。函數(shù)的返回值是很好的通用數(shù)據(jù)返回渠道,如果有多個返回值态坦,可以考慮Tuple (元組) 的方式盐数。
-- 在復雜度適當?shù)那闆r下,盡量采用字符串格式化而不是拼接伞梯,有利于維護和后期的國際化玫氢,無論哪種語言.例如:
var dialogInfo = "是否花費" + info.price + "銀幣購買" + info.ownername + "的" + tableInfo.strName + "?";
更好的寫法:
var dialogInfo = string.Format("是否花費{0}銀幣購買{1}的{2}?", info.price, info.ownername, tableInfo.strName);
-- 函數(shù)之間、類之間最好添加一行空白谜诫,單行可實現(xiàn)的函數(shù)和屬性除外
-- 在開發(fā)過程中盡量避免錯別字漾峡,尤其是客戶端要顯示的文字,這會給玩家?guī)砗懿缓玫挠∠?br>
-- 主干永遠只有游戲本體相關(guān)的東西喻旷,任何于此無關(guān)的都不應該出現(xiàn)在主干灰殴。特定平臺的功能剪裁和定制,特殊的優(yōu)化,如紋理壓縮等都應該在對應的分支
-- 不要因為當前只有一個平臺就覺得在主干上直接嵌入方便牺陶,隨后當?shù)诙€平臺驚喜出現(xiàn)的時候的時候大家就笑了伟阔,又開始各種屏蔽剪裁了
-- 除非特定語言要求必須用空格縮進,否則一般采用tab4縮進
-- 任何一條不必要的輸出信息都可能讓更有效的信息淹沒
-- 日志中不要有廢話掰伸,過期并且無實際意義的日志請及時刪除
;僅僅是個人相關(guān)的臨時調(diào)試日志皱炉,不要提交
-- 關(guān)于技術(shù)的討論,我們應該秉持求同存異的原則狮鸭,目的只是尋求一個合適的解決方案而不是征服一個人的觀點
-- 解決問題應該從問題直觀來源切入合搅,不要妄自揣測,用代碼和邏輯說話歧蕉,顯示上面的問題就先從UI顯示層切入邏輯數(shù)據(jù)問題就從服務(wù)器端切入灾部,這樣可以大大提高解決問題的效率以及減少很多不必要的工作;什么是對什么是錯一定要去證明,否則就是給自的己埋坑惯退。到真正的問題出現(xiàn)的時候赌髓,你就要哭了〈吖颍或者會導致按下葫蘆浮起瓢
-- 工具锁蠕、腳本等研發(fā)輔助系統(tǒng),應該保持默認狀態(tài)就是可用的懊蒸,而不需要先進行大量的配置才能跑起來荣倾。合理精細的默認值設(shè)置,會改善系統(tǒng)的友好度
-- 應該仔細規(guī)劃開發(fā)步驟和提交內(nèi)容骑丸,必須保證倉庫上的版本是可用的舌仍,即使是很大的改動,否則團隊配合會有問題
-- 代碼中盡量不要使用o, l
這樣容易和數(shù)字0, 1
混淆的標識符
-- 不要在代碼中賣萌通危,尤其是可能展示給用戶的提示文字抡笼、日志等,遲早會尷尬的
-- 一定要嚴格的尊重美術(shù)的效果圖和設(shè)計黄鳍,在UI用戶體驗細節(jié)上要高度還原推姻。這里的細節(jié)問題,更多的說明了我們程序?qū)Υ约嚎蚬担瑢Υa(chǎn)品藏古,對待客戶的專業(yè)態(tài)度
-- 代碼是團隊共同所有的。不要忌諱別人改自己的代碼忍燥,也要勇敢的去改別人的代碼拧晕。隨著時間的推移和需求的改變,代碼的調(diào)整是客觀的
-- 程序一定要尊重策劃/美術(shù)的設(shè)計梅垄,要盡最大可能去還原原始設(shè)計厂捞,關(guān)于產(chǎn)品設(shè)計方面,程序不能太強勢
-- 確定過期的代碼請及時刪除,不要在源碼文件中留下大量注釋掉的代碼靡馁,要合理利用版本管理工具
-- 重要的問題在群里溝通欲鹏,盡量避免私聊。防止重復溝通和可能的誤解
-- 事不過三臭墨,過三則重構(gòu)赔嚎。重復的流程性的工作,要善用工具來解決
-- 界面和界面邏輯之間的耦合盡量少用字符串胧弛,編譯器的強類型限制是很好的安全保障
-- 開發(fā)過程中應該及時刪除廢棄的代碼和資源尤误,資源可以備份在其他位置
-- GooglePlay上有侵權(quán)嫌疑的產(chǎn)品,最好是每個賬戶單獨上结缚,這些賬戶之間不要有任何可察覺的關(guān)聯(lián)损晤,比如收款的銀行卡號,注冊的信用卡號红竭,甚至注冊時候的IP地址……尤勋,否則查封的時候是群封。賬號封停后德崭,未結(jié)余款到期后會正常結(jié)算的斥黑。GooglePlay一般違規(guī)三次賬號是肯定會被封的揖盘。上有內(nèi)購的產(chǎn)品眉厨,最好接第三方支付,一旦賬號被封兽狭,至少還有些渣渣能撿憾股。當然接第三方支付本身就是違反GooglePlay規(guī)定的,在產(chǎn)品的FaceBook主頁引導玩家游戲外重置的也是違規(guī)的箕慧。換賬號后服球,新游戲包傳上去后,原賬號下的產(chǎn)品用戶是可以強更到新版本的颠焦。GooglePlay總體在審核上比蘋果松斩熊。
-- 盡量不在代碼中寫死IP,盡量使用域名伐庭,并用單獨的配置文件以方便部署和運維
-- 注釋的正確寫法://
后面一定要加一個空格
-- 程序觀點下的線性代數(shù)
-- C的數(shù)學庫函數(shù)
-- 變量粉渠、函數(shù)、文件圾另、類的命名要么就直接用英文單詞霸株,要么漢語全拼音,千萬不要用簡寫或者少寫一個字母這種失誤出現(xiàn)集乔,一旦在開發(fā)過程中發(fā)現(xiàn)了就立馬糾正去件,不要得過且過
性能優(yōu)化/代碼整理/重構(gòu)
-- 調(diào)整資源加載策略,只加載必須加載的
-- 調(diào)整算法,時間換空間尤溜,空間換時間倔叼。比如緩存和延遲計算等技術(shù)的使用
-- 同步操作可以優(yōu)化為異步的以提高響應
-- 用完后立即釋放短期內(nèi)不會被重復加載的圖片以優(yōu)化內(nèi)存使用
-- 采用合適的atlas拼圖提升圖形渲染效率
-- 盡量減少高級渲染技術(shù)的使用,或用簡單的技術(shù)替代靴跛,可提升幀率
-- 幀率穩(wěn)定比高幀率但不穩(wěn)定要好的多缀雳,人類會很快適應固定長度的延遲。網(wǎng)絡(luò)響應和操作反饋也是相同的原則
-- 實在無法優(yōu)化性能的地方梢睛,就優(yōu)化響應肥印,讓感覺起來很快。比如添加進度條來進行對部分資源的預加載
-- 要通過剖析明確瓶頸所在绝葡,直覺實在是個糟糕的向?qū)罴睿词固貏e熟悉可以代碼的人也不例外
-- 在開發(fā)出可以把全局復雜度降至最低程度的干凈體系之前,關(guān)注性能問題便是過早優(yōu)化——萬惡之源
-- 不要優(yōu)化系統(tǒng)藏畅,而是讓其設(shè)計盡可能的靈活面對改進和擴展敷硅,僅在系統(tǒng)完成之后,再關(guān)注純粹的優(yōu)化
數(shù)據(jù)庫
-- SQL應盡量采用參數(shù)化查詢的方式愉阎,string.foramt會被惡意注入
PS: 有空了接著整理