第一次安卓面試總結

今天面了一家武漢的公司,具體名字不說了,因爲我是面實習生,心裏就想着實習生問點簡單地就好,然後就準備了關於安卓的一些基礎知識.當時還專門去總結了下網上常見的面試題,面試前模擬題,就覺得差不多了,結果…一個都沒問到…,一上來就是數據結構和算法…,所以這次面試我表現很差,我自己都看不下去,問題是我當時刷題就是做出來就可以,沒想過非要最優解,結果面試官只問最優解的方法.所以總結一下,免得以後再在面試官面前丟臉.(答不出來支支吾吾是真得很丟臉,那種感覺好差)

1.自我介紹

2.要求從一個數組中找兩個數和爲100,但是要求複雜度必須是O(n)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],i);
        }
        for (int i=0;i<nums.length;i++){
            int num = target - nums[i];
            if (map.containsKey(num)&&map.get(num)!=i){
                return new int[]{i,map.get(num)};
            }
        }
        return new int[]{};
    }
}

3.如何判斷一個鏈表中有沒有環

一個每次走一步,一個每次走兩步,如果有環,走兩步的肯定會追上走一步的

public static boolean hasCircle(ListNode head) {
        if(null == head) {
            return false;
        }
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;//兩個指針相遇
            }
        }
        return false;
    }

4.哈希表的算法是怎麼實現的?

一般散列算法會根據輸入值計算出輸出應該存儲的位置,這個位置如果和已經存儲鍵值衝突則需進行重新映射.

當發生衝突時散列函數爲:Di=(H(k)+di) mod m

m爲存儲空間

di取指:

a)1,2,3,…m-1,稱線性探測再散列。

b)1,-1,2,-2,4,-4,9,-9,16,-16,…kk,-kk(k<=m/2)稱二次探測再散列。

c)鏈地址法:把據喲相同散列地址的元素用一個線性鏈表鏈接在一起,每個線性鏈表稱之爲一個“桶”,爲了處理方便每個鏈表前設置一個頭結點,所有頭結點存放於散列地址在[0,m-1]的散列表中。如下圖所示:

5.HashMap多線程安全嗎?爲什麼?Synchronized和Lock的區別?

  • 線程不是安全的,因爲假設有線程A和線程B同時對HashMap進行PUT操作,假設A和B插入的Key-Value中key的hashcode是相同的,這說明該鍵值對將會插入到Table的同一個下標的,也就是會發生哈希碰撞,此時HashMap按照平時的做法是形成一個鏈表(若超過八個節點則是紅黑樹),現在我們插入的下標爲null(Table[i]==null)則進行正常的插入,此時線程A進行到了這一步正準備插入,這時候線程A堵塞,線程B獲得運行時間,進行同樣操作,也是Table[i]==null , 此時它直接運行完整個PUT方法,成功將元素插入. 隨後線程A獲得運行時間接上上面的判斷繼續運行,進行了Table[i]==null的插入(此時其實應該是Table[i]!=null的操作,因爲前面線程B已經插入了一個元素了),這樣就會直接把原來線程B插入的數據直接覆蓋了,如此一來就造成了線程不安全問題.
  • Synchronized持有鎖資源,會自動釋放鎖;
  • Lock要手工釋放,而且必須在finally從句中釋放,tryLock()方式可以非堵塞方式是拿鎖;
  • 當競爭激烈時,Synchronized會升級爲重量級鎖,出對速度比Lock要慢,所以Lock效率更高.

6.判斷是否是迴文,但是要求不用字符串解決

左邊一半,右邊一半相反,如果相同,就是迴文

class Solution {
    public boolean isPalindrome(int x) {
      if(x < 0 || (x % 10 == 0 && x != 0)) 
            return false;
        int revertedNumber = 0;
        while(x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
            System.out.print(revertedNumber+" ");
        }
         //偶位數/奇位數
         return x == revertedNumber || x == revertedNumber/10;      
    }
}

7.判斷一個數據在一個數據中是否佔據了一半,要求複雜度O(n)

class Solution {
    public int majorityElement(int[] nums) {
       Map<Integer,Integer> map = countNums(nums);
       Map.Entry<Integer,Integer> majorentry = null;
       for(Map.Entry<Integer,Integer> entry : map.entrySet()){
           if(majorentry == null || entry.getValue() > majorentry.getValue()){
               majorentry = entry;
           }
       }
       return majorentry.getKey(); 
    }

    private Map<Integer,Integer> countNums(int[] nums){
        Map<Integer,Integer> map = new HashMap();
        for(int num : nums){
            if(!map.containsKey(num)){
                map.put(num,1);
            }else{
                map.put(num,map.get(num)+1);
            }
        }
        return map;
    }
}

8.現場手寫一個排序算法,要求這個排序算法,是logn的複雜度

public class QuickSort {
    public static int[] quicksort(int[] arr,int start,int end) {
        int remark = arr[start];
        int temp;
        int left = start;
        int right = end;
        while (left<right) {
            while (arr[left] < remark && left < right)
                left++;
            while (arr[right] > remark && left < right)
                right--;
            if (left<=right){
                temp = arr[left];
                arr[left] = arr[right];
                arr[right] = temp;
                left++;
                right--;
            }
        }
        if (right>start)
            quicksort(arr,start,right);
        if (left<end)
            quicksort(arr,left,end);
        return arr;
    }
}

9.單例模式

https://blog.csdn.net/absolute_chen/article/details/93380566

10.有什麼要問的

本次體會:

1.刷算法要掌握最優解法,不一定要難題,但一定要把一道簡單地算法掌握最優的那種解法.因爲考官只關注你的解法是不是最優的,基本解法誰都會,還有就是及時複習算法題,不然有些題我原來做過,但是面試時忘記了.

2.別把自己定義爲實習生就不該瞭解那些難的,因爲面試官似乎對難的東西纔有問的熱情,簡單的不待問.

3.這是我第一次面試,可能以後面試會簡單一些,但是隻有提升自己纔有進好公司的機會,繼續加油吧.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章