基础知识复习

基础知识复习

wait() notify() notifyAll()必须在同步(Synchronized)方法/代码块中

1. 调用wait(),自身释放锁,让出CPU,进入等待队列,直到被notify()或者NotifyAll()
2. wait()需要try catch,在该线程获取到interrupt异常的情况下,也可以使wait等待的线程唤醒并收到该interrupt异常
3. 对于非睡眠状态的线程,notify无法唤醒 (lost wake up)
4. notify() notifyAll()是将唤醒处于等待线程中的一个或者全部,但自身不会释放锁

多线程同步块中的条件用while后进行wait()的原因

1. 被其他线程操作完成后,条件可能已经变化需要重新判断

finally代码块一定被执行吗

不一定,一般情况都会执行
1. 未进入到try catch不会执行
2. 强制中断(包括且不限于System.exit() 线程中断 守护线程因主线程结束而结束)

面向对象的特征

封装、继承、多态、抽象
1. 封装->隐藏实现,暴露功能
2. 继承->合理的分层和复用
3. 多态->同一个行为具有多个不同表现形式或形态的能力
4. 抽象->指从特定的角度出发,从已经存在的一些事物中抽取我们所关注的特性、行为,从而形成一个新的事物的思维过程,是一种从复杂到简洁的思维方式

CopyOnWriteArrayList容器

优:
读写分离
劣:
额外内存开销
读可能会有延迟

死锁(解决方案 破坏任一条件)

条件:
互斥条件
请求与保持条件
不剥夺条件
循环等待条件
解:
破坏任一条件 例如循环等待->资源获取必须按顺序

线程状态转换

RUNNABLE
NEW
TERMINATED(结束)
BLOCKED(synchronized等 等待锁)
WAITING(Object.wait() Lock Condition)
TIMED_WAITING(计时等待)

应用类型

1. 强引用 
无论内存足不足,都不会回收
Object object = new Object();
object = null; 回收 
2. 软引用 
内存不足时,才回收,适合缓存
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
3. 弱引用
GC时即回收
WeakReference<String> sr = new WeakReference<String>(new String("hello"));
4. 虚引用
不知何时被回收,但是看到hashMap 对key的引用是这玩意

伪共享

CPU缓存读写是以块为单位进行操作,如果多个CPU内存同时操作同一个块,那么会使内存无效。

类加载机制

加载 验证 准备 解析 初始化 使用 卸载

类加载

双亲委派模型->组合非继承->每个loader有缓存,缓存中找不到寻找父类缓存,到顶级加载器找不到后顺序向下进行加载

对象的访问定位方式

句柄、直接指针
HotSpot使用的方式:直接指针 代价:对被移动(GC)需要修改指针

GC

Serial 收集器:
线程数:1
新生代:串行 复制算法
老年代:串行 标记压缩
ParNew 收集器
线程数:-XX:ParallelGCThreads
新生代:并行  复制算法
老年代:串行 标记压缩
Parallel Old 收集器 (JDK1.6)
新生代:并行  复制算法
老年代:并行 标记压缩
CMS收集器
线程数:-XX:ParallelCMSThreads
新生代:并行  复制算法
老年代:初始标记(stop the world 串行)  并发标记()  重新标记(stop the world)  并发清除
G1
使命替换掉JDK1.5中发布的CMS收集器
特点:
1. 空间整合:G1收集器采用标记整理,不会产生内存碎片,()CMS采用标记清除会产生大量内存碎片
2. 可预测停顿:明确指定在一个长度为?毫秒的时间片段内,消耗在垃圾收集上的时间不得超过?毫秒
3. 分区(Region),新生代/老年代不再物理隔阂,为内存中的(可以不连续)Region的集合。
收集步骤:
1. GC pause (young) (inital-mark)  初始标记,并触发Mintor GC,清除survivor区,存活对象移动至老年代。
2. Root Region Scanning,根对象所在区域扫描,计算哪些区域中存在根对象。
3. Concurrent Marking并发标记,与应用程序并行,可能会被young GC中断,若发现区域对象中的所有对象都是垃圾,那个这个区域会被立即回收(图中打X),同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。
4.  Remark, 再标记,G1中采用了比CMS更快的初始快照算法:snapshot-at-the-beginning (SATB)。计算哪些对象有变动,对这些对象重新计算存活情况并标记。
5. 复制/清除,多线程清除失活对象,会有STW。G1将回收区域的存活对象拷贝到新区域,清除Remember Sets,并发清空回收区域并把它返回到空闲区域链表中。

JDK

for-each 与传统for区别
《Effective Java》第46条:
for-each 它的出现为了简化书写,对数组索引的边界只计算一次,只能针对实现了Iterable接口的集合进行迭代
有三种常见的情况是无法使用 for-each 循环的:
过滤——如果需要遍历集合,并删除选定的元素,就需要使用显式地迭代器,以便可以调用它的 remove 方法。
转换——如果需要遍历列表或者数组,并取代它部分或者全部的元素值(增删、或对元素进行赋值),就需要列表迭代器或者数组索引,以便设定元素的值(从第几个元素开始操作和修改)
平行迭代——如果需要并行地遍历多个集合,就需要显式地控制迭代器或者所因变量以便所有迭代器或者索引变量都可以得到同步前移 (双重for循环修改对应第i个元素的值)
可变参数,可变参数必须定义在参数列表结尾(作为类型数组)
泛型 Generics
引用泛型之后,允许指定集合里元素的类型,免去了强制类型转换,并且能在编译时刻进行类型检查的好处。Parameterized Type作为参数和返回值,Generic是vararg、annotation、enumeration、collection的基石。
静态导入
导入类下的所有静态方法,可以在本类中直接以方法名使用
ProcessBuilder 类
ProcessBuilder 类是 Java5 在 java.lang 包中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。
class Test {
    public static void main(String args[]) {
        try {
        	// 文件会生成在你的classpath根目录
            ProcessBuilder proc = new ProcessBuilder(""C:\Program Files\Notepad++\notepad++.exe"", "testfile"); 
            proc.start();
        } catch (Exception e) {
            System.out.println("Error executing notepad.");
        }
    }
}
Formatter
日期 
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
格式化消息
String msg = "当前时间为({0})共有顾客{1}位!"; 
MessageFormat mf = new MessageFormat(msg); 
String fmsg = mf.format(new Object[]{new Date(), 5});
Scanner
用于控制台等输入流输入数据,并以分隔符进行处理 
StringBuilder
非线程安全,线程安全StringBuffer
Diamond Operator
自动类型推断 
Fork/Join
1. 对于有结果的任务,必须继承RecursiveTask<结果类型> 实现compute方法
接口的静态方法
1. 接口的静态方法只能通过接口进行调用,所以不存在1个类继承2个同名静态方法的接口产生的分歧
接口的默认实现
1. 不同接口的默认实现被一类继承时,靠近接口级更高的实现(类实现优先级最高),如果2个接口等级相同,编译器报错:无相关的两接口继承了一个相同的实现
函数式接口
1. lambda表达式
2. 自定义接口函数
// 注解为申明该接口为一个函数接口,仅作检查使用,当该接口存在1个以上抽象方法会提示错误
@FunctionalInterface
interface StringToInteger<F, T> { 
	T convert(F from); 
}
// 实现申明
StringToInteger<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
方法引用
概述:
在使用Lambda表达式时,如果只执行一个方法的调用时,可以使用该方法引用:
ThreadLocal<String> local = ThreadLocal.withInit(String::new)
Arrays.sort(strArray, String::compareToIgnoreCase);  
分类:
有以下四种形式的方法引用:
引用静态方法: 类名::类方法
引用某个对象的实例方法: 对象::对象方法
引用某个类型的任意对象的实例方法:对象类型::对象方法
引用构造方法: 类名::new
流steam
中间操作:filter、map、flatMap、peel、distinct、sorted、limit 和 substream
终止操作: forEach、toArray、reduce、collect、min、max、count、anyMatch、allMatch、noneMatch、findFirst 和 findAny
List<String> list = new ArrayList<String>(3) {
	{
		add.("a");
		add.("b");
		add.
	}
};
Optional<String> reduced = stringCollection .stream() .sorted() .reduce((s1, s2) -> s1 + "#" + s2); reduced.ifPresent(System.out::println); 
Optional
防止空指针异常,当元素为null时,isPresent()返回true,否则false
orElseGet(() -> 生成一个该类型对象)方法生成为空时的默认值
orElse(元素类型的值)提供一个默认值
Date/Time API
Clock
LocalDate 
LocalTime
Timezones 
LocalDateTime
时间转换示例:
DateTimeFormatter formatter = DateTimeFormatter .ofPattern("MMM dd, yyyy - HH:mm"); 
LocalDateTime parsed = LocalDateTime.parse("Nov 03, 2014 - 07:13", formatter); 
String string = formatter.format(parsed);
JavaFx
图形与多媒体工具包
对称加密与非对称加密
对称加密:加密和解密使用同一秘钥 。优:加解密速度快,简单   劣:如果消息被窃取,可以获得秘钥,就可以破解加密,那么消息就无法安全传输。
非对称加密:加密使用公钥,解密使用私钥,优:传输中发送公钥,消息被窃取时,无私钥故无法解密。 劣:速度非常慢
现在的消息传送:消息体使用对称加密进行加密,对称加密的秘钥使用非对称加密进行发送,每次需要解出对称解密的秘钥后,再解出消息体。
故在消息传输时,消息体加密部分的秘钥可以不同变化,而非对称秘钥和公钥不能经常变化(私下保存各自私钥,发布各自私钥对应的公钥对于合作方用于加密消息)
三次握手
理论:
有A B两人,需要确认双方都知道链路是可以双向传输的最小次数
第1次握手 B 收到 A的来信 B获得信息:A -> B的链路是连通的可以传输消息
第2次握手 A 收到 B的来信 A获得信息:A -> B的链路是连通的可以传输消息  B -> A的链路是连通的可以传输消息
如果只有2步,B缺少了B -> A的链路是连通的这个信息,认为没有回信是消息已经丢失不可达。
第3次握手 B 收到 A的回信 B获得信息:B -> A的链路是连通的可以传输消息

实际:
实现过程中,由于消息每次传输可能会丢失,故在回复时,必须与请求消息相互对应加了相应的消息体序号用于判断此消息是否对应某条消息的应答或是一条全新的请求。
第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

TCP是主机对主机层的传输控制协议,提供可靠的连接服务:
位码即tcp标志位,有6种标示:
SYN(synchronous建立联机)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
Sequence number(seq 顺序号码)
Acknowledge number(ack 确认号码)
四次挥手
理论:
多一次挥手,因为当客户端要求断开时,服务端数据暂未发送完毕,等客户端收到服务端数据发送完毕时,才能真正的开启断开,从而通知服务端断开。

常见问题:
1. 大量端口TIME_WAIT 
原因:大每个客户端端口发起断开后的一定时间内,该端口进入TIME_WAIT不可用
在TIME_WAIT下等待2MSL,只是为了尽最大努力保证四次握手正常关闭。确保老的报文段在网络中消失,不会影响新建立的连接收到过期消息
注:MSL(最大分段生存期)指明TCP报文在Internet上最长生存时间,每个具体的TCP实现都必须选择一个确定的MSL值.
RFC 1122建议是2分钟,但BSD传统实现采用了30秒,操作系统内核编译已确认一个固定的时间,
解决:
tcp_tw_recycle 修改操作系统内核参数,进行回收TIME_WAIT的端口(因为回收了原端口,又被使用为了新端口,那么就存在区分是原连接的还是新连接的,如果开启tcp_timestamps会导致connect失败的问题)
tcp_tw_reuse 复用TIME_WAIT连接,此参数仅当客户端时有效(只有主动断开方出现TIME_WAIT)
备注:如果使用tcp_tw_reuse,请激活tcp_timestamps,否则无效,因需要根据时间戳来抛弃过去网络中的遗留数据包(复用,那么就需要区分数据包是残留的还是全新的)
···
参数所在位置:
/etc/sysctl.conf
修改项:
0关闭 1开启
net.ipv4.tcp_tw_reuse = 1 
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
···
应用解决方案:
使用长连接 等方案降低 tcp连接的断开重建。
TCP可靠性
1. 存在缓存区,使用滑动窗口协议,防止较快主机压慢主机,并在缓存区进行数据包的重排序
2. 数据包存在校验位进行校验,如果校验失败丢弃,等待重传(不给收到应答)
3. 对于已正确传输的数据包进行应答,如果是相同数据包会丢弃(发送应答)
DDos(针对TCP这种客户端向服务端申请链接的协议进行攻击)
原理:只玩3步握手的第1步,服务端将有大量端口处于SYN_RCVD等待客户端应答的断开,导致服务大部分断开被占用不可用。
解决:降低等待时间 限制SYN_RCVD端口的数量上限
针对TCP协议进行的攻击,无法进行链路连接前的验证,没好的根治防范方案。
应用层及传输层
TCP UDP 传输层
FTP HTTP  DNS  应用层
HTTP传输
1. 由域名→IP地址 寻找IP地址的过程依次经过了浏览器缓存、系统缓存、hosts文件、路由器缓存、 递归搜索根域名服务器(直至根dns,返回不可达)。
2. 建立TCP/IP连接(三次握手具体过程)
3. 由浏览器发送一个HTTP请求
4. 经过路由器的转发,通过服务器的防火墙,该HTTP请求到达了服务器
5. 服务器处理该HTTP请求,返回一个HTML文件
FTP的主动模式与被动模式 (容器化可能带来的问题)
在一般环境,两种模式基本都可用,但是主动模式存在安全问题且在容器化后,容器里的服务作为客户端时,FTP作为服务端时,无法建立数据链路而失败。
主动模式:
1.  客户端打开一个端口N(大于1023)连接到FTP服务器的21端口,建立控制链接。TCP
2.  客户端打开一个端口X,然后发送X信息至服务端,同时从X端口监听服务端应答。
3.  服务端收到客户端的消息X,知道了客户端向自己打开了一个端口,于是打开自己的数据端口20区连接客户端的X端口。
容器化导致的问题时,第2步中,客户端打开一个端口X,发送消息至服务端,服务端记录下来端口X和客户端地址ClineIP,但是这个ClientIP为容器里的IP,于是FTP服务器无法找到这个容器内IP对应的虚机,导致数据链路建立失败。(同样适应于防火墙:必须允许以下通讯才能支持主动方式FTP:任何端口到FTP服务器的21端口 (客户端初始化的连接到FTP服务器);FTP服务器的21端口到大于1023的端口(服务器响应客户端的控制端口);FTP服务器的20端口到大于1023的端口(服务器端初始化数据连接到客户端的数据端口);大于1023端口到FTP服务器的20端口)
被动模式:
1. 客户端打开一个端口N连接到FTP服务器的21端口,建立控制链路。
2. 在控制链路上,客户端发送申请服务端数据链路端口的请求。
3. 服务端收到请求后,打开一个端口Y,通过控制链路,给与客户端响应:已经开启端口Y,请进行连接
4. 在控制链路上,客户端收到服务端开启端口的消息后,主动发起建立数据链路请求的。
这样都是容器里的服务主动连接容器外的FTP服务器,不存在FTP服务器主动连接容器里的服务,不会造成连接失败的问题。
TCP 网络负荷 拥塞控制方法
1. TCP滑窗,先发送小包再增加窗口大小,动态调整大小,慢开始从0刚开始指数增长,然后加法递增,遇到阻塞使用乘法减少(快恢复算法为减半而不是从0开始),对于三次重复确认立刻重传对方尚未收到的报文。
HTTP本身无状态
要使由状态,使用cookie or session记录请求上下文至相应的缓存中
MYSQL行级锁失效问题
MySql InnoDB默认行级锁,行级锁基于索引,如果未使用到索引,会变未表锁导致速率低下。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值