這是一篇長文独撇,需要你有耐心看完尸变,看前或者看后最好自己動手實踐一下夹纫。
前段時間有和一個在北美的讀者交流,他提到去Facebook面試的一些經(jīng)歷崔挖,希望我能寫一個關(guān)于“如何設(shè)計一個照片上傳App”的主題贸街,因為他不太清楚面試官讓面試者直接設(shè)計一個應用,主要想考察哪方面的能力狸相。
其實大家可以站在面試官的角度想一下薛匪,如果只是問一些技術(shù)點的面試題,面試官能獲得什么呢脓鹃?
也許只是知道面試者哪個技術(shù)點不熟悉逸尖,哪個理解錯誤,那個比較常用,那個能舉一返三冷溶。如果只就一個點問的話渐白,往往只能得到面試者對于一些表面知識的認識程度。但我們知道現(xiàn)實中或項目中的問題往往不是孤立存在的逞频,它們是一個復合的整體纯衍,所以有時候我們需要考察一些“隱性知識”。
而讓面試者設(shè)計一個真實的App苗胀,是考察面試者對Android和應用設(shè)計開發(fā)的隱性知識掌握程序的最簡單有效的手段襟诸。
和隱性知識相對應的詞叫“顯性知識”,諸如Activity的生命周期基协,四大組件的特性等都是顯性知識歌亲,而如何運用和融匯這些特性就需要你具備一定的隱性知識了。說白了澜驮,隱性知識就是你應該會但是“課本”或者“文檔”又沒有直接告訴你的知識陷揪,比如知識之間的聯(lián)系、對比或者差別等杂穷,擁有更多的隱性知識其時也是高手的特征之一悍缠。
面試題:如何設(shè)計一個照片上傳app?
那這個題,我們一改常態(tài),不用之前的面試題的分析套路弟跑。而是把自己放在一個面試官的角度,自己先實現(xiàn)一次這個App趴拧,然后自己總結(jié)一下你在這次實現(xiàn)中需要哪些能力、需要注意哪些事項山叮。最后著榴,再回過頭來看,如果你是面試官屁倔,你希望面試者怎么回答才算是符合你的標準的兄渺?
實現(xiàn)案例
每個人的實現(xiàn)的方式都不一樣,所以你其實可以不看我寫的汰现。直接動手再說挂谍。
還是先說一下我的思路。先把需求整理一下瞎饲,“如何設(shè)計一個照片上傳的App”口叙,雖然題目只有簡單的一句話,但我們要將它細化一下來看嗅战。
即然能上傳妄田,那就一定能瀏覽對吧俺亮,不然不太好確定上傳成功以否(彈出上傳成功的提示,而沒有跳到瀏覽的界面疟呐,顯然是不太友好且也不符合用戶的習慣)脚曾。
即然能瀏覽,那就要有一個列表或網(wǎng)格(如Gallery)的樣式進行启具,那么需要一些滑動之類的動畫效果本讥。那么為了配得起這些效果,界面的UI設(shè)計就不能太糟糕吧鲁冯?
即然有列表了拷沸,那么就得有專門查看一張圖片詳情的界面。
薯演。撞芍。。跨扮。序无。。
我們把這些主要的需求羅列一下:
- 可以瀏覽用戶已經(jīng)上傳到服務器的圖片衡创;
- 可以查看某張圖片的詳情帝嗡;
- 選擇和編輯要上傳的圖片;(從本地或者攝像頭獲取圖片)
- 工作線程上傳一張圖片到服務器钧汹;
陷性的需求:
- 框架的設(shè)計:UI和邏輯的分層設(shè)計丈探,錯誤處理機制 (這點其實很重要)
- 性能要求:列表要滑動順暢录择,不會出現(xiàn)OOM
- 應對需求變代的可擴展性:是否需要加入用戶登錄和注冊拔莱?每張圖片是否可以點贊或者添加評論?是否要加上保存和收藏圖片功能隘竭?
可以還會有很多需求塘秦,如在編輯圖片時添加濾鏡等圖片處理效果;搜索动看、定位尊剔、個人偏好的算法等等。
其實菱皆,需求還沒有完须误。接收圖片的服務器,是第三方的還是需要我們自己寫一個呢仇轻?如果是第三方的京痢,可能會涉及使用一些他們定的REST接口或者SDK,如Instagram篷店。
而且如果是第三方的話祭椰,還需要涉及登錄和授權(quán)之類的工作臭家。
為了讓大家了解整個過程,所以這里方淤,我實現(xiàn)一個自己的服務器用來提供圖片的展示和上傳服務钉赁。
Node.js實現(xiàn)圖片管理服務器
可能還需要支持:斷點續(xù)傳、多文件同時上傳携茂。不過我的Demo里做了一個簡化你踩,沒有實現(xiàn)這兩個功能,留給讀者自己去完善吧邑蒋。
Node.js服務端的設(shè)計請參考這篇文章:如何設(shè)計一個照片上傳App--Node.js篇
Android客戶端
我簡單寫了一個示例代碼放在Github上姓蜂,主要是用來測試和服務端的接口,實現(xiàn)在Android端通過OKHttp上傳圖片医吊。上傳進度通過擴展OKHttp來實現(xiàn)進度信息的獲取钱慢,這樣相對簡單,不需要服務端那邊提供額外的接口卿堂。
沒有加入MVP或者MVVM的框架束莫,一是為了簡化代碼(不增加大家的閱讀難度),二是這個Demo主要是為了給大家展示和Node.js服務端的配合使用草描。
當你可以很簡單就打造自己的服務端時览绿,你的移動端設(shè)計和開發(fā)才不會那么受制于人。但是穗慕,比較完整的實現(xiàn)還是需要你自己動手的饿敲。
因為,我這里往往都沒有面試題的直接答案逛绵。
Github示例:AndroidUploadImageDemo
示例中使用到的一些第三方庫:
圖片庫Glide:https://github.com/bumptech/glide
網(wǎng)絡請求封裝Retrofit2:http://square.github.io/retrofit
Json數(shù)據(jù)轉(zhuǎn)換Gson:https://github.com/google/gson
回到面試題
我們先來總結(jié)一下怀各,經(jīng)歷這次實現(xiàn)過程,你覺得開發(fā)涉及到了哪些技術(shù)點或者模塊术浪,在開發(fā)中需要注意哪些事項瓢对?
相關(guān)的模塊和涉及的技術(shù)點:
- Retrofit做網(wǎng)絡請求和解析(Gson);
- Http文件上傳的協(xié)義胰苏;
- 圖片瀏覽的性能優(yōu)化或者遇到的問題:如圖片庫的加載和ListView的展示配合硕蛹,RecyclerView瀑布流展示頁面跳動等問題;
- 框架的設(shè)計:UI和邏輯的分離問題硕并;
- 無網(wǎng)或網(wǎng)絡異常時的處理法焰;
......
上面的這些,你實際動手就會遇到倔毙,要么你去解決它們埃仪,要么你可以選擇其他的方式來回避它們。比如普监,針對性能問題贵试,如果你只測幾十張圖片琉兜,可能沒有什么優(yōu)化的必要,但如果你在Node.js端放1000+張照片毙玻,在這樣的情景下豌蟋,你就有必要來改善移動端的展示性能了(而解決的方案可以根據(jù)自己的需求來定:如Node.js端加個接口,分頁返回列表數(shù)據(jù)等)桑滩。
針對這類題梧疲,面試官可能會你讓親自動手實現(xiàn),需要你在規(guī)定的時間內(nèi)給出一個源碼工程(可以更直觀看到你的代碼風格)运准;也可能只是讓你談談你的設(shè)計思路幌氮,或者可能遇到的困難的解決方案。這樣題更主要是要考察面試者的綜合能力胁澳。
如果你沒有實際做過该互,那么你應該怎么回答這個面試題呢?
第一韭畸,和對方交流清楚宇智,確定理解面試官關(guān)注和考察的重點;
第二胰丁,盡可能在談設(shè)計思路時考慮到一些實際問題(邊界随橘、異常等),這方面的經(jīng)歷其實正是面試官想看到的锦庸;
第三机蔗、從用戶的角度去展開和設(shè)計這個應用;
小結(jié)
恭喜你是一個有耐心的人甘萧,可以看到最后的小結(jié)部份萝嘁。遺憾的是,這篇面試題沒有小結(jié)幔嗦,因為你親自動手后會得到自己的小結(jié)酿愧,所以沥潭,留給你自己去總結(jié)吧邀泉。