『查漏补缺』Android实习面试知识点(一)

『查漏补缺』Android实习面试知识点 - 2022/06/04

个人语录:人生的艰难困苦我们无法选择,但是可以选择让自己无坚不摧,战无不胜,时间不负有心人,星光不问赶路人

最近面试有点多,自己也没那么多时间对每一个题进行总结,所以这次只是选择了自己面试过程中没有答出来的,或者回答的不是很好的进行回顾和总结

文章目录

  • 『查漏补缺』Android实习面试知识点 - 2022/06/04
    • 单链表删除某一个元素
      • C++ erase函数 吧
      • Java for循环
      • Java 迭代器
    • Integer常量池
    • 拆箱和装箱带来的性能问题

单链表删除某一个元素

C++ erase函数 吧

#include 
#include 
using namespace std;

int main()
{
    // 初始化变量
    int int_erase = 3;
    list<int> list_int = { 1, 4, 3, 5, 9, 3, 6, 8, 3, 2, 6 };

    // 循环链表,删除元素
    list<int>::iterator itor;
    for (itor = list_int.begin(); itor != list_int.end(); )
    {
        if (*itor == int_erase)
        {
            itor=list_int.erase(itor);  // 一定要保存这个迭代器
        }
        else
        {
            cout << *itor << ", ";
            itor++;
        }
    }
    cout << endl;

    return 0;
}

Java for循环

        for (int i=0;i<list.size();i++){
            if (list.get(i).equals(8)){
                list.remove(i);
                i--;  // i一定要减减
            }
        }

Java 迭代器

  1. 使用iterator()来返回一个Iterator。
  2. 使用hasNext()检查序列中是否还有元素。
  3. 使用next()获得序列中的下一个元素。
  4. 使用remove()将迭代器新近返回的元素删除。
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
            Integer integer = iterator.next();
            if (integer.equals(8))
                iterator.remove();
        }

Integer常量池

浅看一下案例:

public class IntegerTest {
    public static void main(String[] args) {
        Integer i1 = 100;
        Integer i2 = 100;
        System.out.println(i1 == i2);
        Integer i3 = 200;
        Integer i4 = 200;
        System.out.println(i3 == i4);
        Integer i5 = 100;
        Integer i6 = new Integer(100);
        System.out.println(i5 == i6);
    }
}

浅看一下结果:

『查漏补缺』Android实习面试知识点(一)_第1张图片

解释:

Integer包装类有默认常量缓存池,范围是-128到127;

当==比较的数组在这个范围内,就可以直接使用缓存池中的数据,从而节省内存。

执行代码段

Integer i1 = 100;

实际上执行的是

Integer i1 = Integer.valueOf(100);

Integer.valueOf对于-128-127之间的数字,始终返回相同的实例

因此比较恰好为true时,不能以为Java标准库的Integer内部有缓存池就用比较,必须用equals()方法比较两个Integer.

Integer.valueOf()源码

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

可以看到,在通过 valueOf() 方法创建 Integer 对象的时候,如果数值在 [-128,127] 之间,便返回指向 IntegerCache.cache 中已经存在的对象的引用;否则创建一个新的 Integer 对象。 i1 和 i2 的数值 100,因此会直接从 cache 中取已经存在的对象,所以 i1 和 i2 指向的是同一个对象,而 i3 和 i4 则是分别指向不同的对象。[-128,127] 这个范围便是 Integer包装类的默认缓存池,也可称为 Integer 常量池。

拆箱和装箱带来的性能问题

先看一段代码:

public class IntegerTest {
    public static void main(String[] args) throws Exception {
        autoboxing();
        unboxing();
        toObject();
        toData();
        integerTranfer();
        intTranfer();
    }
    public static void autoboxing(){
        long starttime = System.currentTimeMillis();
        Integer number;
        for(int i=0;i<100000000;i++){
            number=i;
        }
        System.out.println("自动装箱的时间: "+(System.currentTimeMillis()-starttime)+"ms");
    }

    public static void unboxing(){
        long starttime = System.currentTimeMillis();
        int number;
        for(Integer i=0;i<100000000;i++){
            number=i;
        }
        System.out.println("自动拆箱的时间: "+(System.currentTimeMillis()-starttime)+"ms");
    }

    public static void toObject(){
        long starttime = System.currentTimeMillis();
        Integer number;
        for(int i=0;i<100000000;i++){
            number=(Integer)i;
        }
        System.out.println("强制类型转换为Integer: "+(System.currentTimeMillis()-starttime)+"ms");
    }

    public static void toData(){
        long starttime = System.currentTimeMillis();
        int number;
        for(Integer i=0;i<100000000;i++){
            number=i.intValue();
        }
        System.out.println("Integer转换为基本数据类型: "+(System.currentTimeMillis()-starttime)+"ms");
    }

    public static void integerTranfer(){
        long starttime = System.currentTimeMillis();
        Integer number;
        for(Integer i=0;i<100000000;i++){
            number=i;
        }
        System.out.println("Integer类型赋值运算: "+(System.currentTimeMillis()-starttime)+"ms");
    }

    public static void intTranfer(){
        long starttime = System.currentTimeMillis();
        int number;
        for(int i=0;i<100000000;i++){
            number=i;
        }
        System.out.println("int类型赋值需要时间 "+(System.currentTimeMillis()-starttime)+"ms");
    }
}

运行结果:

『查漏补缺』Android实习面试知识点(一)_第2张图片

1.基本数据类型的运算要远远快于装箱拆箱的运算(对象是不能直接运算的,它必须转换成基本类型再进行运算,然后再装箱成对象),在编程时,要尽量避免装箱拆箱和运算
同时进行。
2.装箱拆箱和强制转换的效率比较其实差不了多少,属于同一数量级的。

1、什么是装箱?什么是拆箱?

装箱:基本类型转变为包装器类型的过程。
拆箱:包装器类型转变为基本类型的过程。

//JDK1.5之前是不支持自动装箱和自动拆箱的,定义Integer对象,必须
Integer i = new Integer(8);

//JDK1.5开始,提供了自动装箱的功能,定义Integer对象可以这样
Integer i = 8;

int n = i;//自动拆箱

2、装箱和拆箱的执行过程?

装箱是通过调用包装器类的 valueOf 方法实现的
拆箱是通过调用包装器类的 xxxValue 方法实现的,xxx代表对应的基本数据类型。
如int装箱的时候自动调用Integer的valueOf(int)方法;Integer拆箱的时候自动调用Integer的intValue方法。

3、常见问题?

整型的包装类 valueOf 方法返回对象时,在常用的取值范围内(-128~127),会返回缓存对象。
浮点型的包装类 valueOf 方法返回新的对象。

你可能感兴趣的:(Android,面试,面试,java,职场和发展)