JAVA基础+入门+必须要掌握的知识

JAVA基础

面向对象三大基本特征

封装

  • 把客观事物封装成抽象类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏

继承

  • 可以让某个类型的对象获得另一个类型的对象的属性和方法

多态

  • 指一个类实例的相同方法在不同情形有不同的表现

五大原则

单一职责原则

  • 指一个类功能单一,不能包罗万象

开放封闭原则

  • 一个模块在扩展方面应该是开放的,而在更改方面应该是封闭的

替换原则

  • 子类应当可以替换父类,并且出现在父类出现的任何地方

依赖原则

  • 具体依赖抽象,上层依赖下层

接口分离原则

  • 模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来

==和equals的区别?

1、equals方法比较的是两个对象的内容
2、==比较的是两个对象是否为同一个对象,或者说比较的是对象的内存地址是否相同(对于基本类型,==比较的是两者的值是否相等,对于引用类型,==比较的是引用地址是否相同)


静态变量和实例变量的区别?

1、静态变量属于类,可通过类名直接调用静态变量
2、实例变量属于对象,必须产生该类的对象,才能调用实例变量


overload(方法重载)和override(方法重写)的区别?

方法重载发生在同一个类里面两个或者多个方法的方法名相同但是参数不同的情况
方法覆盖说到是子类重新定义了父类的方法,方法覆盖必须有相同的方法名、参数列表和返回值类型


abstract class和interface的区别?

1、接口中所有的方法隐含的都是抽象的,而抽象类可以同时包含抽方法和非抽象方法

2、类可以实现很多接口,但是只能继承一个抽象类

3、类如果要实现一个接口,那么必须要实现这个接口中的所有方法。但是类可以不实现抽象类中所有方法,当然这种情况下这个类也必须是抽象类。

4、Java接口中声明的变量默认都是final的,抽象类可以包含非final的变量

5、Java接口中成员函数默认都是public的,抽象类中可以有private protected 或者public

6、接口是绝对的抽象,不可以被实例化。抽象类也不可被实例化,但是如果他有main方法,是可以被调用的。


string stringBuilder 和stringBuffer的区别?

String是字符串常量,被final修饰。stringBuffer是线程安全的字符串变量;stringBuilder是线程不安全的变量。

string是不可变对象,每次对string类型进行操作等同于产生一个新string对象,所以尽量不要对string进行大量的拼接工作,否则会产生很多的临时对象,导致GC开始工作,影响系统性能。
StringBuffer和StringBuilder是对对象本身操作,而不是产生新对象。
注意:JVM对String拼接时会有一定的优化比如:String s = “hello”+“world”;
会被JVM直接优化成String s = “helloworld”,此时就不存在拼接的情况;


string的常见方法:
charAt(int index)
equals()
substing()
trim()
length()
indexOf()
endsWith()
startWith()
equalsIngorCase()
uppstring()
toLower()
toUpCase()


运行是异常和一般异常有什么不一样?

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的操作中可能遇到的异常,是一种常见的运行错误。
Java编译器要求方法必须抛出可能发生的非运行异常,但是并不要求必须声明抛出未捕捉的运行时异常。


深拷贝和浅拷贝的区别?

浅拷贝:被复制的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅复制所考虑的对象,而不复制他所引用的对象。
深拷贝:被复制对象的所有对象都含有原来的对象相同的值,而那些引用其他对象的变量将指向被复制过的新对象,而不再是原来的那些被引用的对象。换言之,深拷贝是把要复制的对象所引用的对象都复制了一遍。


equals()和hashCode()的联系?

hashCode()是object类的一个方法,返回一个hash值,如果两个对象根据equals()方法比较相等,那么调用这两个对象中任意一个对象的hashCode()方法产生肯定产生相同的哈希值。如果两个对象根据equals()方法比较不相等,那么产生的hash值不一定相等。


Collection和Collections的区别?

Collection是集合类的上级接口,继承他的接口主要有Set和List
Collections是针对集合类的一个帮助类,他提供一系列静态方法,实现对各种集合的搜索、排序、线程安全化的操作。


list和set的区别?

1、list和set都继承自collection接口
2、list元素放入有顺序,元素可以重复。set特点。元素放入没有顺序(无序是因为他的存放位置是由该元素的hashcode值决定的,是固定的),元素不可以重复;
3、list接口的实现类:LinkedList ArrayList Vector
set集合的实现类:HashSet, LinkedHashSet


Set集合如何保证不重复的?

1、判断两个对象的hashCode是否相等
如果不相等,则认为两个对象不相等,完毕;
如果相等,转到2
2、判断两个对象的equals()是否相等
如果不相等,则认为两个对象不相等

hashCode主要是为了提高存储效率。


进程和线程的区别?

一个进程是一个独立的运行环境,他可以被看做是一个程序或者一个应用。而线程是在进程中执行的一个任务。Java环境是一个包含了不同的类和程序的单一进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源。

线程有哪些状态?

线程在执行过程中,可能处于下面几种状态:
就绪:线程准备运行,不一定立马就能开始执行。
运行中:进程正在执行线程的代码。
等待中:线程处于阻塞状态,等待外部的处理结束。
睡眠中:线程被强制睡眠
i/o阻塞:等待i/o操作完成
同步阻塞:等待获取锁
死亡:线程完成了执行。

线程同步的方法有哪些?

1、synchronized关键字修饰方法
2、synchronized关键字修饰语句块
3、使用重入锁Lock类实现线程同步
4、使用ThreadLocal管理变量实现线程同步
5、使用阻塞队列
6、使用原子变量

如何保证几个线程有序执行?

1、共享对象锁,可以保证每个方法只能有一个线程进入,配合wait和nitifyall方法,可以启动或者换线线程
2、通过主线程join()

Java中wait和sleep方法有何不同?

1、这两方法来自不同的类分别是:Thread和Object
2、sleep没有释放锁,而wait方法有释放锁,使得其他线程可以使用同步控制块或者方法
3、wait notify 和notifyAll只能在同步控制方法或者同步指控块中使用,而sleep方法可以在任何地方使用。
4、sleep方法必须捕获异常,而wait,notify和notifyAll不需要捕获异常。

yield()方法:

调用yield()方法会让当前线程交出CPU权限,让CPU去执行其他线程,他跟sleep()方法类似,同样不会释放锁。但是yield()不能控制具体交出CPU的时间,另外yield()方法只能让拥有相同优先级的线程有获得CPU执行时间的机会,另外yield()方法不会让线程进入阻塞状态,而是让线程重新回到就绪状态,它只需等待重新获取CPU执行时间,这一点和sleep()不一样。


ThreadLocal有什么用?

他是一个创建线程局部变量的类,简单说ThreadLocal就是一种以空间换时间的做法,在每一个Thread里面维护了一个以开放地址法实现的ThreadLocal.ThreadLocalMap,把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了。


线程中同步和异步的区别?

同步:A线程要去请求某一个资源,但是此资源正在被B使用,因为同步机制的存在,A线程请求不到资源,只能等待。

异步:A线程要去请求某一个资源,但是此资源正在被B使用,因为没有同步机制的存在,A线程仍然能请求到资源,无需等待。

简述线程局部变量ThreadLocal?

线程局部变量是局限于线程内存的变量,属于线程自身所有,不在多个线程之间共享,是一种实现线程安全的方式。


简述Java多线程的悲观锁和乐观锁?

悲观锁:就是不管是否发生多线程冲突,只要存在这种可能,就每次访问都加锁,加锁就会导致锁之间的争夺,有争夺就有输赢,输者等待。

乐观锁:获得锁后一直持有锁以防本线程再次申请该锁造成无畏的解锁再加锁的开销。


finalize()方法什么时候被调用以及作用?

在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法。一般建议在该方法中释放对象持有的资源。


简述类加载机制以及加载过程?

类从被加载到虚拟机内存中开始,直到卸载出内存为止,他的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中验证、准备和解析这三个部分统称为连接(linking)。

加载:加载阶段由类加载器完成,起主要作用如下:
(1)获取定义此类的二进制字节流
(2)将这个字节流所代表的静态存储结构转换 为方法区的运行时数据结构
(3)在Java堆中生成一个代表这 个 类 的Java.lang.Class对象

验证:验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身的安全。
准备:是为类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法区中进行分配
解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程
初始化:初始化阶段是执行类构造器()方法的过程。

Java的8种基本数据类型?


								占用字节
byte						1
short						2
int							4
long						8
float						4
double						8
char						2
boolean						1/8
=======================
1byte 		= 	8it
1024byte	=	1kb
1024kb	   	= 	1M
1024m 		= 	1G

Map和ConcurrentHashMap的区别:

ConcurrentHashMap对整个桶数组进行了分割分段,即segment,然后在每段上都用lock锁进行保护,相对于HashTable的synchronized关键字锁的颗粒度要更精细,并发性能要更好,而HashMap没有锁机制,是线程不安全的,HashMap键值可以允许null,但是ConcurrentHashMap都不允许!


简述http协议?

HTTP:超文本传输协议,是一种基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式。
http请求头由3部分组成:分别是:请求行、消息报头、请求正文,响应也分为三部分,状态行(包含http版本、状态码、状态码的原因短语)、响应首部字段、响应内部实体。


重定向和转发的区别?

1、重定向是客户端的行为,转发是服务器的行为
2、重定向两次请求两次响应,转发一次请求一次响应
3、重定向可以跳到任意网站,转发只能在服务器内部进行转发
4、重定向会导致request对象信息丢失,转发不会


cookie和session的作用、区别?

1、cookie数据保存在客户端,session保存在服务端
2、cookie是不安全的,别人可以分析存放在本地的cookie并进行cookie欺骗,所以重要的数据应该使用session,存放在服务端。
3、session会在一定时间内保存在服务器上,但是会占用内存资源,当访问的用户过多,会加重服务器的负担,考虑到服务器的压力,应该将不重要的数据存放到cookie上。
4、当个cookie保存的数据不能超过4K。


集合(Collection)

单列集合

List

ArrayList

底层数组实现,查询快,增删慢,不安全,效率高

默认容量是10,扩容后增加50%

LinkedList

底层链表实现,查询慢,增删快,不安全,效率高

Vector

底层数据实现,增删改查都慢,但是安全

默认容量10,默认加载因子1,扩容后是原容量的1倍

Set

HashSet

底层HashMap,子类LinkedHashSet底层链表实现

默认容量是16,加载因子0.75,扩容是1倍

TreeSet

可以排序,底层二叉树算法实现

双列集合

Map

HashMap

底层hash算法,针对键,允许null键和值,线程不安全,效率高,键不能重复存储,值可以

默认容量是16,加载因子0.75,扩容后是原来的1倍

TreeMap

底层是二叉树,针对键,可以排序

LinkedHashMap

底层是哈希算法,和HashSet一样键唯一,值可以改变。

Dictionary

HashTable

不允许null键和值,线程安全,效率低

默认容量是11,扩容是2倍+1


线程池

1、corePoolSize

核心线程数

在创建线程池后,默认情况下,线程池中并没有任何线程而是等待有任务到来时才回去创建线程然后取执行任务。
默认情况下,在创建线程池后,线程池中的线程数为0,当一个任务来之后,就会创建一个线程去执行任务,当线程池中的线程数达到corePoolSize后,就会把到达的任务缓存到队列中,当有线程空闲时再分配任务执行。

2、maxiumPoolSize

线程池允许创建的最大线程数

线程池允许创建的最大线程数,如果队列满了,但已创建的线程数小于最大线程数,则线程池会再创建新的线程去执行任务。

但如果使用的是无界队列,这个参数就没有效果!

3、keepAliveTime

表示线程没有任务执行时最多保持多久时间终止

表示线程没有任务执行时最多保持多久时间会终止。
默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,知道线程池中的线程数不大于corePoolSize。

也就是说这个参数使作用于 大于corePoolSize小于maxiumPoolSize的线程的。

4、TimeUnit

时间单位:一共有7种,纳秒,微妙,毫秒,秒,分,小时,天

5、workQueue

保存等待执行任务的阻塞队列

synchronousQueue
标记: 优先级 1

这个队列收到任务的时候,会直接提交给线程去处理,而不是保留它,如果所有线程都在工作,那么就创建线程。所以为了保证不出现线程数达到了maxiunPoolSize而不能创建线程的错误,使用这个队列的时候一般讲maxiunPoolSize指定为Integer.MAX_VALUE,即无穷大。

LinkedBlockingQueue
标记: 优先级 2

这个队列接收到任务的时候,如果当前线程数小于corePoolSize,则新建线程来处理,如果当前线程数等于核心线程数,则进入队列等待,这就导致了maxiumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize。

ArrayBlockingQueue
标记: 优先级 3

可以设定队列的长度,接收到任务的时候,如果没有达到corePoolSize,则新建线程,如果达到了,则进入队列等待,如果队列又满了,则新建线程,如果总线程数达到了maxiumPoolSize,并且队列也满了,则报错。

DelayQueue
标记: 优先级 4

队列内元素必须实现Delayed接口,这就意味着你传进去的任务必须实现Delayed接口,这个队列接收到任务后,首先进入队列,只有达到了指定时间,才会执行任务。

6、ThreadFactory

线程工厂,主要用来创建线程

7、RejectedExecutionHandler

当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认是(1)AbortPolicy,表示无法处理新任务是抛出异常。一共4种,另外3种为:(2)DiscardPolicy表示丢弃任务但不抛出异常。(3)DiscardOldestPolicy表示丢弃队列最前面的任务,然后重新尝试执行任务。(4)CallerRunsPolicy表示由调用线程处理该任务。

发布了4 篇原创文章 · 获赞 4 · 访问量 103

猜你喜欢

转载自blog.csdn.net/qq_40585384/article/details/105376604