赞
踩
Error常见的有StackOverFlowError,OutOfMemoryError等等。
Exception可分为运行时异常和非运行时异常。对于运行时异常,可以利用try catch的方式进行处理,也
可以不处理。对于非运行时异常,必须处理,不处理的话程序无法通过编译。
ClassNotFoundException是在类加载第一个阶段,加载这个动作的时候,类加载器不能找到class文件,则会报ClassNotFoundException。比如在A中有段代码使用了Class.forName(B)去加载B,此时B的class文件不见了,则会报错ClassNotFoundException。它报这个错是说B的加载阶段出错了。(A类去加载B类,A类会报ClassNotFound B类)
NoClassDefError这个类是继承LinkageError(连接错误),所以也可以大概的猜出,NoClassDefError是在类加载的连接这个阶段报出来的。当A类中引用了B类,然后A类进行类的加载,加载成功后,然后进行接下来的连接阶段的时候,如果涉及到引用到B类却找不到B类的时候,就会报NoClassDefError。它报这个错是说A的连接阶段出错了。(A类去加载B类,A类会报B类NoClassDef)
Linux实现CAS的指令cmpxchgl
在 thread dump 中,要留意下面几种状态
二叉搜索树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。搜索复杂度为o(logn)最差为o(n)
平衡二叉搜索树AVL树:本质上是带了平衡功能的二叉查找树,每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。
红黑树:需要满足以下性质:红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作
1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点,即空结点(NIL)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。也就是说从每个叶子到根的所有路径上不能有两个连续的红色节点
5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。
short a = 4;
a += 5;
//a = a + 3会报错
a = (short) (a + 3);
+=是一个运算符,编译器会自动转换类型
a = a+b
Map是一个键值对集合,存储键、值和之间的映射。 Key无序,唯一;value 不要求有序,允许重复。Map没有继承于Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。
Map 的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap
阻塞IO
非阻塞NIO
堆排序
堆的数据结构
相同点
(1)都不能被实例化 (2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为 public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的,1.8 可以有static方法,可以有default方法,子类可以不实现。
抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;可以有非抽象方法,抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。抽象类中可以有非抽象方法,有抽象方法的一定是抽象类
TEXT类型一般分为 TINYTEXT(255长度)、TEXT(65535)、 MEDIUMTEXT(int最大值16M),和LONGTEXT(long最大值4G)这四种,对于text列,插入时MySQL不会对它进行填充,并且select时不会删除任何末尾的字节。
text的最大限制也是64k个字节,但是本质是溢出存储,innodb默认只会存放前768字节在数据页中,而剩余的数据则会存储在溢出段中。text类型的数据,将被存储在元数据表之外地方,但是varchar/char将和其他列一起存储在表数据文件中,值得注意的是,varchar列在溢出的时候会自动转换为text类型。text数据类型实际上将会大幅度增加数据库表文件尺寸。
除此之外,二者还有以下的区别
1、当text作为索引的时候,必须 制定索引的长度,而当varchar充当索引的时候,可以不用指明。
2、text列不允许拥有默认值。
3、当text列的内容很多的时候,text列的内容会保留一个指针在记录中,这个指针指向了磁盘中的一块区域,当对这个表进行select *的时候,会从磁盘中读取text的值,影响查询的性能,而varchar不会存在这个问题。
public final class Singleton { private Singleton() { } // 问题1:解释为什么要加 volatile?为了保证赋值和构造器不要发送重排序,否则第二个线程可能拿到不完整的对象。 private static volatile Singleton INSTANCE = null; // 问题2:对比实现3, 说出这样做的意义 public static Singleton getInstance() { if (INSTANCE != null) { return INSTANCE; } synchronized (Singleton.class) { // 问题3:为什么还要在这里加为空判断, 之前不是判断过了吗?为了防止第二个线程等第一个线程释放锁后,再次创建新对象 if (INSTANCE != null) { // t2 return INSTANCE; } INSTANCE = new Singleton(); return INSTANCE; } } }
// 问题1:枚举单例是如何限制实例个数的 ==static final 变量
// 问题2:枚举单例在创建时是否有并发问题 ==没有并发,jvm保证
// 问题3:枚举单例能否被反射破坏单例 ==不能
// 问题4:枚举单例能否被反序列化破坏单例 不能,枚举类实现了序列化
// 问题5:枚举单例属于懒汉式还是饿汉式 ==饿汉式
// 问题6:枚举单例如果希望加入一些单例创建时的初始化逻辑该如何做== 加构造器
enum Singleton {
INSTANCE;
}
public final class Singleton {
private Singleton() {
}
// 问题1:属于懒汉式还是饿汉式 ==懒汉式,不调用方法不加载静态类
private static class LazyHolder {
static final Singleton INSTANCE = new Singleton();
}
// 问题2:在创建时是否有并发问题 ==没有,静态成员变量,在类加载的时候完成,jvm保证
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
单体架构的优缺点如下:
**优点:**架构简单、部署成本低
**缺点:**耦合度高(维护困难、升级困难)
分布式架构的优缺点:
**优点:**降低服务耦合、有利于服务升级和拓展
**缺点:**服务调用关系错综复杂
当我们需要封禁一个账号时,只需要将其账号的status
值修改为0即可,对方再次登录系统时,我们便可以检测到status
值不为1禁止登录。由于我们只在登录时检测status
值,这也就代表:如果对方不主动注销账号,他的会话还是会一直存在且有效。
那怎么才可以做到在封禁账号后立即生效?
你可能会想到使用拦截器,拦截用户的所有请求检测账号状态:status=0
时禁止访问,status=1
时再对请求放行。
可以用户数据库+status状态、登录时判断、拦截器请求时判断、redis维护黑名单。
使用Sa-Token框架
该原则提出对象不应该承担太多职责,如果一个对象承担了太多的职责,至少存在以下两个缺点:
单一职责原则的优点
单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。如果遵循单一职责原则将有以下优点。
Unicode就是一种编码:它包含了世界上所有的符号,并且每一个符号都是独一无二的
UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有两条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码
GBK/GB2312/GB18030
GBK和GB2312都是针对简体字的编码,只是GB2312只支持六千多个汉字的编码,而GBK支持1万多个汉字编码。而GB18030是用于繁体字的编码。汉字存储时都使用两个字节来储存
修饰普通方法:对象锁
修饰静态方法:类锁
修饰代码块:类锁synchronized(A.class)、对象锁synchronized(this)
为啥先进阻塞队列再创建最大线程
线程池创建线程需要获取mainlock这个全局锁,会影响并发效率,所以使用阻塞队列把第一步创建核心线程与第三步创建最大线程隔离开来,起一个缓冲的作用。引入阻塞队列,是为了在执行execute()方法时,尽可能的避免获取全局锁。
核心线程数 corePoolSize
任务队列长度 workingQueue
最大线程数 maximumPoolSize
最大空闲时间
状态 | 描述 |
---|---|
RUNNING | 能接受新提交的任务,并且也能处理阻塞队列中的任务 |
SHUTDOWN | 关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务。在线程池处于 RUNNING 状态时,调用 shutdown()方法会使线程池进入到该状态。(finalize() 方法在执行过程中也会调用shutdown()方法进入该状态) |
STOP | 不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。在线程池处于 RUNNING 或 SHUTDOWN 状态时,调用 shutdownNow() 方法会使线程池进入到该状态 |
TIDYING | 如果所有的任务都已终止了,workerCount (有效线程数) 为0,线程池进入该状态后会调用 terminated() 方法进入TERMINATED 状态 |
TERMINATED | 在terminated() 方法执行完后进入该状态,默认terminated()方法中什么也没有做 |
第一次握手丢失:客户端重传SYN
第二次握手丢失:客户端重传SYN、服务器都重传SYN-ACK
第三次握手丢失:服务端重传SYN-ACK,客户端的ACK不会重传
序列号可以用来解决网络包乱序的问题,确认号可以⽤来解决网络包丢失的问题
一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
客户端连续发送多次 SYN 建立连接的报文,在网络拥堵情况下:
SYN + ACK
报文给客户端;RST
报文给服务端,表示中止这一次连接MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接
大量TCP连接处在close_wait状态,形成原因和解决办法
客户端发送FIN客户端收到后,客户端自动ACK后进入close_wait状态,socket.close因为阻塞关闭不及时。
Server端在某些异常情况时,没有关闭Socket。关闭socket不及时:例如I/O线程被意外阻塞,或者I/O线程执行的用户自定义Task比例过高,导致I/O操作处理不及时,链路不能被及时释放。
浏览器–>本地域名服务器缓存–>根域名服务器(全球有13个)–>com顶级域名服务器–>baidu.com主域名(权威)服务器–>找到ip地址 缓存到本地域名服务器
DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。
DNS使用UDP还是TCP:区域传送时使用TCP,域名解析时使用UDP协议
DNS在进行区域传输的时候使用TCP协议,其它时候则使用UDP协议;
DNS的规范规定了2种类型的DNS服务器,**一个叫主DNS服务器,一个叫辅助DNS服务器。**在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone transfer)。
为什么既使用TCP又使用UDP?
首先了解一下TCP与UDP传送字节的长度限制:
UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。当DNS查询超过512字节时,协议的TC标志出现删除标志,这时则使用TCP发送。通常传统的UDP报文一般不会大于512字节。
区域传送时使用TCP,主要有一下两点考虑:
1.辅域名服务器会定时(一般时3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用TCP而不是UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。
2.TCP是一种可靠的连接,保证了数据的准确性。
域名解析时使用UDP协议:
客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向DNS服务器查询的时候使用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
http请求一定要访问80端口吗
不一定。80端口只是客户端(浏览器)发出的http请求默认去访问的服务器端口,只要请求的端口和服务器程序运行的端口保持一致就可以。我们日常开发使用的tomcat就运行在8080端口,在浏览器输入http://localhost:8080
也可以访问tomcat的。只是一般网站服务器程序都运行在80端口上,我们只需要输入网址即可,不用再输入类似ww.google.com:80这样带有端口号的地址,比较方便。
简单的说,当你登陆一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登陆或具有某种权限。由于数据是存储在服务器上面,所以你不能伪造
假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。关于WAP上的应用,常规的cookie就派不上用场了。运用session需要使用URL地址重写的方式。一切用到session程序的URL都要进行URL地址重写,否则session会话跟踪还会失效。
cookie什么情况下会丢失
1、 Cookie 的Domain设置不正确 ;
2、 Cookie 超时 ;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。