第一次安卓面试总结

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插入的数据直接覆盖了,如此一来就造成了线程不安全问题.
  • 第二就是如果多个线程同时检测到元素个数超过数组大小*loadFactor,这样就会发生多个线程同时对Node数组进行扩容,都在重新计算元素位置以及复制数据,但是最终只有一个线程扩容后的数组会赋给table,也就是说其他线程的都会丢失,并且各自线程put的数据也丢失。
    关于HashMap线程不安全这一点,《Java并发编程的艺术》一书中是这样说的:

HashMap在并发执行put操作时会引起死循环,导致CPU利用率接近100%。因为多线程会导致HashMap的Node链表形成环形数据结构,一旦形成环形数据结构,Node的next节点永远不为空,就会在获取Node时产生死循环。

  • 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 = new HashMap<>();
        for (int i=0;i<nums.length;i++){
            if (map.containsKey(nums[i])){
                map.put(nums[i],map.get(nums[i])+1);
            }else {
                map.put(nums[i],1);
            }
            if (map.get(nums[i])>nums.length/2){
                return nums[i];
            }
        }
        return 0;
    }
}

8.现场手写一个排序算法,要求这个排序算法,是nlogn的复杂度

https://blog.csdn.net/nrsc272420199/article/details/82587933



public class QuickSort {
    public static void main(String[] args) {
        int[] a = {5, 8, 4, 2, 6, 1, -2, 8};
        quicksort(a, 0, a.length - 1);
        for (int i : a) {
            System.out.print(i + " ");
        }
    }

    private static void quicksort(int[] a, int low, int high) {
        if (low < high) {
            int index = getIndex(a, low, high);
            quicksort(a, low, index - 1);
            quicksort(a, index + 1, high);
        }
    }

    private static int getIndex(int[] a, int low, int high) {
        int tmp = a[low];
        while (low < high) {
            while (low < high && a[high] >= tmp)
                high--;
            a[low] = a[high];

            while (low < high && a[low] <= tmp)
                low++;
            a[high] = a[low];
        }
        a[low] = tmp;
        return low;
    }
}

9.单例模式

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

10.有什么要问的

本次体会:

1.刷算法要掌握最优解法,不一定要难题,但一定要把一道简单地算法掌握最优的那种解法.因为考官只关注你的解法是不是最优的,基本解法谁都会,还有就是及时复习算法题,不然有些题我原来做过,但是面试时忘记了.

2.别把自己定义为实习生就不该了解那些难的,因为面试官似乎对难的东西才有问的热情,简单的不待问.

3.这是我第一次面试,可能以后面试会简单一些,但是只有提升自己才有进好公司的机会,继续加油吧.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值