java 概述
何为编程
变成是让计算机解决某种问题而使用的程序涉及语言编写程序代码,得到解决
为了使计算机能够理解人的意图,人类通过一定手段告诉计算机,使计算机能够根据人的指令一步一步的去完成对应的任务,这种人和机器的交互过程叫做编程
变成又分为机器语言,和汇编语言,比如java 语言,是数据高级语言,由class文件交代给虚拟机,虚拟机转换高级汇编语言,变成机器语言,告知机器按照一步一步完成汇编语言的指令;
什么是java
java 是一门面向对象的汇编语言,属于汇编语言的一种;主张的是一次运行 到处编译。由虚拟机基础上,简化了变成的基类实现,和垃圾回收自动回收;方便了开发人员的代码编写使用。
java分为三个版本
- javaSE 主要作为部署桌面服务器,嵌入试试环境使用java 应用
- java EE 企业开发面向服务体系结构
- java ME 嵌入式设备开发比如手机,电视上运行的应用程序
关于虚拟机jvm jre jdk
- JVM 是java 的虚拟机,java程序编译为class 文件,需要在虚拟机上面运行
- JRE java运行环境,提供一些核心类库,基本数据,基本函数等
- JDK jdk包含jre 以及 jvm 是提供给开发人员使用,其中包含java开发工具,同时包括即实编译,打包工具等
java 为什么可以跨平台
java 跨平台的原因是 java编译为class文件,calss文件被虚拟机运行,也就是说只要系统安装了虚拟机,那么这个程序就可以运行
java 和 C++ 有什么区别
- C++ 和 java 其实都是面向对象语言,都支持封装继承多态
- java 是不提供指针访问内存的 但是C++ 支持指针访问内存
- java的类都是单继承的,但是C++支持多继承 java是有object基类的
- java 是不需要自己手动释放内存的,
基础语法
java 有那些数据类型 为什么有数据类型
java
基础类型有 : byte short int long float double char boolen
引用类型有 : 类 接口 数组
为什么有数据类型,是因为java语言是强类型语言,对于每一种数据,在内存中分配不同的空间
java中计算效率最快的方法是什么
java 最快的计算方式是直接对数据进行位计算处理,比如 2乘以8 可以可以用 2 << 3 2的三次方, 2除以8 可以用 2>>3
final finally finalize 区别
final 最终态,修饰类不能继承,修饰方法不能重写,修饰变量不可改变
finally 是try catch 代码块的最终必然执行的代发块
finallize 是通知行垃圾回收的一种方法
this 与 super区别
super 是关键字 只想父类。this 是指针指本对象里面的方法,构造以及属性
面向对象
面向对象的三大特征
抽象: 抽象是将一个类对象的共同特征抽离出来,抽象值关注 对象的那些属性行为,并不关注他的细节
封装:封装是把一个对象的方法隐藏起来,对外提供公共的访问方式
继承,继承是为了扩展,提高类的复用
多态,多态是指,每个类都有自己的独特处理方法,对于整体的所有下属类,比如猫科, 花猫狸猫。进行共有的方法,比如吃,喝等行为进行统一调用;
实现多态的三个必要调节,继承,重写,向上转型。
面向对象的五大基本原则
单一原则:
开闭原则:
依赖倒置原则:
接口分离原则
里式原则
普通类和抽象类有什么区别
普通类不能包含抽象方法,抽象类可以包含抽象方法
抽象类不能实例化,普通类可以实例化
衍生 抽象类可以使用final ,不行,原因是因为抽象类作为一个抽象不能实例化,是为了被其他类继承 加了final 失去了他的意义
为什么重写hashcode 需要 重写equals
hashcode的作用是为了获取哈希码,如果两个对象相等,那么hashcode 肯定是相等,但是如果两个hashcode相等,那么值不一定是相等的。因为hashcode 是散列值,有可能重复,所以重写hashcode 需要重写equals
关于值传递
方法中,有基本数据类型作为入参方法,也有引用类型,和对象,这种非基本数据类型在值传递中,是可以改变她的对象引用地址的。所以在写方法时候要注意入参判断
jdk 常用包
lang包基本数据类型
io包基础io
nio 同步非阻塞包
util 工具包
juc 并发包
sql 数据库操作类包
socket 套接字包
IO流
java io流分为 字节流和字符流, 同时兼顾了 输入流,和输出流。
input Stream / output Stream
reader / writer
正常流程,基础篇有博客,大致就是建立流通道,读取字节/字符, 循环到缓冲流, 写入输出流。然后刷新,最后关闭流通道
BIO NIO AIO 区别
BIO
Block IO 同步阻塞io 就是平常使用的io 他的特点是简单方便,并发处理能力低
NIO
Non IO 同步非阻塞IO 是对于传统IO 的升级,客户端和服务端通过Channer 通道通讯,实现多路复用
AIO
Asynchronous IO 也就是异步io 是基于事件和回调机制
BIO
数据读取写入必须阻塞在一个线程内等待完成,在活动数量特别高的的情况就会特别影响性能
NIO
提供了Channer selector buffer 等抽象,支持缓冲,和通道I/O 操作办法。对于低并发,可以使用,但是对于高并发 高负载,任然是性能较弱
AIO
就是基于时间回调实现,不会阻塞在哪里,当后台处理完成,操作系统会通知对应线程进行后续操作
Files 常用方法
- exists
- createFile
- delete
- move
- copy
- read
- write
- createDirectory
反射
反色机制是在程序运行状态,对于某个类的结构,任意调用拆解,这便是反射机制
反射场景有哪些
反射一般会跟注解想呼应,一版用于通过反射对于任意类型进行一些处理,比如增加插入时间等
同时无论那个框架,或者定义的自定义注解,可以在进行某一部操作需要对于特定字段进行拆解的时候,通过拆出注解标注的值进行对于此字段处理。同时springBoot 大量使用注解,用于选择器,和类加载扩展
集合
集合框架是java中常用的数据存储容器,由接口,实现类,以及算法形成。
要聊集合其实需要用原始类型数组作为存储单元。那么需要对齐做一个比较
- 数组是固定长度,集合是可边长度,达到一定算法值会进行扩容
- 数组是集合的基本存储类型,集合是可以存储基本存储类型,比如集合可以存储数组
- 数组存储是单一类型存储,但是集合可以通过算法,存储不同的数据类型
集合的基类是collection 集合 衍生出 list
set
queue
集合队列, 同时拥有对应集合的实现类。
关于键值对集合是由map
接口衍生出 hashMap
等键值对集合
- list 集合底层是数组,所以是有序的
- set集合是无序 不可重复因为他是通过hash 散列排列的
- treeSet 是有序的 且不可重复 因为在hashCode的基础上沿用了红黑树存储
- hashmap 是无序的,因为 key/value 存储。key也是hash散列的,对此维护了一个链表防止hash冲突 jdk 1.8 之后引入红黑树,对于高并发冲突降解io查询效率
如何确保一个集合不被修改
使用Collections 工具类的 unmodifiableCollection 创建只读集合。
list<String> list = new ArrayList<>();
list. add("x");
Collection<String> clist = Collections. unmodifiableCollection(list);
clist. add("y"); // 运行时此行报错
System. out. println(list. size());
说一下HashSet原理
HashSet 是基于HashMap 实现的, HashSet的值存放在 HashMap Key上
HashSet增加数据如何保证不可重复, 判断元素是否存在,比较HashCode值,比较 Equles
由于HashSet值是存放在HashMapKey上,如果重复,会覆盖旧值。所以HashCode的值不同所以是无序的,不保证有序;
关于Queue
BlockingQueque 是队列, 在进行检索或者移除元素的时候,他的等待队列变为非空,当添加元素,他会等待队列中的可用空间,
如何决定使用 HashMap 还是TreeMap?
对于在Map中插入、删除和定位元素这类操作,HashMap是 好的选择。然
而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,
也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历
HashMap 和 ConcurrentHashMap 的区别
-
ConcurrentHashMap对整个桶数组进行了分割分段(Segment),然后在每一个分段上都用lock锁进
行保护,相对于HashTable的synchronized 锁的粒度更精细了一些,并发性能更好,而HashMap
没有锁机制,不是线程安全的。(JDK1.8之后ConcurrentHashMap启了一种全新的方式实现,利用
CAS算法。并且锁升级了,不适用分段索使用synchronized ) -
HashMap的键值对允许有null,但是ConCurrentHashMap都不允许。
ConcurrentHashMap 底层具体实现
JDK1.7
首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据
时,其他段的数据也能被其他线程访问。
在JDK1.7中,ConcurrentHashMap采用Segment + HashEntry的方式进行实现。
一个 ConcurrentHashMap 里包含一个 Segment 数组。Segment 的结构和 HashMap类似,是一种数
组和链表结构,一个 Segment 包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素,每
个 Segment 守护着一个 HashEntry数组里的元素,当对 HashEntry 数组的数据进行修改时,必须首先
获得对应的 Segment的锁
在JDK1.8中,放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发
安全进行实现,synchronized只锁定当前链表或红黑二叉树的首节点
,这样只要hash不冲突,就不会产
生并发,效率又提升N 倍
Java中的队列都实现类有哪些
- ArrayDeque, (数组双端队列)
- PriorityQueue, (优先级队列)
- ConcurrentLinkedQueue, (基于链表的并发队列)
- DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQueue接口)
- ArrayBlockingQueue, (基于数组的并发阻塞队列)
- LinkedBlockingQueue, (基于链表的FIFO阻塞队列)
- LinkedBlockingDeque, (基于链表的FIFO双端阻塞队列)
- PriorityBlockingQueue, (带优先级的无界阻塞队列)
- SynchronousQueue (并发同步阻塞队列)