面试题Five

1 finally和retrun

 public static void main(String[] args) {
                int result = m();
                System.out.println(result);//输出的是100为什么?

    }

    /*
        java语法规则(代码自上而下顺序执行)
        java语法规则(return语句一旦执行,整个方法必须结束)
        那么我们用反编译工具看看class文件为什么结果是100而不是101
        反编译之后的代码
        public static int m(){
              int i =100;
              int j = i;//这里他把i的的值赋给了j
              i++;
              return j;//最后返回了j

        }
        仔细思考下,代码自上而下执行,那么int i =100;下面的是不是return i?这里按照顺序就应该把i=100返回
        但是,return又是最后执行的,这里为了保证本来return的是一个100,并且后面finally里的i++也要执行,
        所以就把i的值赋给了j,返回了j(100),再执行i++ i的值变成了101



    */
    public static  int m(){
            int i = 100;
            try {
                return  i;//return是最后执行的,finally会先执行i++

            }finally {
                i++;
            }



    }

2 map集合

/*
map.put(k,v)实现原理
第一步:先将k,v封装到Node节点对象中
第二步:底层会调用k的hashCode()方法得出hash值
第三步:通过hash算法转换成数组的下标,下标位置如果没有任何元素
则把Node添加到这个位置上,如果说下标位置下对应有链表,此时会拿着k
和链表上每一个节点的k进行equals,如果所有的equals方法返回的都是false,
那么这个新节点会被添加到链表的末尾,如果有一个equals方法返回了true,
那么这个节点的value将会被覆盖

        v = map.get(k)
        先调用hashCode()得出hash值,hash算法转换成数组的下标,通过数组下标快速定位到某个位置,
        如果位置上什么都没有,返回null。
        如果这个位置上有链表,那么拿着参数k和链表上每个节点的k进行equals比较,如果equals返回false
        那么get返回null
        如果其中一个节点的k进行比较返回的是true,那么这个节点的value就是我们要返回的value


        放在HashMap集合的k部分实际上是放在HashSet集合中
        所以在HashSet集合中的元素同样需要重写equals()和hashCode()

        哈希表使用不当时无法发挥性能
        假设将hashCode()方法返回的hash值是固定的值,那么会导致底层哈希表变成了
        纯单向链表,这种情况称之为:散列分布不均匀
        什么是散列分布不均匀:假设有100个元素,10个单向链表,那么每个单向链表有十个节点,这就是最好的,
        散列分布均匀的,如果所有节点这里50个那里3,4个就分布不均匀

        那hash值全都不同可以吗?
        那底层就变成数组了,也是散列分布不均匀

        HashMap 集合的初始化容量为16,默认加载因子为0.75
        这个默认加载因子是当HashMap集合底层的数组容量达到75%,数组开始扩容,而不是满了才扩容

        重点:记住:HashMap集合初始化容量必须是2的倍数,这也是官方推荐的
        这是因为达到散列分布均匀,为了提高HashMap集合的存取效率,所必须的

        对于o1和o2,hash值相同,那么一定是放在同一个链表下的
        如果o1和o2hash值不同,经过hash算法算出的数组下标可能是同一个, 这时发生"哈希碰撞"
        就像数学7%3 = 1   4 %3 也是=1



 */

3 冒泡排序

 public static void main(String[] args) {

        //冒泡排序,最大的放在了右边
        // 比如三个数字  三个数字要比两次,才能把最大的放右边, 然后剩下2个数,再比一次,再把最大的数放右边
        //  a b  c     a 和b比  b 比较大 , 然后 b 和c 比, c 比较大
        //  下次剩下ab  a 和 b比   b 比较大

        int arr[] = {11,34,23,14,65};


        for(int i=arr.length-1;i>0;i--)//使用i--的方式  每比较一次排除掉一个最大数再进行下次比较
        {

            for(int j=0;j<i;j++)

            {
                if(arr[j]>arr[j+1]) {
                    int temp;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }

        for (int i = 0; i <arr.length ; i++) {
            System.out.println(arr[i]);
        }

    }

4 选择排序

 public static void main(String[] args) {

        int[] arr = {11,25,21,33,22,77,69};

        for (int i = 0; i <arr.length-1 ; i++) {

            int min =i;//每次都认为当前下标就是最小值
            for(int j=i+1;j<arr.length;j++) {

                if (arr[min] > arr[j]) {
                    min = j;//循环比较之后把最小值的下标给min
                }


                if (min != i)
                //上一个循环结束后判断min是否还等于一开始的i
                // 如果不等于,将此时最小值的下标和一开始假设当前是最小值的下标互换位置
              
                {
                    // 即如果此时最小值的下标为4,而一开始假设的最小值下标为0,
                    // 那么下标为4和下标为0的值互换,确保每次左边都是最小值
                    int temp;
                    temp = arr[min];
                    arr[min] = arr[i];//4 和0 互换
                    arr[i] = temp;//将最小值的下标放进了一开始假设的下标(相当于作弊)

                }
            }
        }

        for (int i = 0; i <arr.length-1 ; i++) {
            System.out.println(arr[i]);
        }


    }

5 二分查找法

 public static void main(String[] args) {

        //二分法是基于排序后查找
        int[] arr = {11,22,33,44,55,77,99};

        int index = binarySearch(arr,44);
        System.out.println(index==-1?"数组不存在":"下标"+index);



    }

    public static int binarySearch(int[] arr, int dest) {

            int begin =0;//开始下标
            int  end = arr.length-1;//结束下标
        while (begin<=end){//开始下标在结束下标的左边会一直循环

            int mid = (begin+end)/2;
            if(arr[mid]==dest){
                 return mid;//
            }
            if(dest>arr[mid]){
                begin = mid +1; //数组下标在右边
            }
            if(dest<arr[mid]){
                end = mid -1; //数组下标在左边
            }
            return  -1;//没有找到
        }
        return dest;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值