并发&网络

并发

一、JAVA如何开启线程?如何保证线程安全?
1.进程是CPU资源分配的最小单位,线程是CPU任务调度的最小单位。线程隶属于进程。

2.开启线程主要有两种方式,第一种是通过实现Runnable接口,实现run()方法。第二种是通过继承Thread类,重写run()方法。除此之外还可以通过实现Callable接口实现call方法或者是通过线程池来开启新的线程。

3.通过加锁来保证线程安全,有两种方式,一种是使用JVM提供的隐式锁Synchronized(偏向锁,轻量锁…)。另一种是使用JDK的显示锁(实现Lock接口,而Lock操作借助于内部类Sync,Sync继承了AQS类)。

二、Volatile和Synchronized有什么区别?Volatile能不能保证线程安全?DCL单例为什么要加Volatile?什么是指令重排?
1.Synchronized是关键字,用于加锁。而Volatile是用来保证变量的线程可见性(每次线程访问该变量得到的都是最新的值),但是不具有原子性,因此并不能保证线程安全,一般用于一个线程写,多个线程读的场景。

2.DCL单例加入Volataile目的是防止指令重排,造成高并发场景下的线程安全问题 。

3.指令重排是指JVM为了调高性能,在不影响结果的条件下,不按照编码的顺序执行语句。

三、单例模式?什么是懒汉式和饿汉式写法?懒汉式如何保证并发性和性能高效(DCL)?什么情况下可以破坏单例模式?

1.单例模式是指当你多次使用一个对象且作用相同时,为了防止多次重复创建该对象,导致内存飙升,内存中只创建一个对象,让所有需要调用的地方共享该对象。

2.懒汉式是指如果没有使用或者调用该对象时,就不创建一个新的对象,仅当使用时才创建new一个对象。而饿汉式是指不管有没有被调用,在类加载时已经创建好该单例对象

3.懒汉式通过DCL实现,保证高并发场景下,不会多次创建多个对象;如果已经创建有对象,则不需要等待锁直接返回该对象(高效)。

public class SingleDemo{
    private static SingleDemo volatile singleDemo;
    private SingeleDemo(){}
    public static SingleDemo getInstance(){
        if(singleDemo==null){ //高效性
            synchronized(SingleDemo.class){ //控制高并发
                if(singleDemo==null){
                    singleDemo=new SingleDemo();
                }
            }
        }
        return singleDemo;
    }
}

4.可以通过反射机制,强制访问该类的私有构造器,去创建另一个对象。通过T.class.getConstructor获得该类的构造方法(构造器),setAccessible(true)取消语言访问,暴力访问。

四、对象创建创建时JVM会经过哪三步?对象在内存中的存储布局是怎样的?

1.对象创建时经过以下三步:①先在内存堆中给对象分配空间②初始化对象③把栈中的引用对象指向堆中分配好的空间。

2.对象存储布局包括:①四个字节的Markword对象头,来标记对象的属性,包括锁状态等等②四字节的类型指针,指向方法区的class类 ③成员变量信息④字节填充,使得能被八字节整除。

五、JAVA锁机制是怎样的?偏向锁、轻量级锁、重量级锁有什么区别,如何升级?什么是CAS?

1.JAVA的锁就是在对象Markword中记录的一个锁状态,并根据资源竞争激烈程度,不断升级锁,分为无锁,偏向锁,轻量级锁,重量级锁。

2.偏向锁可以理解为锁偏向于第一个获取它的线程,创建的第一个线程则上偏向锁,当该线程下次再想获得锁时,不需要再获得锁;若存在锁资源竞争则升级为轻量级锁,通过CAS 避免了使用互斥量的开销其他线程通过CAS发现对象的Mark word头中线程id不是自己的,则保持自旋等待更新;当有非常多自旋的线程时(存在线程之间的同时竞争,CAS失败),JVM上报操作系统升级为重量级锁,每一步都让操作系统来管理,效率比较低。

在这里插入图片描述

可以理解为偏向锁相当于只有一个线程在临界区;轻量级锁相当于有多个线程交替访问临界区,你用完给我,我用完给你;而重量级锁相当于是同时有多个线程想要进入临界区。

3.锁又可以分为悲观锁(synchronized)和乐观锁(CAS),前者性能比较差。CAS就是通过比较和交换,有三个操作数V,A和B,要进行修改操作时,先把要写入内存地址V的值取出来赋给A(旧预期值),然后把修改后结果赋给B,当要把B写入V时,要检查A和当前V地址的值是否相同,若相同则写入B,否则重复以上操作更新A和B并重新写入。

六、谈谈对AQS的理解。AQS如何实现可重入锁?

1.AQS是一个JDK提供的显示锁的框架,Lock类操作通过内部类Sync类来实现,而Sync类又继承了AQS类;在AQS类当中,有一个双向线程队列,还有一个state信号量,通过该信号量来控制线程排队放行的。不同场景下有不同意义。

2.可重入锁是指对同一个线程而言,该线程可以lock()多次获得多个锁,一般适用于线程需要多次进入临界区的场景。在可重入锁场景下,state用来记录锁的计数值,每lock()一次就加1,release()则减一,直到减为0其他线程才能进入临界区。

七、有A,B,C三个线程,如何保证三个线程同时执行?如何在并发情况下保证三个线程依次执行?如何保证三个线程有序交错进行?

1.线程同时执行(或者一个线程等多个线程)使用CountDownLatch,初始时先设定一个计数器,每当一个任务执行完则CountDownLatch.countDown()使计数器减一,当计数器减为0时,被CountDownLatch.await()阻塞的线程唤醒,执行await()往下的代码。

2.依次执行可以使用volataile变量来控制;有序交错执行都可以使用Semaphore信号量,B要在A执行完后才执行,则A执行完后需要release()释放B的信号量,B中acquire()获得信号量后才能执行往下的代码。

八、如何对一个字符串快速进行排序?

1.归并排序。使用Fork和Join框架分而治之。

网络

一、TCP和UDP区别?什么是TCP的序号和期望号?TCP为什么是三次握手,不是二次?为什么是四次挥手不是三次,以及为什么最后发送方要等2MSL?

1.TCP是面向连接可靠的传输层协议,而UDP是无连接不可靠的传输层协议。

2.TCP会对数据字节编号,序号seq是当前报文的第一个字节号,期望号ack等于收到对方报文的最后一个数据号加一,表示期望收到对方下一个报文的序号。TCP规定携带SYN字段的报文即使不携带数据,也要消耗一个序号;而对于没有SYN的报文不携带数据,就不消耗序号

3.两次握手的问题在于,A和B建立TCP连接,如果A第一次发送过程中如果因为网络堵塞超时了,A会重新发送TCP连接报文给B,B发确认报文给A然后两者进行数据传输。当A和B断开连接时,如果这时候B才收到了之前A第一次发送的超时的TCP连接报文,那么B会认为A此时要创建新的TCP连接,于是B会给A发送确认报文,数据运输通路建立完成(假设两次即可),而A收到后不予理睬,因此会导致B一直等待A的数据,造成资源的浪费。而如果时三次握手的话上述情况,B因为没有收到A发送的第三个报文而不会建立连接。

4.如果是三次挥手,则B发完数据后,发送第三个断开连接报文给A后B关闭连接,A收到B的第三次挥手后也会关闭连接。但是问题在于,当网络堵塞时,如果B发送的第三次挥手报文丢失,那么A会一直等待B发送关闭连接报文,而此时B已经关闭
A发送给B第四次确认时,如果不等待2MSL时长就立即关闭,当网络阻塞B收不到第四个报文时,B会一直重传,一直处于最后确认状态而无法关闭。

二、JAVA有哪几种IO模型?有什么区别?
1.同步与异步是针对客户端(请求者)而言。同步是指客户端没出结果之前一直轮询等待,直到对方return返回结果后采取做别的事情。而异步是指客户端发出请求后,可以去干别的事情,服务器端处理完后会通知客户端。

而阻塞与非阻塞是相对于服务端而言(被请求者)。阻塞是指服务器端没有处理完得出结果之前,不会返回结果给客户端;非阻塞是指服务端收到请求后就立即返回一个状态值,无需等到IO彻底完成。

2.BIO:同步阻塞IO,服务器端每收到一个客户端请求就创建一个新的线程进行业务处理,然后把结果返回给客户端。 可靠性比较差,当线程数增加时会出现线程堆栈溢出,导致不能对外服务。适用于连接数目比较少且固定的架构。

在这里插入图片描述

3.NIO:同步非阻塞IO,用一个线程处理多个请求,客户端发送的请求都注册到Selector多路选择器上,通过Selector选择器对通道进行轮询,如果通道上面有事件发生,则把线程资源分配给该通道。适用于连接数较多且比较短的架构,如聊天服务器,弹幕系统。

在这里插入图片描述

4.AIO:异步非阻塞IO,客户端发完请求后可以去干别的事情,服务端处理完会通过队列把相应推给客户端。适用于连接数多且重操作架构,如相册服务器。需要操作系统来支持。

在这里插入图片描述

三、NIO三大核心组件作用?

1.buffer用于存入要写的数据;每一个channel对应一个buffer缓冲区,它会注册到Selector上并且通知事件的产生;Selector会根据channel上的读写事件,将请求交给某个空闲的线程处理。

buffer和channel都是可读可写的。

四、select,poll和epoll有什么区别?

1.是NIO中实现多路复用的实现机制。是由LInux提供的。

五、描述HTTP和HTTPS区别

1.HTTP是互联网上一种应用广泛的网络通信协议,基于TCP实现的。传输时先建立TCP连接,再进行资源传输。分给持久连接和非持久连接,持久连接只需建立一次TCP连接,后续访问数据传输不需要建立新的连接;而非持久连接中每次访问资源都需要建立一次新的TCP连接建立通道。

HTTPS可以认为是HTTP+SSL,他在HTTP基础上增加了一系列安全机制,一方面在保证数据传输的安全性以外,另一方面还对访问者增加了验证机制。

2.HTTP免费的,而HTTPS需要申请证书,证书需要收费。

HTTP默认80端口,而HTTPS默认443端口。

HTTPS握手协议比较耗时,除了三次握手之外,还增加了对证书的验证过程,因此比较影响服务的响应速度和吞吐量。并且证书体系也不是完全安全的,对于DDOS(分布式拒绝访问攻击)甚至会起到反作用。

六、输入一个URL访问后发生什么?

1.首先通过DHCP协议动态获取本机IP地址。

DHCP是基于UDP实现的,大致过程如下:主机先广播discover报文,其中包含有主机的MAC地址;所有DHCP服务器接收到之后,向主机通过广播或者单播(通过discover报文中的MAC地址进行单播)的方式发送offer报文;主机收到后一般会响应最先收到的那个,并广播request报文,表示接受使用该DHCP服务器提供的ip地址;DHCP收到会发送确认报文。

2.通过DNS域名解析获取URL对应的ip地址。

首先浏览器先查看自己的DNS缓存,若没有则搜索操作系统缓存,若没有则查看本地host文件是否有该域名的映射,都没有则进行DNS查询。

先对本地域名服务器进行递归查询,本地域名服务器会查询自己的缓存,如果没有则会依次向根域名服务器,顶级域名服务器,权限域名服务器等等进行迭代查询。最后本地域名服务器得到ip地址后返回给浏览器。

3.获得目的ip地址后,传输层会进行TCP三次握手建立传输链路

4.网络层首先是在路由表中,根据目的ip地址查找下一条路由器的地址,其中如果本机在局域网中,还可能涉及本地路由器的NAT转换,将本机的私有IP地址转化为路由器的公网IP。

再者还需要通过ARP协议获取目的ip对应的MAC地址,主机将包含目的ip的ARP请求广播到局域网上的所有主机,并接受消息以确认目标MAC地址。

5.建立完连接后开始传输数据。客户端会根据HTTP协议生成HTTP请求报文,并发送给服务器端。服务器接收到http请求后,就会把客户端请求的web资源通过HTTP响应报文发给客户端。客户端接收到响应后,进行四次挥手来与服务器关闭连接

6.浏览器就会进行解析和渲染,呈现给我们看到的页面。



今日总结

复习知识

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值