java基础、底层实现、面试

 

目录

1.String、StringBufer、StringBuilder

1.1 String

1.2 StringBuffer、StringBuilder

1.3 Efficiency

2. Interface and abstract class

3. 运算符

3.1. 移位运算符

4. List

4.1. ArrayList的扩容机制

 


 框架学再多,基础甚至底层都不会有什么用哟。面试的时候就只能说我会用框架,一问理论、底层就懵逼了。原来我只是会用,仅仅会用。自学了那么多框架,结果面试都过不了。多么嘲讽的。大学刚毕业的那时候,没有人告诉你需要做什么?虽然之前在某公司IT部独立负责三个项目的二次开发,依旧没能遇到引路人。就这样当条咸鱼,偶尔学学框架敲敲代码,甚至连BAT也没有想过。没有一点点的挣扎就随便选了一家公司然后开始了。

现在想来甚是后悔,就应该在大一的时候开始想要做什么?要学什么?要去哪里?然后开始准备了。

那就从现在开始,开始复习开始刷题吧!希望一年后能遇到更好的自己。

1.String、StringBufer、StringBuilder

String是只读字符串,典型的Immutable对象,对它的任何改动。起手都是创建一个新对象,再把引用指向该对象。String对象赋值操作后,会在常量池中进行缓存。如果下次引用的时候,该对象已经存在就会直接调用缓存池中。StringBuffer则是可以在原对象上进行修改,是线程安全的。StringBuffer和StringBuilder都是继承了AbstractStringBuilder。该抽象类也是以字符数组的形式存储字符串。StringBuilder线程不安全,但是效率比StringBuffer高。

1.1 String

String对象是不可变,也是不可继承的。如下源码中String是被final所修饰的。

public final class String
   
implements java.io.Serializable, Comparable<String>, CharSequence {
   
/** The value is used for character storage. */
   
private final char value[];

    /** Omit resource code ……  . */
}

String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.

String中的对象是不可变的,也就可以理解为常量, 显然线程安全

1.2 StringBuffer、StringBuilder

StringBuffer、StringBuilder都是继承AbstractStringBuilder类。

在AbStaractStringBuiler中使用字符数组保存字符串。可知这两种对象都是可变的。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;
    /** Omit resource code ……  . */
}

AbstractStringBuilder(int capacity) {
    value = new char[capacity];
}
/** --------StringBuffer Resource code-------------- */
public StringBuffer(int capacity) {
    super(capacity);
}
public StringBuffer() {
    super(16);
}

 StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立,  如: StringBuffer sb = new StringBuffer();

不能通过赋值符号对他进行付值. sb = "welcome to here!";//error

对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.StringBuffer中赋值的时候可以通过它的append方法.      sb.append("hello");

StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。

/** --------StringBuffer Resource code-------------- */
@Override
public synchronized int length() {
    return count;
}

@Override
public synchronized int capacity() {
    return value.length;
}

@Override
public synchronized void ensureCapacity(int minimumCapacity) {
    super.ensureCapacity(minimumCapacity);
}
/** --------Omit Resource code-------------- */

StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。 

使用场景:1. 操作少量数据: String  2. 操作大量数据、单线程: StringBuilder  3. 操作大量数据、多线程: StringBuffer

1.3 Efficiency

如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。  

效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高。

 

2. Interface and abstract class

参考CSDN文档:https://blog.csdn.net/aptentity/article/details/68942916 

参考CSDN文档:https://blog.csdn.net/Speed_Pig/article/details/71628368?locationNum=3&fps=1(1.8特性)

类型abstract classinterface
定义abstract class 关键词Interface关键字
继承抽象类可以继承一个类或者实现多个接口。子类只能实现一个抽象类接口类只可以继承接口(一个或者多个)。子类可以实现多个接口
访问修饰符

抽象方法可以有publicprotecteddefault这些修饰符

JDK1.8以前 抽象类的方法默认访问权限为protected,JDK1.8后,默认访问权限变为default.

接口方法默认修饰符是public abstract。你不可以使用其它修饰符。1.8版本允许定义static 、default
接口中的变量隐式声明为public static final
方法实现可以定义构造方法,抽象方法,具体方法接口完全抽象,没有方法体。1.8后允许在接口里面定义default,static方法体
实现方式子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的抽象方法的实现,可以选择所需的非抽象方法的实现。通过super去调用抽象类中的方法参数。子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
作用把相同的东西提取出来,即重用为了把程序模块进行固化的契约,是为了降低偶合

 

3. 运算符

3.1. 移位运算符

用最有效率的方式计算2乘以8

2  〈〈  3 

常见的JDK源码里面HashMap默认容量 16

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 = 1 * 2^4

直接二进制操作,表示1 左移4位,低位补0,即10000转化二进制位16。

在代码编写中,尽量使用移位运算符。虽然 DEFAULT_INITIAL_CAPACITY =16可能更直观!

栗子:

<< :左移运算符,num<< 1,不区分正负数,低位补0,相当于num*2
        4 << 1  // aka  4 * 2^1  = 8
        5<< 4  // aka  5 * 2^4  = 64
>> :右移运算符,num>>1,如果该数为正,则高位补0,若为负数,则高位补1
        64 >> 1  // aka 64 / 2    32
       64 >> 2   // aka 64 / ( 2 ^ 2) 16

4. List

4.1. ArrayList的扩容机制

注意:JDK1.7之前ArrayList默认大小是10,JDK1.7后是0

未指定集合容器,默认为0。若已指定大小则为所指定集合大小。当集合第一次添加元素时候,集合大小扩容为10。ArrayList的元素个数大于其容器,扩容的大小 = 原始大小 + 原始大小/2

首先认识ArrayList的重要变量:

数组每次新增时候,都会使用ensureCapacityInternal确保数组容量,使用该方法进行容量判断。之后将新增的元素添加到数组中,size++。

ensureCapacityInternal将判断委托给calculateCapacity获取当前容器所需最小的容量。(一般我写代码都是用放一起然后接收,再传参给下个函数,没有多处使用,这样想来一点都不好。要抽出公共代码模块)

扩容的实现方法grow方法:

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值