JavaSE

概念积累

接口和抽象类区别

接口=规范(属性:public static final;方法:抽象方法);抽象类=规范+实现

接口和抽象类均可多态(父类定义,子类实现),但抽象类只能单继承,接口可以多个实现;抽象类可实例化对象,接口无构造函数,不能实例化;抽象类可以不包含抽象方法,但接口只能有抽象方法。

内部类

要想访问内部类中的内容,必须通过外部类对象来实例化内部类。能够访问外部类所有的属性和方法,原理就是在通过外部类对象实例化内部类对象时,外部类对象把自己的引用传进了内部类,使内部类可以用通过Outer.this去调用外部类的属性和方法,一般都是隐式调用了,但是当内部类中有属性或者方法名和外部类中的属性或方法名相同的时候,就需要通过显式调用Outer.this了。

局部内部类是在一个方法内部声明的一个类。局部内部类中可以访问外部类的成员变量及方法。局部内部类中如果要访问该内部类所在方法中的局部变量,那么这个局部变量就必须是final修饰的

异常

多个catch:先小后大,按顺序匹配,当某一个catch匹配,跳过之后的catch,进入后续步骤。

反射,注解

  • 反射:实例化对象,通过Class.forName()获取对象
  • 注解:@Target注解目标,@Retention注解生存周期,@Documented注解文档
  • 加密算法:AES(对称加密),RES(非对称加密,公钥加密,私钥解密)

String

public static void main(String[] args) { 
String str1 = "Lance"; //常量池存储
String str2 = new String("Lance"); //堆存处
String str3 = str2; //引用传递,str3直接指向st2的堆内存地址 1234
String str4 = "Lance"; /** * ==: * 基本数据类型:比较的是基本数据类型的值是否相同 * 引用数据类型:比较的是引用数据类型的地址值是否相同 * 所以在这里的话:String类对象==比较,比较的是地址,而不是内容 */ System.out.println(str1==str2);//false
System.out.println(str1==str3);//false
System.out.println(str3==str2);//true
System.out.println(str1==str4);//true, 常量池数据可复用
}


boolean hashCode(Object obj): 比较字符串内容所计算出的hash值

boolean equals(Object obj):比较字符串的内容是否相同

boolean equalsIgnoreCase(String str): 比较字符串的内容是否相同,忽略大小写

boolean startsWith(String str): 判断字符串对象是否以指定的str开头

boolean endsWith(String str): 判断字符串对象是否以指定的str结尾

IO 流

IO

  • 阻塞IO(BIO):A拿着一支鱼竿在河边钓鱼,并且一直在鱼竿前等,在等的时候不做其他的事情,十分专心。只有鱼上钩的时,才结束掉等的动作,把鱼钓上来。
  • 非阻塞IO(NIO):B也在河边钓鱼,但是B不想将自己的所有时间都花费在钓鱼上,在等鱼上钩这个时间段中,B也在做其他的事情(一会看看书,一会读读报纸,一会又去看其他人的钓鱼等),但B在做这些事情的时候,每隔一个固定的时间检查鱼是否上钩。一旦检查到有鱼上钩,就停下手中的事情,把鱼钓上来。 B在检查鱼竿是否有鱼,是一个轮询的过程。
  • 异步IO(AIO):C也想钓鱼,但C有事情,于是他雇来了D、E、F,让他们帮他等待鱼上钩,一旦有鱼上钩,就把鱼钓上来,然后打电话给C
  • 多路复用IO:H同样也在河边钓鱼,但是H生活水平比较好,H拿了很多的鱼竿,一次性有很多鱼竿在等,H不断的查看每个鱼竿是否有鱼上钩。增加了效率,减少了等待的时间。
  • 信号驱动IO:G也在河边钓鱼,但与A、B、C不同的是,G比较聪明,他给鱼竿上挂一个铃铛,当有鱼上钩的时候,这个铃铛就会被碰响,G就会将鱼钓上来

Stream

  • list过滤:List boys = studentList.stream().filter(s->s.getGender() && s.getHeight() >= 1.8).collect(Collectors.toList());
  • list升序排序:List wodbList = map.get(str).stream().sorted(Comparator.comparing(ApsScheduleWODB::getISort)).collect(Collectors.toList()); 升序排序,降序Comparator.reverseOrder()

NIO

  • Channel(通道)
  • Buffer(缓冲区):缓冲通道往返数据
  • Selector(选择区):监听通道

集合

  • Collection对集合进行排序,查找,复制等功能。(二分查找,乱序)总继承
  • List 有序集合
  • ArrayList:数组形式存储,默认长度为0,添加数据默认长度为10,长度不足时可以扩容但有最大长度限制。
  • LinkedList:双向链表,含有长度,头结点,尾节点三个属性,在迭代中可以添加删除数据
  • Vector: 线程安全的ArrayList,即当线程A使用Synchronized标记方法时,其他线程阻塞。但一般不使用,原因1. 线程并不安全,产生fail-fase错误;2. 在业务中有加锁需求,重复加锁浪费资源。
  • 在迭代中修改数据会产生fail-fast错误。但java.util.concurrent包下的相同情况会产生fail-safe错误,其原因是对数据修改时是对原数据的副本进行修改,不影响原数据;当修改完成后将原数据指向副本。
  • Set 无序集合
  • Map 键值对
  • HashMap: 数组+(链表 or 红黑树)
  • keySet():String:获取map.key的set集合
  • entrySet():Set:获取map关系的set集合

util

  • StringUtil common.lang​​​
  • BigDecimal 浮点数精确计算
  • setScale(scale, BigDecimal.ROUND_HALF_UP):四舍五入,scale=小数后几位?
  • add/subtract 加减法
  • mutiply() 乘法
  • divide() 除法

JVM(堆,方法区,程序计数器,虚拟机栈,本地方法栈)

  • 堆:对象,数组
  • 方法区(永久代):类信息,常量,静态变量
  • 程序计数器:当前线程执行 的字节码行号指示器
  • 虚拟机栈:多个栈帧(局部变量表,操作数栈,动态链接表,方法出口):java方法的执行即为栈帧的入栈,出栈
  • 本地方法栈:类似虚拟机栈,对native方法执行出入栈操作

垃圾回收

  • 标记方法: 引用计数(引用次数为0节点回收),可达性分析(从根节点出发,未到达节点回收)
  • 回收方法
  • 标记清除:直接回收节点
  • 复制:划分等大区域,将可用节点复制到空白区域,清空当前区域
  • 标记整理:将存活对象移向内存的一端。然后清除端边界外的对象
  • 分代
  • 新生代
  • serial:单线程复制(Client 默认)
  • parNew:多线程复制(Server 默认) -XX:ParallelGCThreads
  • paraller Scavenge:多线程复制,高效(关注程序吞吐量=运行代码时间/(运行代码时间+垃圾回收时间))
  • G1
  • 老年代
  • CMS:多线程标记清除
  • 初始标记:暂停所有,标记可达对象
  • 并发标记,跟踪Roots,
  • 重新标记:暂停所有,标记修改部分(多线程)
  • 并发清除:清楚不可达对象
  • serial old:单线程标记整理
  • paraller old:多线程标记整理,关注程序吞吐量
  • G1:标记整理的CMS, G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾最多的区域。区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收集效率。

类加载(加载,链接【验证,准备,解析】,初始化,使用,卸载)

  • 类加载器:启动类lib,扩展类jre/lib/ext,应用程序类classpath,自定义类
  • 双亲委派:当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父
    类去完成。只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的
    Class),子类加载器才会尝试自己去加载。【使用不同的类加载
    器最终得到的都是同样一个 Object 对象】

多线程

  • 线程创建, 继承Thread类,实现Runnable接口,实现Callable接口【有返回值时,通过Future.get()获取】
  • 线程共享:堆,方法区(元数据); 线程私有:程序计数器,虚拟机栈,本地方法栈
  • 状态: 新建(New)、就绪(Runnable)start()、运行(Running)run()、阻塞(Blocked)和死亡(Dead)
  • 死锁:

- 属性锁:对属性操作需获取锁,没有锁无法操作属性;方法锁:使用方法需获取锁,没有锁无法执行方法
- 公平锁:按照访问时间顺序排队获取锁;非公平锁:可以插队获取锁
- 乐观锁:拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作
- 悲观锁:拿数据的时候都认为别人会修改,所以每次在读写数据的时候都会上锁,这样别人想读写这个数据就会 block 直到拿到锁。
- 自旋锁:如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗
- 锁膨胀:锁可以从偏向锁升级到轻量级锁,再升级到重量级锁
- Lock:ReentrantLock
- synchronized
1. 作用于方法时,锁住的是对象的实例(this);
2. 当作用于静态方法时,锁住的是Class实例,又因为Class的相关数据存储在永久带PermGen(jdk1.8 则是 metaspace),永久带是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程;
3. synchronized 作用于一个对象实例时,锁住的是所有以该对象为锁的代码块。它有多个队列,当多个线程一起访问某个对象监视器的时候,对象监视器会将这些线程存储在不同的容器中。
- ReadWriteLock读写锁:读读不互斥,读写互斥,写写互斥
- 读锁:如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁
- 写锁:如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁
- volatile


网络编程:tcp/udp stock编程

  • url(统一资源定位符) :传输协议://主机名:端口号/文件名 #片段名?参数列表(片段名 = 显示文件片段的位置);uri(统一资源标识符):唯一标记网上资源 = url+urn
    WAF: Web应用程序防护系统(Web Application Firewall҅),位于Web服务器前,阻止sql注入,跨站脚本等攻击

计算机网络

  • 七层架构
  • 物理层:物理设备标准,模数转换,(网线,光纤)bit
  • 数据链路层:数据MAC封装和解封,(设备交换机),帧
  • 网络层:ip封装和解封,(路由器),数据报
  • 传输层:传输数据协议和端口(tcp, udp),报文段
  • 会话层:建立数据传输通路,系统发起会话和接受会话请求
  • 表示层:数据加密解密,压缩,形成视频,图片,音频
  • 应用层:终端应用,(虚拟终端协议(TELNET,TELecommunications NETwork)、文件传输协议(FTP,File Transfer Protocol)、电子邮件传输协议(SMTP,Simple Mail Transfer Protocol)、域名服务(DNS,Domain Name Service)、网上新闻传输协议(NNTP,Net News Transfer Protocol)和超文本传送协议(HTTP,HyperText Transfer Protocol)等。)报文

数据库操作

关系型数据库 MySQL;非关系型数据库:redis,Hbase,MongoDB,Cassandra

事务属性ACID:原子性(操作不可分),一致性(数据一致),隔离性(事务独立),永久性(修改永久)

idea

- http:get,post,delete,put用http Tools调试
- 相机图标截取当前线程状态 :查看在运行中的线程
- 打断点,调试
- 找到实现 ctrl+点击 或者 前方图标
- ctrl+shift+/ 区块注释
- Alt+Insert 产生构造方法、getter/setter等方法
- Ctrl+R 替换
- Shift+Enter 在当前行的下方开始新行
- Ctrl+Alt+Enter 在当前行上方插入新行
- Ctrl + Alt + b 转到实现
- Ctrl+Alt+L 格式化代码
- ctrl+Q 查看方法说明
- Ctrl+D 复制光标所在行的内容,插入光标位置下面
- psvn main
- sout 默认输出
- itar for遍历