我的Android面試之路

最近在找Android開發(fā)的工作辕漂,遇到了一些面試的問題呢灶,加上朋友面試遇到的一些問題吴超,感覺有必要在此記錄一下,也分享給大家鸯乃,說不定還有用呢鲸阻。

1跋涣、線程同步問題:有3個(gè)線程abc,循環(huán)輸出十次abc鸟悴。

這個(gè)問題簡單的就是使用AtomicInteger來實(shí)現(xiàn)陈辱,具體實(shí)現(xiàn)方式如下:

private AtomicInteger sycValue = new AtomicInteger(0);
private static final int MAX_SYC_VALUE = 3 * 10;

public void test() {
    new Thread(new RunnableA()).start();
    new Thread(new RunnableB()).start();
    new Thread(new RunnableC()).start();
}

private class RunnableA implements Runnable {
    public void run() {
        while (sycValue.get() < MAX_SYC_VALUE) {
            if (sycValue.get() % 3 == 0) {
                System.out.println(String.format("第%d遍", sycValue.get() / 3 + 1));
                System.out.println("A");
                sycValue.getAndIncrement();
            }
        }
    }
}

private class RunnableB implements Runnable {
    public void run() {
        while (sycValue.get() < MAX_SYC_VALUE) {
            if (sycValue.get() % 3 == 1) {
                System.out.println("B");
                sycValue.getAndIncrement();
            }
        }
    }
}

private class RunnableC implements Runnable {
    public void run() {
        while (sycValue.get() < MAX_SYC_VALUE) {
            if (sycValue.get() % 3 == 2) {
                System.out.println("C");
                System.out.println();
                sycValue.getAndIncrement();
            }
        }
    }
}

2、多線程下載同一個(gè)文件

這個(gè)問題主要分三步來考慮:

  • 獲取文件總長度细诸,通過總長度來確定開啟幾個(gè)線程下載沛贪,并不是線程越多就越好。
  • 分段下載文件震贵,確定線程數(shù)后利赋,每個(gè)線程下載相應(yīng)的數(shù)據(jù)。
  • 將分段下載的文件拼接為一個(gè)完整的文件猩系。
  private void test() {
      new Thread(new Runnable() {
          @Override
          public void run() {
              System.out.println("開始下載");
              download("https://a-ssl.duitang.com/uploads/item/201307/11/20130711155049_yhiWQ.jpeg", 3);
          }
      }).start();
   }

  private void download(String path, int threadNum) {
    try {
        URL url = new URL(path);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(5 * 1000);
        //獲取文件長度
        int length = connection.getContentLength();
        //計(jì)算每個(gè)線程下載長度
        int block = (length % threadNum) == 0 ? length / threadNum : length / threadNum + 1;
        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                    path.substring(path.lastIndexOf("/") + 1));
            for (int i = 0; i < threadNum; i++)
                new DownThread(i, file, block, url).start();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
  }

  public class DownThread extends Thread {
    /**
     * 線程序號(hào)id
     */
    private int id;
    /**
     * 目標(biāo)文件
     */
    private File file;
    /**
     * 每個(gè)線程下載文件的長度
     */
    private int block;
    /**
     * 下載地址
     */
    private URL url;

    public DownThread(int id, File file, int block, URL url) {
        this.id = id;
        this.file = file;
        this.block = block;
        this.url = url;
    }

    @Override
    public void run() {
        int start = (id * block);// 當(dāng)前線程開始下載處
        int end = (id + 1) * block - 1;// 當(dāng)前線程結(jié)束下載處
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rwd");
            randomAccessFile.seek(start);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(5 * 1000);
            connection.setRequestMethod("GET");
            // 指定網(wǎng)絡(luò)位置從什么位置開始下載,到什么位置結(jié)束
            connection.setRequestProperty("Range", "bytes=" + start + "-" + end);
            InputStream in = connection.getInputStream();
            byte[] data = new byte[1024];
            int len = 0;
            while ((len = in.read(data)) != -1) {
                randomAccessFile.write(data, 0, len);
            }
            in.close();
            randomAccessFile.close();
            System.out.println("線程" + id + "下載完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  }

3媚送、網(wǎng)頁端生成二維碼,手機(jī)端掃描登錄

這個(gè)問題需要服務(wù)器端的配合寇甸,這里就講一講大概的思路了塘偎。

  1. 網(wǎng)頁端生成二維碼,同時(shí)長連接等待服務(wù)器響應(yīng)拿霉。
  2. 手機(jī)端掃描二維碼吟秩,然后判斷手機(jī)端是否登錄,如果沒有就先登錄绽淘,然后通知服務(wù)器掃描結(jié)果峰尝。
  3. 網(wǎng)頁端收到服務(wù)器響應(yīng),顯示已經(jīng)掃描待手機(jī)端確認(rèn)登錄收恢,同時(shí)手機(jī)端顯示確認(rèn)界面武学。
  4. 手機(jī)端確認(rèn)或取消登錄,同時(shí)通知服務(wù)器結(jié)果伦意,網(wǎng)頁端收到服務(wù)器響應(yīng)火窒,同時(shí)顯示相應(yīng)結(jié)果。

4驮肉、廣播的種類和不同之處

Android系統(tǒng)中有3種廣播熏矿,話說當(dāng)時(shí)只知道前面3種常用的,后來回來查資料才發(fā)現(xiàn)有5種离钝。

  • 普通廣播(Normal Broadcast)
  • 系統(tǒng)廣播(System Broadcast)
  • App應(yīng)用內(nèi)廣播(Local Broadcast)
  • 有序廣播(Ordered Broadcast)
  • 粘性廣播(Sticky Broadcast)
普通廣播(Normal Broadcast)

普通廣播是完全異步的票编,可以在同一時(shí)刻(邏輯上)被所有廣播接收者接收到,消息傳遞的效率比較高卵渴,廣播接收者中注冊(cè)時(shí)intentFilter的action與廣播匹配慧域,才會(huì)接收到此廣播。發(fā)送普通廣播使用的是Context.sendBroadcast()浪读。

系統(tǒng)廣播(System Broadcast)

Android中內(nèi)置了多個(gè)系統(tǒng)廣播昔榴,只要涉及到手機(jī)的基本操作(如開機(jī)辛藻、網(wǎng)絡(luò)狀態(tài)變化、拍照等等)互订,都會(huì)發(fā)出相應(yīng)的廣播吱肌,每個(gè)廣播都有特定的Intent - Filter(包括具體的action)。當(dāng)使用系統(tǒng)廣播時(shí)仰禽,只需要在注冊(cè)廣播接收者時(shí)定義相關(guān)的action即可氮墨,并不需要手動(dòng)發(fā)送廣播,當(dāng)系統(tǒng)有相關(guān)操作時(shí)會(huì)自動(dòng)進(jìn)行系統(tǒng)廣播吐葵。

App應(yīng)用內(nèi)廣播(Local Broadcast)

App應(yīng)用內(nèi)廣播可理解為一種局部廣播勇边,廣播的發(fā)送者和接收者都同屬于一個(gè)App。相比于全局廣播(普通廣播)折联,App應(yīng)用內(nèi)廣播優(yōu)勢(shì)體現(xiàn)在:安全性高 & 效率高粒褒。使用方式上與普通廣播幾乎相同,只是注冊(cè)/取消注冊(cè)廣播接收器和發(fā)送廣播時(shí)將參數(shù)的Context變成了LocalBroadcastManager的單一實(shí)例诚镰。并且只能通過LocalBroadcastManager動(dòng)態(tài)注冊(cè)奕坟,不能靜態(tài)注冊(cè)。

//動(dòng)態(tài)注冊(cè) 
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, intentFilter);
//取消注冊(cè)
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
//發(fā)送應(yīng)用內(nèi)廣播
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
有序廣播(Ordered Broadcast)

有序廣播是按照接收者聲明的優(yōu)先級(jí)別(聲明在intent-filter元素的android:priority屬性中清笨,數(shù)越大優(yōu)先級(jí)別越高,取值范圍:-1000到1000月杉。也可以調(diào)用IntentFilter對(duì)象的setPriority()進(jìn)行設(shè)置),被接收者依次接收廣播抠艾。如:A的級(jí)別高于B,B的級(jí)別高于C,那么苛萎,廣播先傳給A,再傳給B检号,最后傳給C腌歉。A得到廣播后,可以往廣播里存入數(shù)據(jù)齐苛,當(dāng)廣播傳給B時(shí),B可以從廣播中得到A存入的數(shù)據(jù)翘盖。

//發(fā)送有序廣播
Context.sendOrderedBroadcast(intent)
//終止廣播
BroadcastReceiver.abortBroadcast()
粘性廣播(Sticky Broadcast)

由于在Android5.0 & API 21中已經(jīng)失效,所以不建議使用凹蜂,在這里也不作過多的總結(jié)了馍驯。

5、移動(dòng)支付

話說現(xiàn)在移動(dòng)支付還是用得挺常見的玛痊,正好也弄過常見的微信支付汰瘫、支付寶支付和銀聯(lián)支付,總體來說使用起來并不會(huì)有什么難度擂煞,各家的SDK都是介紹得很詳細(xì)的混弥,這里就貼一下各家的開發(fā)文檔地址。(傳送門:微信支付颈娜、支付寶支付剑逃、銀聯(lián)支付

6浙宜、死鎖的四個(gè)條件

  1. 互斥條件:進(jìn)程對(duì)所分配到的資源不允許其他進(jìn)程進(jìn)行訪問官辽,若其他進(jìn)程訪問該資源蛹磺,只能等待,直至占有該資源的進(jìn)程使用完成后釋放該資源
  2. 請(qǐng)求和保持條件:進(jìn)程獲得一定的資源之后同仆,又對(duì)其他資源發(fā)出請(qǐng)求萤捆,但是該資源可能被其他進(jìn)程占有,此事請(qǐng)求阻塞俗批,但又對(duì)自己獲得的資源保持不放
  3. 不可剝奪條件:是指進(jìn)程已獲得的資源俗或,在未完成使用之前,不可被剝奪岁忘,只能在使用完后自己釋放
  4. 環(huán)路等待條件:是指進(jìn)程發(fā)生死鎖后辛慰,必然存在一個(gè)進(jìn)程--資源之間的環(huán)形鏈

處理死鎖的基本方法

  • 預(yù)防死鎖:通過設(shè)置一些限制條件,去破壞產(chǎn)生死鎖的必要條件
  • 避免死鎖:在資源分配過程中干像,使用某種方法避免系統(tǒng)進(jìn)入不安全的狀態(tài)帅腌,從而避免發(fā)生死鎖
  • 檢測(cè)死鎖:允許死鎖的發(fā)生,但是通過系統(tǒng)的檢測(cè)之后麻汰,采取一些措施速客,將死鎖清除掉
  • 解除死鎖:該方法與檢測(cè)死鎖配合使用

7、Object的公共方法

眾所周知Java中所有的類都是繼承于Object五鲫,所以我們編寫的類默認(rèn)都具有這些方法溺职,包括有hashCode()wait()位喂、notify()浪耘、notifyAll()equals()塑崖、getClass()点待、toString()clone()弃舒、finalize()等癞埠。

  • hashCode()方法簡單地說就是返回一個(gè)integer類型的值,這個(gè)值是通過該Object的內(nèi)部地址(internal address)轉(zhuǎn)換過來的聋呢,這個(gè)哈希碼是可以通過getClass()方法看到具體值的苗踪,顯示的是十六進(jìn)制的數(shù),有時(shí)候可以通過此方法來判斷對(duì)象的引用是否相等削锰。
  • wait()用于多線程中通铲,使當(dāng)前線程等待該對(duì)象的鎖,當(dāng)前線程必須是該對(duì)象的擁有者器贩,也就是具有該對(duì)象的鎖颅夺。
  • notify用于喚醒在該對(duì)象上等待的某個(gè)線程朋截,notifyAll()用于喚醒在該對(duì)象上等待的所有線程。
  • equals()用于判斷這兩個(gè)引用是否指向的是同一個(gè)對(duì)象吧黄。
  • getClass()用戶獲取該對(duì)象的運(yùn)行時(shí)類的java.lang.Class 對(duì)象部服。
  • toString()方法返回一個(gè)字符串,它的值等于:getClass().getName()+ '@' + Integer.toHexString(hashCode())拗慨。
  • clone()保護(hù)方法廓八,實(shí)現(xiàn)對(duì)象的淺復(fù)制,只有實(shí)現(xiàn)了Cloneable接口才可以調(diào)用該方法赵抢,否則拋出CloneNotSupportedException異常剧蹂。
  • finalize()用于當(dāng)垃圾回收器確定不存在對(duì)該對(duì)象的更多引用時(shí),由對(duì)象的垃圾回收器調(diào)用此方法烦却。子類重寫finalize 方法宠叼,以配置系統(tǒng)資源或執(zhí)行其他清除。

** ---- End ---- 暫時(shí)記錄到這其爵,后面不定時(shí)更新冒冬,歡迎關(guān)注。**


寫在最后的話:個(gè)人能力有限醋闭,歡迎大家在下面吐槽窄驹。喜歡的話就為我點(diǎn)一個(gè)贊吧。也歡迎 Fork Me On Github 证逻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乐埠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子囚企,更是在濱河造成了極大的恐慌丈咐,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件龙宏,死亡現(xiàn)場(chǎng)離奇詭異棵逊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)银酗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門辆影,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人黍特,你說我怎么就攤上這事蛙讥。” “怎么了灭衷?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵次慢,是天一觀的道長。 經(jīng)常有香客問我,道長迫像,這世上最難降的妖魔是什么劈愚? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮闻妓,結(jié)果婚禮上菌羽,老公的妹妹穿的比我還像新娘。我一直安慰自己纷闺,他們只是感情好算凿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布份蝴。 她就那樣靜靜地躺著犁功,像睡著了一般。 火紅的嫁衣襯著肌膚如雪婚夫。 梳的紋絲不亂的頭發(fā)上浸卦,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音案糙,去河邊找鬼限嫌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛时捌,可吹牛的內(nèi)容都是我干的怒医。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼奢讨,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼稚叹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拿诸,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤扒袖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后亩码,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體季率,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年描沟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了飒泻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吏廉,死狀恐怖泞遗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情迟蜜,我是刑警寧澤刹孔,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響髓霞,放射性物質(zhì)發(fā)生泄漏卦睹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一方库、第九天 我趴在偏房一處隱蔽的房頂上張望结序。 院中可真熱鬧,春花似錦纵潦、人聲如沸徐鹤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽返敬。三九已至,卻和暖如春寥院,著一層夾襖步出監(jiān)牢的瞬間劲赠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工秸谢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凛澎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓估蹄,卻偏偏與公主長得像塑煎,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子臭蚁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容