JAVA基础

ArrayList和数组有什么区别?ArrayList的扩容机制

  1. 数组在内存中是连续的,查找较快,但在创建数组时需要指定其大小,在进行添加删除等操作时都比较麻烦。
  2. ArrayLsit底层是一个数组,可以动态进行扩容,可以很方便的进行数据的添加和删除。但是Arraylist中使用的是Object类,进行装箱与封箱时会比较消耗资源。

包装类与自动装箱拆箱

  1. JAVA是面向对象的语言,然而基本数据类型并不是面向对象的,所以将基本数据类型变成包装类进行使用。
  2. 装箱是指:将基本数据类型变成对应的包装类。
    拆箱是指将包装类变成对应的基本数据类型。
    自动装箱是指在编译期间采用Integer.valueOf(i)将其变成包装类
    自动拆箱是指在编译期间采用i.intValue()方法将其变成基本数据类型。

项目中主要用到的设计模式

主要有使用到spring框架。

  1. 单例模式
  2. 工厂模式 beanFactory,applicationContex bean工厂
  3. AOP 代理模式
  4. jdbc tmpalate 模板模式

object下的方法

  • getClass 方法 native final 方法
  • hashcode 方法:在一个对象没有改变的情况下,他的hash值应该是一直不变的。如果equals相等他的hash值一定是相等。如果equals不等,哈希值可以相等。
  • equals 方法
    == 对于基本数据类型 比较的是两者的值是否相等。如果是对象之间的比较,比较的是地址是否相等。
    equals 方法是比较地址是否相等。string重写了equals方法,会比较string中的值是否相等。
  • clone方法
  1. 浅拷贝 对于基本数据类型来说浅拷贝相当于一个值传递,对于引用对象来说只是进行了引用的传递。
  2. 深拷贝 在拷贝的过程中创建了一个新的内存地址来存放新的对象。
    采用clone方法要实现cloneable接口 并且在object中使用protected来修饰 同时也要重写该方法来扩大其范围,不然会报错。
  • wait notify notifyall sleep没有释放锁 wait释放锁
  • tostring方法
  • finalize方法 在垃圾回收的时候会调用该方法。

runtime Exception 和 非runtime Exception

  • runtime Exception 运行时异常:空指针异常,数组越界 算数异常
  • 非runtime Exception 编译器异常

OOM 内存溢出

堆溢出 new了很大的对象 调整xmx xms参数
栈异常 stackOverflow 递归没有出口
元空间溢出 大量的class信息 出现大量的jsp页面或者cglib增强信息 调整maxpermsize信息。

重载与重写

重载是一个方法的不同实现。方法名称相同,输入参数,返回值类型都可以不同。
重写是子类对父类的一个方法功能的拓展。方法名称 输入参数都应该不相同。返回值范围 异常抛出的范围都应该小于等于父类。
编译器无法决定调用哪个重写的方法,因为只从变量的类型上是无法做出判断的,要在运行时才能决定;但编译器可以明确地知道该调用哪个重载的方法,因为引用类型是确定的,参数个数决定了该调用哪个方法。
多态针对的是方法的重写。

“==”与equals方法的不同

== 分为基本数据类型的比较与对象的比较。基本数据类型比较的是值大小,对象比较的是两个引用是否指向同一块地址。
equals 方法如果没有重写的话也是比较内存值。如果重写了 String方法判断的就是char[]数组里面的数值是否是一致的。

static与final关键字

static 一般在类加载时就初始化完成。static意为静态的,被static修饰的说明属于类,方便在没有创建对象时使用,通过类名.直接调用
static可以修饰内部类。

InnerClass inner = new Inner.Innerclass();

static可以修饰变量,说明是类变量。修饰方法
static也可以修饰代码块 静态代码块在类第一次被加载的时候会运行。

final关键字修饰基本数据类型 表明基本数据类型是常量不可以被修改 可以不赋初始值 但是在构造的时候必须赋值
修饰引用类型 引用对象不可以更改不能指向其他对象,但是引用对象的内容可以被修改。
修饰方法 方法不可以被重写 但是可以被访问
修饰类 不可以被继承

static final取两者的共同体
修饰内部类
修饰变量 是类变量并且不可以被修改
修饰方法

接口与抽象类

抽象类是对类的抽象,更多的在于模板的设计。接口是行为的抽象,更多的是对行为的规范。只能继承一个类,却可以实现多个接口。
如果一个类中有抽象方法的存在就被称为抽象类,必须得用abstract关键字来修饰。
抽象类中不一定必须要有抽象方法,抽象类中同时也可以有具体的方法实现。
抽象类不能用来创建对象,子类继承抽象类必须全部实现父类的抽象方法。
接口中可以有方法和变量,会被隐式的指定为public static final 方法会被指定为public
接口中必须为抽象方法 不能有具体的方法实现 且子类如果不是抽象类实现接口的时候需全部实现接口中的方法。
在java8的时候可以有具体的静态方法。

hashmap的遍历方式

  • map.keySet() for each
for (String key : map.keySet()) {
System.out.println("key= "+ key + " and value= " + map.get(key));
}
  • map.values
  • iterator
Iterator iterator=map.entrySet().iterator();
  • 映射成set去遍历
  for (Map.Entryentry:map.entrySet()){
            System.out.println("key:"+entry.getKey()+"------value:"+entry.getValue());
        }

java异常处理

  • error 错误。一般是指运行代码时JVM会出现问题,导致线程终止。比如内存不足 OOM
  • exception异常 分为runtime运行异常 chechedException编译器异常。

线程实现

  • 继承Thread类 重写run方法 调用start方法来启动线程
  • 实现Runnable接口
    实现Runnable接口优于继承Thread类。可以实现多个接口,继承的话只能继承一个类。Runnable更容易实现资源共享,能多个线程同时处理一个资源。
  • 实现callable接口 实现call方法 创建线程后有返回值。

线程终止 thread.stop会导致所有的已锁定的监听器解锁,有缺陷 采用interrupt

JAVA迭代器

实现Collections 接口的集合都有iterator方法,用来遍历集合。主要有hasnext()、next()、remove()方法
listIterator继承自iterator接口,专门针对list对象。
Iterator与listIterator区别

  • Iterator可以用于遍历list、set。listIterator只可以用来遍历list。
  • Iterator只可以向后遍历,listIterator既可以向后遍历又可以向前遍历。
  • listIterator实现了更多方法,比如add方法。

fail-fast机制 :快速失败

当在使用Iterator迭代器进行遍历时 如果使用add方法添加元素会抛出异常。

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

是通过 modCount和expectedModCount来判断是否抛出异常。当在遍历过程中对集合中元素进行增加删除会改变modCount来抛出异常。

fail-safe机制 安全失败机制

采用fail-safe机制的集合在遍历集合时并不会直接访问原集合,而是创建一个副本,在拷贝的集合上进行遍历,所以在遍历过程中可以对集合进行修改,但不能访问到修改值。

你可能感兴趣的:(JAVA基础)