2021-10-09

手写lru算法

lru 算法是指least recently used 最近最少使用算法,一种常用的页面置换算法,选择最近最久未使用的数据予以淘汰。
存在读写操作,就要按照命中率的思路考虑,需要考虑读写的时间复杂度。
然后因为存在排序的要求,因此需要区分最近和最少使用的数据进行排序。
由于LinkedHashMap可以记录Map中元素的访问顺序,所以可以轻易实现LRU算法,只需要将构造accessOrder传人true,并重写removeEldestEntry方法即可。accessOrder设置为true时,可以实现记录访问顺序。

哈希表+双向链表
哈希表负责查找,构建虚拟的双向链表,里面装入一个个node节点,作为数据载体。构建一个虚拟的双向链表新的插入头部,旧的从尾部移除。

进程和线程的区别

进程是并发执行程序,在执行过程中分配和管理资源的基本单位。
而线程是进程的一个执行单位,是进程内部调度实体,比进程更小的独立运行的基本单位线程也被称为轻量级进程
区别:
1,地址空间
线程共享进程的地址空间,而进程之间是独立的地址空间。
2,资源
线程共享进程的资源如内存,IO,cpu等,不利于资源的管理和保护,而进程之间是独立的,能够很好的进行资源管理和保护。
3,健壮性
多进程比多线程健壮,之前有说过,进程是独立的,所以一个进程崩溃后,在保护模式下不会对其他进行产生影响,但是线程不一样,一旦一个线程崩溃,将导致整个进程都死掉。
4,并发性
两者均可以并发

5,切换性
进程进行切换时,消耗的资源大,效率高,所以涉及到频繁的切换时,使用进程,同样如果要求同时进行又要共享某些变量的并发操作,只能用线程。

6,其他
线程是处理器调度的基本单位,但进程不是。

总结:
进程是程序的一次执行,是系统进行资源分配和调度的独立单位,他的作用是是程序能够并发执行提高资源利用率和吞吐率。

由于进程是资源分配和调度的基本单位,因为进程的创建、销毁、切换产生大量的时间和空间的开销,进程的数量不能太多,而线程是比进程更小的能独立运行的基本单位,他是进程的一个实体,可以减少程序并发执行时的时间和空间开销,使得操作系统具有更好的并发性。

线程基本不拥有系统资源,只有一些运行时必不可少的资源,比如程序计数器、寄存器和栈,进程则占有堆、栈。

进程之间通信的方式

一、管道

管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。

特点:

它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

二、FIFO

FIFO,也称为命名管道,它是一种文件类型。

1、特点

FIFO可以在无关的进程之间交换数据,与无名管道不同。

FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

三、消息队列

消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。

特点

消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

四、信号量

信号量(semaphore)与已经介绍过的 IPC 结构不同,它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

特点

信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。

信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。

每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。

支持信号量组。

五、共享内存
共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区。

特点
共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。
因为多个进程可以同时操作,所以需要进行同步。

信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问

详细介绍:

https://blog.csdn.net/hyb612/article/details/89629189
https://www.php.cn/faq/469981.html

线程之间通信的方式

线程间的通信目的主要是用于线程同步。
方式一:
基于volatile关键字来实现线程间相互通信是使用共享内存的思想。实现就是多个线程同时监听一个变量,当这个变量发生变化的时候,线程能够感知并执行相应的业务。

方式二:
使用Object类提供的wait()和notify()方法;
wait(),notify(),notifyAll()都是Object类提供的线程间通信的方法,它们是多线程通信的基础,2而这种实现方式的思想自然事线程间的通信。
wait(),notify()需要配合synchronized使用,wait方法释放锁,notify方法不释放锁。

方式三:
使用JUC工具类CountDownLatch
jdk1.5之后在JUC包下提供了很多并发编程相关的工具类,CountDownLatch是基于AQS框架,相当于也是维护一个线程共享变量state

方式四:
使用ReentrantLock结合Condition
这个种方式和Object的wait和notify一样,A线程在唤醒操作后并不释放锁。

方式五:
基于LockSupport实现线程间的阻塞和唤醒
LockSupport是一种非常灵活的实现线程阻塞和唤醒的工具,它不用关注是等待线程先进行还是唤醒线程先运行。

说说io多路复用

先讲一下IO模型:
首先输入操作包含
1,等待数据准备。这个阶段存在一个套接口上的操作,这个步骤将数据从网络到达,将其复制到内核的某个缓冲区。
2,将数据从内核缓冲区复制到进程缓冲区。
我们常见的IO模型有BIO,NIO,AIO
BIO就是传统的socket编程,同步阻塞模式,即服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器 端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程 池机制改善,实现多个客户连接服务器。
BIO存在的问题:
1,每个请求都需要创建独立的线程。
2,并发数量较大时,需要创建大量的线程来处理,系统资源占用较大。
3,连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在read操作上,造成线程浪费。
NIO 在BIO基础上做了优化,同步非阻塞,服务器实现模式为一个线程处理多个请求连接,即当客户端发送连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求就进行处理。
Netty就是基于NIO的网络编程框架开发的。
AIO 是异步非阻塞模式,引入了异步通道的概念,采用proactor模式。

tcp udp的区别

tcp即传输控制协议是面向连接的协议,也就是在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次握手才能建立起来,简单描述过程:
第一次握手:主机A通过向主机B发送含有同步序号的标志位(SYN)的数据段发给主机B,向主机B请求建立连接,通过这个数据段,主机A告诉主机B两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我。

第二次握手:主机B收到主机A的请求后,用带有确认应答ACK和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两件事:我已接收到消息,你可以传输数据了。

第三次握手:主机A收到这个数据段后,再发送一个确定应答,确认已收到主机B的数据段:“我已收到回复,我现在要开始传输实际数据了”。
这样3次握手就完成了,主机A和主机B就可以传输数据了。

对于TCP断开连接的4次挥手:
第一次: 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求 ;

第二次: 主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1;

第三次: 由主机B 端再提出反方向的关闭请求,将FIN置1 ;

第四次: 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束。

由TCP的三次握手和四次挥手可以看出,TCP使用面向连接的通信方式, 大大提高了数据通信的可靠性。

UDP 用户数据协议
UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
UDP是面向报文的。
udp的包头机构:
源端口、目的端口、长度、校验和

总结:
1,tcp基于连接,udp是无连接;
2,对系统资源的要求(tcp较多,udp较少);
3,udp程序结构较为简单;
4,tcp是流模式传输,udp是以数据报文模式;
5,tcp保证数据正确性,udp可能存在丢包;
6,tcp保证数据顺序,udp不保证;

网络的几层结构

网络是7层模型主要包括:
物理层->数据链路层->网络层->传输层->会话层->表示层->应用层
物理层:主要是定义物理设备标准的,比如网线接口类型,各种传输介质的传输速率等。
数据链路层:主要从物理接收的数据进行MAC地址的封装与解封装。常把该层的数据称为帧。这一层工作的设备主要是交换机,数据通过交换机来传输。
网络层:主要将下层的数据进行IP地址的封装与解封装。工作设备是路由器,常把这一层的数据叫做数据包。
传输层:定义了一些传输数据的协议和端口号。如:TCP,UDP。主要是将下层接收的数据进行分段进行传输,到达目的地址后进行重组。这层数据叫做段。
会话层:通过传输层建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求。
表示层:主要进行对接收的数据进行解释、加密与解密、压缩与解压等。
应用层:主要是一些终端应用。比如FTP,WEB,QQ之类的。

Linux系统中的多路复用是怎么体现的

命令执行???

虚拟内存管理映射和实际内存的分配问题???

为了充分利用和管理系统内存资源,Linux采用虚拟内存管理技术,利用虚拟内存技术让每个进程都有4GB 互不干涉的虚拟地址空间。
进程的虚拟地址空间分成:用户空间和内核空间。
在这里插入图片描述

https://mp.weixin.qq.com/s?__biz=MzkwOTE2OTY1Nw==&mid=2247486893&idx=1&sn=8295c8a87137ccc7fa5eebcbca350b81&source=41#wechat_redirect

网络通信的套接字编程了解多少

socket是用户进程与内核网络协议栈的编程接口。可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信。
在编写程序时,首先要对TServerSocket(在服务器端)与TClientSocket(在客户端)进行实例化。
对于TServerSocket的对象,主要设置其服务类型(ServerType)与端口(Port)的属性,然后编写“OnClientRead”事件处理程序的代码,处理来自客户机的请求。

如何实现一个线程安全的计数器。

Java 提供了一组atomic 类来帮助简化同步处理。基本工作原理是使用了同步synchronized的方法实现了对一个long, integer, 对象的增、减、赋值(更新)操作.

synchronized关键字和lock的区别

synchronized是Java的关键字,在JVM层面上的。
lock是一个接口。

synchronized底层使用指令码方式来控制锁,映射成字节码指令:monitorenter和monitorexit。当线程执行遇到monitorenter指令时会尝试获取内置锁,如果获取到锁则锁的计数器+1,如果没有获取到锁则阻塞;当遇到monitorexit指令锁计数器-1,如果计数器为0,则释放锁。
lock:底层是CAS乐观锁,依AbstractQueuedSynchronizer类,把所有的请求线程构成一个CLH队列。而对该队列的操作均通过Lock-Free(CAS)操作。

锁释放:
synchronized是以获取锁的线程执行完同步代码,释放锁;在线程执行发生异常,jvm会让线程释放锁;
lock:在finally中必须释放锁,不然容易造成线程死锁

锁的获取:
synchronized:假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待
lock:分情况而定,Lock有多个锁获取的方式,可以尝试获取锁,线程可以不用一直等待。

锁的释放
synchronized:在发生异常时候自动释放占用的锁,因此不会出现死锁。
lock:发生异常时候,不会主动释放占用的锁,必须手动unlock释放锁,可能引起死锁的发生。

锁的类型
synchronized:可重入 不可中断 非公平
lock:可重入 可判断 可公平(两者皆可)

性能:
Lock可以提高多个线程进行读操作的效率,可以通过readwritelock实现读写分离。

调度:
synchronized:使用object类提供的wait,notify,notifyAll调度机制。
lock:可以使用Condition进行线程之间的调度。

redis分布式锁 的问题 redlock 脑裂问题

分布式锁的主从架构下的 万一setnx的时候主挂掉了怎么办
在redis主从架构下,当在主从切换时,所丢失可以使用Redlock算法实现。

zookeeper作为分布式锁的选举算法

这个是解释zookeeper的选举算法吗???

redis的持久化

redis持久化方式有两种:RDB和AOF
redis持久化是为了快速恢复数据而不是为了存储数据。
RDB是redis默认的存储方式,是通过快照方式,进行全量备份

redis作为缓存和mysql数据不一致的问题

通过缓存更新策略:
利用Redis的缓存淘汰策略被动更新,这个一致性较差,维护成本低
利用过期时间被动更新,这个一致性较差,维护成本低
在更新数据库是主动更新,一致高,成本较高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值