導航:首頁 > 程序命令 > 程序員一夜未歸

程序員一夜未歸

發布時間:2025-04-29 16:31:50

A. iOS 的封閉性體現在哪裡安卓的開放性又體現在哪裡他們各自的優勢和劣勢是什麼

作者:陳雲浩
鏈接:http://www.hu.com/question/20082440/answer/13918396
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。

IOS:封閉,這樣蘋果可以做到端到端的控制,控制自己的產品和運行在上面的軟體,具有統一的用戶體驗或者質量上有保證。其實這是Jobs對完全開放做的妥協,其實apple本身就不主張開發。這種受控制的開放或者說是封閉,最大的受益者就是apple,對於用戶的益處就是apple一直強大良性循環,只要apple還有創新還在前進,用戶就能得到一如既往好的用戶體驗。其次,其實是副作用,給個人開發者一個有規則的生態環境,所以可以幫一些個人開發者一夜暴富的機會或者少量但穩定的商業機會。
劣勢:不能把生態環境擴展到整個手機行業,一家指定規則,對用戶來說選擇性就小,比如flash就沒有生存的餘地,對於一些先進的技術不能夠吸納,因為商業的原因。如果apple出現問題,沒有其他公司或者合作者來支持其發展,對於iOS的發展只能寄希望於apple的團隊足夠強大,未免讓人擔心。
但是,至今為止apple還沒有出現以上劣勢中出現的情況,可見其發展是勢不可擋。

android:開放,Google把Android定位於開源軟體,大部分代碼以Apache和BSD版本協議發布,在http://source.android.com可以下載到最新代碼。
Android優勢:Android的優勢體現在對於廠商方面,廠商可以拿到代碼隨意定製,廠商可以在Android framework中加入一些自己的特別的功能,同時還能按照BSD或者Apache協議不開源,這樣最大的程度保護了廠商的利益,所以說Android的開源只是google對廠商的,而不是廠商對終端用戶的。尤其在HAL層的處理上,google更是繞過了linux kernel中GPL協議,把驅動寫在HAL層,HAL層大部分都是BSD Apache協議,同時也可以閉源。所以,把linux讓廠商最頭疼的版權問題順利繞過。而且系統還是免費獲取,對於廠商來說價格優勢很明顯,可定製性比其他任何系統都強。
對於終端用戶,集成了google的強大服務系統,如map,gtalk,gmail等讓終端用戶能夠用上最方便的操作系統。最重要 Android market上應用免費,破解相對容易,終端用戶來說更加喜歡更加便宜。

劣勢:
google對開發者和生態系統的維護太差,開發者鮮有在Android Market上賺到錢的,所以Android上的應用基本素質和創新度,發布時間都要比iOS差,造成了部分高端用戶還是選擇iOS。Android系統版本和終端類型極其混亂和復雜,對開發者來說也是有難度的。這樣開發者很難集中精力在軟體的創意和微調上,所以Android程序比iOS程序粗製濫造,這是其中的一個原因。

Android用java作為程序語言,有自己優化了虛擬機 dalvik。本意是招攬更多的java程序員,因為java程序員比較多,但是java語言的特性決定了Android是好硬體大戶,所以即使Android硬體很強大,但是也沒有iOS流暢。

Android上沒有標准,因為太開放了,各個廠商定製界面,同時發布自己sdk就是一個例子,大家都想一家獨大,都想成為標准,內訌這種事情還是有的,所以這也是不利因素。

最後,個人覺得在5年內iOS在手持類設備上還是最好的操作系統,Android在手機行業會在基本飽和之後,被WP7或者別的OS蠶食掉一些,但是是還有數量上的絕對領先。Android最適合的地方是數字家庭或者是各種非手持電子設備,在這個方向Android將會大放異彩。

B. 程序員在職業生涯中易犯的7個錯誤

1.沒有明確的職業目標


沒有目標的人生,就像無根的浮萍,水流到哪裡就飄到哪裡,一生漂泊。


如果你想要在軟體開發領域獲得真正的成功,那麼就必須知道該何去何從。或許面對遙遠的未來,你已經有了一個粗略的目標了。但是除了這點還不夠,你應當堅實自己的目標——清楚的定義在實現過程中的每個重要時間點所需要達到的效果。


我認識許多程序員和其它方面的專業人士,數十年來他們都在相同的職位上反復地做著同樣的事情。是的,你沒有看錯,是數十年。接受職業現狀,不做任何改變,是造成這種悲劇的根源。對於未來,如果你沒有明確的職業規劃,這樣的悲劇就很可能會發生在你身上。


面對於此,你該怎麼做呢?


從現在開始,花一些時間來認真規劃一下職業並確定最近的目標。一旦你達到了這個目標,你就要選擇一個新的目標了。在職業生涯中,這樣的目標會一個接著一個。你可以把這些目標寫下來,放在一個每天都可以看見的地方,這樣就可以讓你隨時回想起當前需要做的工作。


2.不重視「軟技能」或非技術的東西


我認識許多擅長寫代碼的程序員,他們可以用所寫的演算法把我耍得團團轉,他們對復雜架構的理解力和思考能力令我自愧不如。


但是真實的狀況卻是:技術不如他們的我,軟體開發領域的職業發展卻全面超過了他們,除了職位,還包括薪水、生產力等諸多方面。


在這里我並不是為了吹噓自己多了不起,而是為了向那些只埋頭專研技術的程序員們說明「軟技能」對於職業發展有多重要。


作為一個軟體開發者,我相信你也清楚,編寫代碼並不是工作的全部。在通往成功的道路上,還需要學習很多其它技能。我們需要長期與他人打交道,所以必須學習為人處事;軟體開發面臨長期的趕工與不同的需求變化,所以需要學習對心態和注意力的調整;在不斷變化的環境里有許多事情需要處理,所以應當學習對事情劃分優先順序以做到效率的最大化。另外,我們對待身體健康應當和對待自己收入一樣敏感,這個才是革命的本錢。


我還可以繼續列舉出更多的東西,關於了解開發者應當掌握的「軟技能」你可以去閱讀我寫的《SoftSkills:TheSoftwareDeveloper』sManua》一書。


總的來說,在生活中無論從事什麼樣的工作,那些軟技能通常都比硬性的技術能力更為重要,所以請保持不斷地學習這些技能。


3.不融入社區生活


在程序員生涯中有一樣東西令我受益頗深,它就是社區的幫助。成為這個大群體的一部分,不僅讓我擁有了歸屬感不再孤獨,也幫助我改進了自身的技能,向著更高的平台發展。


如果你還沒有參與社區生活的話,我強烈建議你融入這個圈子裡來。它是一個比自我寬廣得多的平台,有助於你的發展。


如果你感覺自己的軟體開發工作停滯不前,費勁腦力也無法獲得更大突破的時候,最好的方式就是加入社區,與一群有志同道合的人共同探討所遇到的困難,獲得有助於解決問題的建議。另外,融入社區生活還能夠聚集人氣,培養人脈,這對於提升自身的職業發展也有很大幫助。


但是,如何才能融入到社區生活中呢?


這很簡單,世界各地都有很多開發者團體,你可以通過程序員網站找到並加入到他們當中去。你還可以參加開源夏令營,這是一個一年一度的免費地方性活動,眾多開發人員會聚在一起分享他們的工作,任何人都可登記參加自己感興趣的話題。


如果你不希望在現實生活中與過多的人接觸,也可以選擇加入虛擬社區。


那些大眾的程序員社區會是你的第一選擇。在社區中你會發現有一些非常厲害的程序員,他們會在自己的博客上寫一些精闢的文章並解答大家的問題。除此之外,還有另外一些不錯的在線社區,比如大牛們的博客網站、各種技術論壇、討論群等。


當你開始學會分享,把自己的所知與所想都寫出來的時候,你就真正的融入進了社區生活——而這個博客就是我為自己加入這個程序員社區所做的第一件事。:-)


4.沒有專長


如果你過去常訪問我的博客或者YouTube視頻,你會發現我很多時候都在談論這個話題。這個話題是如此重要,以至於我一有機會就會說到它。


俗話說,術業有專攻。你應當選擇一項想要專精的技術並努力磨煉它。但這並不意味著你就可以放棄對其它技術的基本理解而一味地去專研某項技術——我對那些會數種語言的人是非常欣賞的。這一點非常重要,尤其是在你職業生涯的早期培養一技之長的時候。


專長可以滿足更高級的需求,因此,在同等條件下,它會帶來更豐厚的報酬並更快的積累聲望——這些對於業界對你的認可是很有幫助的。


有專長的人好比是小池塘中的大魚,受人矚目。或許最終這條大魚會跳入更寬廣的池子,但是所累積的聲望和名氣同樣有助於在軟體開發行業的其它領域的發展。


凡事只要七分就好,對於專長技術的研究學習同樣如此。過度的投入會對程序員的時間與精力造成浪費,這是得不償失的。


5.無視個人品牌價值


生活中充滿著各種變數:搬家、結婚、換工作、一夜暴富、突然發福等等。無論如何,有一樣東西始終會伴隨著你一生,而這個東西就是——名字。


你的名字會貫穿於你的全部生活,難道它還不值得你去重視么?


你的名字或者也可以稱作是你的個人品牌是一件非常有投資價值的東西,可許多軟體開發人員對此卻一無所知。


對於獲得工作、取得晉升、客戶端的登陸以及工作的開展等,名字無疑都展現了其強大的作用。毫不誇張的說,假如你臭名昭著的話,會萬事難行,而如果你有良好的名譽的話,大多事情只需通過簡單的握手就能搞定。


我認識很多的軟體開發人員,他們從不擔心自己會失業,這是因為他們投資了時間和精力來打造堅實的個人品牌。他們知道,無論發生什麼事情,在他們失業後的幾個小時內就可以獲得一份新的工作,這是因為他們在業界有良好的聲譽。


對產品和服務進行的投資看起來很正常,但是你是否考慮過自我營銷的價值?要在軟體開發行業建立起自己的個人品牌,我的建議是從創建自己的博客開始,選擇將自己的專長或者有很深了解的領域作為提高自己影響力的跳板,學會把自己的名字一步步做成行業的金字招牌。如何快速的提高自己的影響力呢?最好的方法之一就是創建對別人有幫助的文章。


就拿這個博客為例吧。這個博客建立了我在互聯網上的個人品牌和聲譽,如果你認為我的文章或者網站是有價值的,你會選擇進行分享。甚至你有可能把它列入收藏或者進行訂閱,以方便以後繼續訪問。而這只是其中一種打造個人品牌的方式。同樣的,你還可以選擇視頻網站、播客等媒體,或者在書刊上發表文章,在會議上演講等方式。如果你對如何在軟體開發領域深度挖掘自身的品牌價值很感興趣,這個網站會告訴你如何去做。


6.荒廢業務時間


在工作之餘,你應當做一些項目來練練手。


做業余工作有許多你不知道的好處。首先,它可以有效的改進你的專業技能,特別是那些在平時的工作中很少用到的技術。相比起平時朝九晚五的工作,業余工作類型多變,對於專業技能的提高更有好處。其次,它有助於你對新的開發技術和技巧的學習。這對於日後你想從事新的工作是很有幫助的。我碰到過許多程序員,他們向我抱怨在當前工作中沒有機會去學習新技術,這讓他們今後無法在工作市場上立足。而我向他們建議工作之餘去做一些小項目,使用他們今後想要立足的新技術——這種方式對於提高相關技術是很有幫助的。


除此之外,我們不要忽視做業余工作所帶來的經濟利益。人們常認為業余時間做的那些小項目是掙不到什麼錢的,而事實上它卻是額外收入的重要來源。4年以前,我在業余時間里開發了一個在Android和iOS平台上使用的應用程序,而到現在,這個應用程序還能為我創造價值。


我還認識一些程序員,他們從業余工作做起,最後把這些工作發展為了全職工作。而事實上我就是這些程序員中的一位。這個博客本身以及SimpleProgrammer周圍的其它部分現在成為了我的全職工作。我喜歡稱自己為程序員的生活導師,但是也有很多人認為我是一個專職的博客寫手。


業余工作可以讓你充滿樂趣,它能夠把你從那些你不喜歡但又必須去做的工作中解脫出來。作為一種釋放工作壓力的好方法,它會每天帶給你新的希望。


7.沒有自我學習的計劃


在我面試軟體人員的時候,我首先會問到的一個問題就是關於他們的自我學習和持續完善的計劃——如何進行自我完善。程序員如何在這個快速變化的領域保持技術與觀念上的更新?我希望獲得的回答是他們能告訴我對於自我學習與成長他們有著一個實際可行的計劃。因為一個致力於不斷學習進步的人不僅能夠讓自己邁向成功還能影響到周圍的人,使他們一同邁向成功。


然而,有如此之多的程序員對於自我學習沒有任何計劃。假如你是這些人中的一員,你就應該立即行動起來做一個自我學習的計劃。


這兒有一個可供參考的個人簡單計劃:


堅持每月讀一本關於技術學習或者職業發展的書籍。


這意味著一年時間里你需要閱讀12本書。對於我來說,我會在每天用至少45分鍾時間來閱讀。當我在跑步機上運動的時候我會同時閱讀一些與我個人職業發展相關的文章。


積沙成塔,集腋成裘。每天只需花費30分鍾時間來閱讀書籍,一兩年時間之後你的人生境遇就會發生很大的改變。

C. android中handler和service的區別是什麼

任務、進程和線程
關於Android中的組件和應用,之前涉及,大都是靜態的概念。而當一個應用運行起來,就難免會需要關心進程、線程這樣的概念。在Android中,組件的動態運行,有一個最與眾不同的概念,就是Task,翻譯成任務,應該還是比較順理成章的。
Task的介入,最主要的作用,是將組件之間的連接,從進程概念的細節中剝離出來,可以以一種不同模型的東西進行配置,在很多時候,能夠簡化上層開發人員的理解難度,幫助大家更好的進行開發和配置。

任務
在SDK中關於Task(guide/topics/fundamentals.html#acttask),有一個很好的比方,說,Task就相當於應用(application)的概念。在開發人員眼中,開發一個Android程序,是做一個個獨門獨戶的組件,但對於一般用戶而言,它們感知到的,只是一個運行起來的整體應用,這個整體背後,就是Task。
Task,簡單的說,就是一組以棧的模式聚集在一起的Activity組件集合。它們有潛在的前後驅關聯,新加入的Activity組件,位於棧頂,並僅有在棧頂的Activity,才會有機會與用戶進行交互。而當棧頂的 Activity完成使命退出的時候,Task會將其退棧,並讓下一個將跑到棧頂的Activity來於用戶面對面,直至棧中再無更多 Activity,Task結束。

事件 Task棧
點開Email應用,進入收件箱(Activity A) A
選中一封郵件,點擊查看詳情(Activity B) AB
點擊回復,開始寫新郵件(Activity C) ABC
寫了幾行字,點擊選擇聯系人,進入選擇聯系人界面(Activity D) ABCD
選擇好了聯系人,繼續寫郵件 ABC
寫好郵件,發送完成,回到原始郵件 AB
點擊返回,回到收件箱 A
退出Email程序 null

如上表所示,是一個實例。從用戶從進入郵箱開始,到回復完成,退出應用整個過程的Task棧變化。這是一個標準的棧模式,對於大部分的狀況,這樣的Task 模型,足以應付,但是,涉及到實際的性能、開銷等問題,就會變得殘酷許多。比如,啟動一個瀏覽器,在Android中是一個比較沉重的過程,它需要做很多初始化的工作,並且會有不小的內存開銷。但與此同時,用瀏覽器打開一些內容,又是一般應用都會有的一個需求。設想一下,如果同時有十個運行著的應用(就會對應著是多個Task),都需要啟動瀏覽器,這將是一個多麼殘酷的場面,十個Task棧都堆積著很雷同的瀏覽器Activity,是多麼華麗的一種浪費啊。於是你會有這樣一種設想,瀏覽器Activity,可不可以作為一個單獨的Task而存在,不管是來自那個Task的請求,瀏覽器的Task,都不會歸並過去。這樣,雖然瀏覽器Activity本身需要維系的狀態更多了,但整體的開銷將大大的減少,這種舍小家為大家的行為,還是很值得歌頌的。
如此值得歌頌的行為,Android當然會舉雙手支持的。在Android中,每一個Activity的Task模式,都是可以由Activity提供方(通過配置文件...)和Activity使用方(通過Intent中的flag信息...)進行配置和選擇。當然,使用方對Activity的控制力,是限定在提供方允許的范疇內進行,提供方明令禁止的模式,使用方是不能夠越界使用的。
在SDK中(guide/topics/fundamentals.html#acttask),將兩者實現Task模式配置的方式,寫的非常清晰了,我再很絮叨挑選一些來解釋一下(完整可配置項,一定要看SDK,下面只是其中常用的若干項...)。提供方對組件的配置,是通過配置文件(Manifest)<activity>項來進行的,而調用方,則是通過Intent對象的flag進行抉擇的。相對於標準的Task棧的模式,配置的主要方向有兩個:一則是破壞已有棧的進出規則,或樣式;另一則是開辟新Task棧完成本應在同一Task棧中完成的任務。
對於應用開發人員而言,<activity>中的launchMode屬性,是需要經常打交道的。它有四種模式:"standard", "singleTop", "singleTask", "singleInstance"。
standard模式,是默認的也是標準的Task模式,在沒有其他因素的影響下,使用此模式的Activity,會構造一個Activity的實例,加入到調用者的Task棧中去,對於使用頻度一般開銷一般什麼都一般的Activity而言,standard模式無疑是最合適的,因為它邏輯簡單條理清晰,所以是默認的選擇。
而singleTop模式,基本上於standard一致,僅在請求的Activity正好位於棧頂時,有所區別。此時,配置成singleTop的Activity,不再會構造新的實例加入到Task棧中,而是將新來的Intent發送到棧頂Activity中,棧頂的Activity可以通過重載onNewIntent來處理新的Intent(當然,也可以無視...)。這個模式,降低了位於棧頂時的一些重復開銷,更避免了一些奇異的行為(想像一下,如果在棧頂連續幾個都是同樣的Activity,再一級級退出的時候,這是怎麼樣的用戶體驗...),很適合一些會有更新的列表Activity展示。一個活生生的實例是,在 Android默認提供的應用中,瀏覽器(Browser)的書簽Activity(BrowserBookmarkPage),就用的是singleTop。
singleTop模式,雖然破壞了原有棧的邏輯(復用了棧頂,而沒有構造新元素進棧...),但並未開辟專屬的Task。而singleTask,和singleInstance,則都採取的另闢Task的蹊徑。標志為singleTask的Activity,最多僅有一個實例存在,並且,位於以它為根的Task中。所有對該Activity的請求,都會跳到該Activity的Task中展開進行。singleTask,很象概念中的單件模式,所有的修改都是基於一個實例,這通常用在構造成本很大,但切換成本較小的Activity中。在Android源碼提供的應用中,該模式被廣泛的採用,最典型的例子,還是瀏覽器應用的主Activity(名為Browser...),它是展示當前tab,當前頁面內容的窗口。它的構造成本大,但頁面的切換還是較快的,於 singleTask相配,還是挺天作之合的。
相比之下,singleInstance顯得更為極端一些。在大部分時候singleInstance與singleTask完全一致,唯一的不同在於,singleInstance的Activity,是它所在棧中僅有的一個Activity,如果涉及到的其他Activity,都移交到其他Task中進行。這使得singleInstance的Activity,像一座孤島,徹底的黑盒,它不關注請求來自何方,也不計較後續由誰執行。在Android默認的各個應用中,很少有這樣的Activity,在我個人的工程實踐中,曾嘗試在有道詞典的快速取詞Activity中採用過,是因為我覺得快速取詞入口足夠方便(從notification中點選進入),並且會在各個場合使用,應該做得完全獨立。
除了launchMode可以用來調配Task,<activity>的另一屬性taskAffinity,也是常常被使用。taskAffinity,是一種物以類聚的思想,它傾向於將taskAffinity屬性相同的Activity,扔進同一個Task中。不過,它的約束力,較之launchMode而言,弱了許多。只有當<activity>中的allowTaskReparen ting設置為true,抑或是調用方將Intent的flag添加FLAG_ACTIVITY_NEW_TASK屬性時才會生效。如果有機會用到Android的Notification機制就能夠知道,每一個由notification進行觸發的Activity,都必須是一個設成FLAG_ACTIVITY_NEW_TASK的Intent來調用。這時候,開發者很可能需要妥善配置taskAffinity屬性,使得調用起來的Activity,能夠找到組織,在同一taskAffinity的Task中進行運行。

進程
在大多數其他平台的開發中,每個開發人員對自己應用的進程模型都有非常清晰的了解。比如,一個控制台程序,你可以想見它從main函數開始啟動一個進程,到 main函數結束,進程執行完成退出;在UI程序中,往往是有一個消息循環在跑,當接受到Exit消息後,退出消息循環結束進程。在該程序運行過程中,啟動了什麼進程,和第三方進程進行通信等等操作,每個開發者都是心如明鏡一本帳算得清清楚楚。進程邊界,在這里,猶如國界一般,每一次穿越都會留下深深的印跡。
在Android程序中,開發人員可以直接感知的,往往是Task而已。倍感清晰的,是組件邊界,而進程邊界變得難以琢磨,甚至有了進程託管一說。Android中不但剝奪了手工鍛造內存權力,連手工處置進程的權責,也毫不猶豫的獨佔了。
當然,Android隱藏進程細節,並不是刻意為之,而是自然而然水到渠成的。如果,我們把傳統的應用稱為面向進程的開發,那麼,在Android中,我們做得就是面向組件的開發。從前面的內容可以知道,Android組件間的跳轉和通信,都是在第三方介入的前提下進行,正由於這種介入,使得兩個組件一般不會直接發生聯系(於Service的通信,是不需要第三方介入的,因此Android把它全部假設成為穿越進程邊界,統一基於RPC來通信,這樣,也是為了掩蓋進程細節...),其中是否穿越進程邊界也就變得不重要。因此,如果這時候,還需要開發者關注進程,就會變得很奇怪,很費解,乾脆,Android將所有的進程一並託管去了,上層無須知道進程的生死和通信細節。
在Android的底層,進程構造了底部的一個運行池,不僅僅是Task中的各個Activity組件,其他三大組件Service、Content Provider、Broadcast Receiver,都是寄宿在底層某個進程中,進行運轉。在這里,進程更像一個資源池(概念形如線程池,上層要用的時候取一個出來就好,而不關注具體取了哪一個...),只是為了承載各個組件的運行,而各個組件直接的邏輯關系,它們並不關心。但我們可以想像,為了保證整體性,在默認情況下,Android肯定傾向於將同一Task、同一應用的各個組件扔進同一個進程內,但是當然,出於效率考慮,Android也是允許開發者進行配置。
在Android中,整體的<application>(將影響其中各個組件...)和底下各個組件,都可以設置<process>屬性,相同<process>屬性的組件將扔到同一個進程中運行。最常見的使用場景,是通過配置<application>的process屬性,將不同的相關應用,塞進一個進程,使得它們可以同生共死。還有就是將經常和某個Service組件進行通信的組件,放入同一個進程,因為與Service通信是個密集操作,走的是RPC,開銷不小,通過配置,可以變成進程內的直接引用,消耗頗小。
除了通過<process>屬性,不同的組件還有一些特殊的配置項,以Content Provider為例(通過<provider>項進行配置...)。<provider>項有一個mutiprocess的屬性,默認值為false,這意味著Content Provider,僅會在提供該組件的應用所在進程構造一個實例,第三方想使用就需要經由RPC傳輸數據。這種模式,對於構造開銷大,數據傳輸開銷小的場合是非常適用的,並且可能提高緩存的效果。但是,如果是數據傳輸很大,抑或是希望在此提高傳輸的效率,就需要將mutiprocess設置成true,這樣,Content Provider就會在每一個調用它的進程中構造一個實例,避免進程通信的開銷。
既然,是Android系統幫助開發人員託管了進程,那麼就需要有一整套紛繁的演算法去執行回收邏輯。Android中各個進程的生死,和運行在其中的各個組件有著密切的聯系,進程們依照其上組件的特點,被排入一個優先順序體系,在需要回收時,從低優先順序到高優先順序回收。Android進程共分為五類優先順序,分別是:Foreground Process, Visible Process, Service Process, Background Process, Empty Process。顧名思義不難看出,這說明,越和用戶操作緊密相連的,越是正與用戶交互的,優先順序越高,越難被回收。具體詳情,參見:guide/topics/fundamentals.html#proclife。
有了優先順序,還需要有良好的回收時機。回收太早,緩存命中概率低可能引起不斷的創造進程銷毀進程,池的優勢盪然無存;回收的太晚,整體開銷大,系統運行效率降低,好端端的法拉利可能被糟蹋成一枚QQ老爺車。Android的進程回收,最重要的是考量內存開銷,以及電量等其他資源狀況,此外每個進程承載的組件數量、單個應用開辟的進程數量等數量指標,也是作為衡量的一個重要標識。另外,一些運行時的時間開銷,也被嚴格監控,啟動慢的進程會很被強行kill掉。Android會定時檢查上述參數,也會在一些很可能發生進程回收的時間點,比如某個組件執行完成後,來做回收的嘗試。
從用戶體驗角度來看,Android的進程機制,會有很可喜的一面,有的程序啟動速度很慢,但是在資源充沛的前提下,你反復的退出再使用,則啟動變得極其快速(進程沒死,只是從後台弄到了前台),這就是拜進程託管所賜的。當然,可喜的另一面就是可悲了,Android的託管演算法,還時不時的展現其幼稚的一面,明明用戶已經明顯感覺到操作系統運行速度下降了,打開任務管理器一看,一票應用還生龍活虎的跳躍著,必須要手動幫助它們終結生命找到墳墓,這使得任務管理器基本成為Android的裝機必備軟體。
從開發角度上來看,Android這套進程機制,解放了開發者的手腳。開發人員不需要處心積慮的構造一個後台進程偷偷默默監聽某個時間,並嘗試用各種各樣的守護手段,把自己的進程鍛造的猶如不死鳥一輝一般,進程生死的問題,已經原理了普通開發人員需要管理的范疇內。但同時,於GC和人肉內存管理的爭議一樣,所有開發人員都不相信演算法能比自己做得效率更高更出色。但我一直堅信一點,所有效率的優勢都會隨著演算法的不斷改良硬體的不斷提升而消失殆盡,只有開發模式的簡潔不會隨時間而有任何變化。

組件生命周期
任何架構上的變化,都會引起上層開發模式的變化,Android的進程模型,雖然使開發者不再需要密切關注進程的創建和銷毀的時機,但仍然需要關注這些時間點對組件的影響。比如,你可能需要在進程銷毀之前,將寫到內存上的內容,持久化到硬碟上,這就需要關注進程退出前發生的一些事件。
在Android中,把握這些時間點,就必須了解組件生命周期(Components Lifecycles)。所謂組件的生命在周期,就是在組件在前後台切換、被用戶創建退出、被系統回收等等事件發生的時候,會有一些事件通知到對應組件上,開發人員可以選擇性的處理這些事件在對應的時間點上來完成一些附加工作。
除Content Provider,其他組件都會有生命周期的概念,都需要依照這個模型定時定點處理一些狀況,全部內容參見:guide/topics/fundamentals.html#lcycles。在這里,擒賊先擒王,還是拿Activity出來作楷模。

繼續偷圖,來自SDK。一個自然的Activity生命旅途,從onCreate開始,到onDestroy消亡。但月有陰晴圓缺組件有禍福旦夕,在系統需要的時候且組件位於後台時,所在的進程隨時可能為國捐軀被回收,這就使得知道切入後台這個事情也變得很重要。
當組件進入棧頂,與用戶開始交互,會調用onResume函數,類似,當退出棧頂,會有onPause函數被呼喚。onResume和onPause可以處理很多事情,最常規的,就是做一些文件或設置項的讀寫工作。因為,在該組件不再前台運行的時候,可能別的組件會需要讀寫同樣一份文件和設置,如果不再onResume做刷新工作,用的可能就是一份臟數據了(當然,具體情況,還需要具體分析,如果文件不會被多頭讀寫,可以放到onCreate裡面去做讀工作)。
除了前述切入後台會被其他組件騷擾的問題,另外,死無定因也是件很可怕的事情。在Android中,組件都有兩種常見的死法,一種是自然消亡,比如,棧元素ABC,變成AB了,C組件就自然消亡了。這種死發輕如鴻毛,不需要額外關心。但另一種情況,就是被系統回收,那是死的重如泰山,為國捐軀嘛。
但這種捐軀的死法,對用戶來說,比較費解。想像一下,一款游戲,不能存檔,你一直玩啊玩,三天三夜沒合眼,這時候你mm打來電話鼓勵一下,你精神抖擻的准備再接再厲,卻發現你的游戲進程,在切入後台之後,被系統回收了,一夜回到解放前三天努力成為一場泡影,你會不會想殺做游戲的人,會不會會不會會不會,一定會嘛。這時候,如果沒有Activity生命周期這碼事,游戲程序員一定是被冤死的,成了Android的替罪羊。但是,Android的組件是有生命周期的, 如果真的發生這樣情況,不要猶豫,去殺開發的程序員吧。
為了逃生,程序員們有一塊免死金牌,那就是Android的state機制。所謂state,就是開發人員將一些當前運行的狀態信息存放在一個Bundle對象裡面,這是一個可序列化鍵值對集合。如果該Activity組件所處的進程需要回收,Android核心會將其上Activity組件的Bundle對象持久化到磁碟上,當用戶回到該Activity時候,系統會重新構造該組件,並將持久化到磁碟上的Bundle對象恢復。有了這樣的持久化的狀態信息,開發人員可以很好的區分具體死法,並有機會的使得死而復生的Activity恢復到死前狀態。開發者應該做的,是通過onSaveInstanceState函數把需要維系的狀態信息(在默認的狀態下,系統控制項都會自己保存相關的狀態信息,比如TextView,會保存當前的Text信息,這都不需要開發人員擔心...),寫入到Bundle對象,然後在onRestoreInstanceState函數中讀取並恢復相關信息(onCreate,onStart,也都可以處理...)。

線程
讀取數據,後台處理,這些猥瑣的伙計,自然少不了線程的參與。在Android核心的調度層面,是不屑於考量線程的,它關注的只有進程,每一個組件的構造和處理,都是在進程的主線程上做的,這樣可以保證邏輯的足夠簡單。多線程,往往都是開發人員需要做的。
Android的線程,也是通過派生Java的Thread對象,實現Run方法來實現的。但當用戶需要跑一個具有消息循環的線程的時候,Android有更好的支持,來自於Handler和Looper。Handler做的是消息的傳送和分發,派生其handleMessage函數,可以處理各種收到的消息,和win開發無異。Looper的任務,則是構造循環,等候退出或其他消息的來臨。在Looper的SDK頁面,有一個消息循環線程實現的標准範例,當然,更為標準的方式也許是構造一個HandlerThread線程,將它的Looper傳遞給Handler。
在Android中,Content Provider的使用,往往和線程掛鉤,誰讓它和數據相關呢。在前面提到過,Content Provider為了保持更多的靈活性,本身只提供了同步調用的介面,而由於非同步對Content Provider進行增刪改查是一個常做操作,Android通過AsyncQueryHandler對象,提供了非同步介面。這是一個Handler的子類,開發人員可以調用startXXX方法發起操作,通過派生onXXXComplete方法,等待執行完畢後的回調,從而完成整個非同步調用的流程,十分的簡約明了。

實現
整個任務、進程管理的核心實現,盡在ActivityManagerService中。上一篇說到,Intent解析,就是這個ActivityManagerService來負責的,其實,它是一個很名不副實的類,因為雖然名為Activity的Manager Service,但它管轄的范圍,不只是Activity,還有其他三類組件,和它們所在的進程。
在ActivityManagerService中,有兩類數據結構最為醒目,一個是ArrayList,另一個是HashMap。 ActivityManagerService有大量的ArrayList,每一個組件,會有多個ArrayList來分狀態存放。調度工作,往往就是從一個ArrayList裡面拿出來,找個方法調一調,然後扔到另一個ArrayList裡面去,當這個組件沒對應的ArrayList放著的時候,說明它離死不遠了。HashMap,是因為有組件是需要用名字或Intent信息做定位的,比如Content Provider,它的查找,都是依據Uri,有了HashMap,一切都順理成章了。
ActivityManagerService用一些名曰xxxRecord的數據結構,來表達各個存活的組件。於是就有了,HistoryRecord(保存Activity信息的,之所以叫History,是相對Task棧而言的...),ServiceRecord,BroadcastRecord,ContentProviderRecord,TaskRecord,ProcessRecord,等等。
值得注意的,是TaskRecord,我們一直再說,Task棧這樣的概念,其實,真實的底層,並不會在TaskRecord中,維系一個Activity 的棧。在ActivityManagerService中,各個任務的Activity,都以HistoryRecord的形式,集中存放在一個 ArrayList中,每個HistoryRecord,會存放它所在TaskRecord的引用。當有一個Activity,執行完成,從概念上的 Task棧中退出,Android是通過從當前HistoryRecord位置往前掃描同一個TaskRecord的HistoryRecord來完成的。這個設計,使得上層很多看上去邏輯很復雜的Task體系,在實現變得很統一而簡明,值得稱道。
ProcessRecord,是整個進程託管實現的核心,它存放有運行在這個進程上,所有組件的信息,根據這些信息,系統有一整套的演算法來決議如何處置這個進程,如果對回收演算法感興趣,可以從ActivityManagerService的trimApplications函數入手來看。
對於開發者來說,去了解這部分實現,主要是可以幫助理解整個進程和任務的概念,如果覺得這塊理解的清晰了,就不用去碰ActivityManagerService這個龐然大物了。

================
這是轉載的 ,感覺比一樓說的好

=============
一下是自己的

服務(Service)需要配置 才能使用
線程 使用就不說了
hanler ,是用來進行消息隊列的一個東東,handler 可以用來更新控制項的顯示 ,以及線程之間的通信,
service只能啟動後台,屬於應用組件之一

D. 計算機軟體開發系統提給我們的一些方法,他們都有哪些

系統給我們提供了很多常用的,比如日期函數,文件函數,字元串函數,信用卡函數等,下面是常見的一些函數。
1.創建一條新線程,並將其壓棧, 並返回維護這個線程的 lu a_State 指針。 這個函數返回的新線程共享原線程的全局環境, 但是它有獨立的運行棧。
2.沒有顯式的函數可以用來關閉或銷毀掉一個線程。 線程跟其它 L ua 對象一樣是垃圾收集的條目之一。
3.創建一個運行在新的獨立的狀態機中的線程。 如果無法創建線程或狀態機(由於內存有限)則返回 NULL。 參數 f 是一個分配器函數; L ua 將通過這個函數做狀態機內所有的內存分配操作。 第二個參數 ud ,這個指針將在每次調用分配器時被轉入。
這個函數分配一塊指定大小的內存塊, 把內存塊地址作為一個完全用戶數據壓棧, 並返回這個地址。 宿主程序可以隨意使用這塊內存。
4.將一個 L ua 浮點數轉換為一個 L ua 整數。 這個宏假設 n 有對應的整數值。 如果該值在 L ua 整數可表示範圍內, 就將其轉換為一個整數賦給 *p。 宏的結果是一個布爾量,表示轉換是否成功。 (注意、由於圓整關系,這個范圍測試不用此宏很難做對。)
該宏有可能對其參數做多次取值。
用戶數據是保留在 Lu a 中的 C 值。 輕量用戶數據 表示一個指針 void*。 它是一個像數字一樣的值: 你不需要專門創建它,它也沒有獨立的元表,而且也不會被收集(因為從來不需要創建)。 只要表示的 C 地址相同,兩個輕量用戶數據就相等。
這個宏等價於 lua_pushlstring, 區別僅在於只能在 s 是一個字面量時才能用它。 它會自動給出字元串的長度。
lu a_pushlstring
const char *lua_pushlstring (lua_State *L, const char *s, size_t len);
5.把指針 s 指向的長度為 len 的字元串壓棧。 Lua 對這個字元串做一個內部副本(或是復用一個副本), 因此 s 處的內存在函數返回後,可以釋放掉或是立刻重用於其它用途。 字元串內可以是任意二進制數據,包括零字元。
返回內部副本的指針。
返回給定索引處值的固有「長度」: 對於字元串,它指字元串的長度; 對於表;它指不觸發元方法的情況下取長度操作('#')應得到的值; 對於用戶數據,它指為該用戶數據分配的內存塊的大小; 對於其它值,它為 0 。

E. 程序員蘇享茂被毒妻威脅勒索致死,因為他忽視了至關重要的一點

這幾天,程序員蘇享茂被惡毒的前妻翟欣欣威脅,巨額勒索,最終被活活逼死的新聞在網上刷屏。

蘇享茂,一個獨自開發了wephone的IT界天才,天資聰慧,獨自創業,但是也許是對開發軟體工作太過於專注投入,而缺乏社會經驗和處事技法的他,遇人不淑,遭受漂亮前妻無休止的折磨和勒索,最終走向了自盡的不歸路去逃避變本加厲貪心的妻子。

這無疑是一個人間悲劇,且不論毒妻翟欣欣是綠茶婊,心機婊,狐狸精,害人精,活生生地逼死了一個優秀老實的程序員,應該背上千古罵名。

但是我們拋開對毒妻的唾罵,仔細冷靜下來想想,難道不諳世事的蘇享茂本身就不存在一絲一毫的問題嗎?

讓我們仔細回想一下蘇享茂和翟欣欣認識相處的經過,會發覺,翟欣欣這個老謀深算的心機女,僅僅用了三天,就把蘇享茂的全部底細徹底摸清。

僅僅用了三天,被一個陌生人摸清底細,是一件多麼恐怖的事情。

而聰明的物質女翟欣欣是如何輕易地把蘇享茂的底細摸清的呢?

首先,是蘇享茂這個單純的程序員,在朋友圈曬自己一輛特拉斯豪車,引了翟欣欣敏銳目光的注意。

然後翟欣欣想盡心機引出蘇享茂的全部底細,發了一段別墅的視頻給蘇享茂,那個單純極度缺乏社會經驗的程序員就按捺不住自己的情緒,把自己的股票和理財賬戶全部和盤托出,怕失去這個漂亮的尤物。

是呀,和盤托出自己的全部家當和底細,絲毫不為自己保留一絲神秘感。

就是因為可憐值得同情的程序員絲毫不為自己保留一絲神秘感,所以直到最後翟欣欣掌握了他公司的灰色運營和偷稅漏稅,把大好前途的他逼上了不歸路。

整個悲劇發生的過程中,單純老實的蘇享茂無一絲神秘感,家底,財產,公司全部被翟欣欣玩弄於股掌之中,掌握了他所有把柄,所以他無路可退。

如果蘇享茂沒有在朋友圈曬自己的豪車,沒有把自己的底細全部赤裸裸地展現在翟欣欣面前,沒有把公司的運營狀況和商業機密全部暴露給翟欣欣,讓翟欣欣無法徹徹底底摸清自己所有底細,她就無法把老實巴交的程序員活活逼死,是不是就可以避免這場人間悲劇的發生呢?

是呀,都說在我們現實生活中,就連自己身邊最親近的人,都不應該把自己所有老底全部都暴露無遺,況且是剛認識不久的外人翟欣欣,蘇享茂也赤裸裸地展現了自己所有秘密和家底,所以他自己也間接地縱容釀成了悲劇的發生。

在我們身邊,也發生過許多類似的活生生的例子。

自己身邊的朋友,一個普通的家庭,一個普通平凡卻苦命的妻子,年輕時期少不更事,被幻想的感情沖昏了頭腦,深陷感情的她被幻想麻木了雙眼,一步一步地毫不理智地掉進了感情渾濁的泥潭中無法自拔。

婚後的她,犯了許多傻女人共同的錯誤,遭遇了不靠譜渣男殘酷的家暴。

可憐命苦的妻子,經常鼻青臉腫地哭哭啼啼地去上班。

女人傻到一定境界,丈夫不出去工作,家裡的支出全靠她一個人苦苦支撐。

這樣被丈夫毆打家暴的女人,在朋友的勸說和安慰下,常年心灰意冷的麻木內心瞬間清醒。

她照做了朋友給她出的主意,每個月,默默地為苦命的自己,存下一筆錢,買了一套小居室,但是,對那個渣男家暴老公,她隻字未提。

在丈夫的毒打和滿口臟話的罵聲中,她依舊牢牢塵封著屬於自己的秘密。

當禽獸不如的丈夫出軌,和她提出離婚並讓她凈身出戶。

那個狠心的丈夫,傻傻地得意的以為,那個傻女人離開了家肯定無處可去,無家可歸,生活肯定無法想像的艱難。

殊不知,妻子已經一邊在辦離婚手續,一邊裝修著真正屬於自己的小居室。

離婚手續完結之後,苦命的女人順理成章地住進了屬於自己的小房間,開始了新的生活。

生活中還有許多層出不窮屢見不鮮的例子。

在一所大學同寢室的女生們,其中有一位女生個性特別張揚,還特別愛炫富。

炫富到自己有多少存款,多少個銀行卡,每個銀行卡多少錢,她都喜歡向同寢室的室友宣布炫耀,絲毫不誇張。

而這個傻女孩,還喜歡用自己的生日作為銀行卡密碼。

結局可想而知,一夜之間,女孩所有銀行卡的存款全部被別人一掃而光,全部清零。

記得老子《道德經》中提出:神龍見首不見尾,神龍騰雲駕霧,仙境中一閃而過,只見龍首,龍尾卻隱藏在霧蒙蒙的雲海中,給人留下若隱若現的神秘感,讓人引發無限的遐想。

所以親愛的朋友們,從現在起,讓我們在同事,朋友,親人之間,給人保留些許的神秘感吧,不必把自己的家產,底細,存款全部暴露無遺地展現在別人面前,不讓任何人抓住你內心深處的把柄,才不會發生別人對你不利的悲劇,那樣你才能保全你自己不受傷害。

親愛的朋友們,現在起,開始在眾人面前,保留一點自己的小秘密吧,並不是讓我們有心機,而僅僅是為了在錯綜復雜的社會中保護好自己。

閱讀全文

與程序員一夜未歸相關的資料

熱點內容
unix下編譯庫文件 瀏覽:631
程序員的u盤 瀏覽:235
android根據經緯度獲取城市 瀏覽:564
python使用解釋器還是編譯器 瀏覽:358
以下關於有加密演算法及密鑰描述 瀏覽:219
linuxgethostname 瀏覽:415
程序員多數有對象 瀏覽:131
單片機延時程序計算 瀏覽:444
編譯原理語法翻譯 瀏覽:504
pr編譯出錯渲染存在偏移 瀏覽:262
如何製作自家的app 瀏覽:199
推薦一個解壓軟體rar解壓幫手 瀏覽:210
wd文檔加密器 瀏覽:748
伺服器上傳壓縮包一般是什麼格式 瀏覽:333
發送加密文件密碼幾位數 瀏覽:160
樹洞app怎麼樣 瀏覽:175
vivo編譯時間可以改么 瀏覽:150
編譯和編輯怎麼區分 瀏覽:981
iar編譯文件順序 瀏覽:899
java二叉搜索樹 瀏覽:634