JavaIO

news2024/10/3 10:46:55

CPU指令与内核态、用户态

在操作系统中,CPU负责执行指令,这些指令有些来自应用程序,有些是来自底层系统。
有些指令是非常危险的,如清除内存,网络连接等等,如果错误调用的话有可能导致系统崩溃。
因而CPU将指令分为特权指令和非特权指令,对于某些特定的指令,只需要操作系统及其相关模块进行调用。
因而,根据这个特点,操作系统内部也划分出了内核态和用户态。

内核态

内核态拥有完全的底层资源控制权限,可以执行任何的CPU指令,访问任何内存地址,其占有的处理机是不允许被抢占的。

用户态

用户程序是运行在操作系统之上,这些程序运行时称之为用户态,用户态下不能直接访问底层硬件和内存地址,只能通过委托系统调用的方式来访问底层硬件和内存。

从用户态切换到内核态有三种方式

  • 系统调用

  • 外围设备的中断
    当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号。这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序。
    如果先前执行的是用户态下的指令,那么这个切换过程就是用户态转为内核态。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作

  • 异常

在网络I/O的过程中,都涉及到了内核态与用户态的切换。

BIO

阻塞模式同步IO

以前大多数网络通信方式都是阻塞模式的,即:

  • 客户端向服务器端发出请求后,客户端会一直等待(不会再做其他事情),直到服务器端返回结果或者网络出现问题。

  • 服务器端同样的,当在处理某个客户端A发来的请求时,另一个客户端B发来的请求会等待,直到服务器端的这个处理线程完成上一个处理。

传统的BIO通信方式存在几个问题:

  • 同一时间,服务器只能接受来自于客户端A的请求信息;虽然客户端A和客户端B的请求是同时进行的,但客户端B发送的请求信息只能等到服务器接受完A的请求数据后,才能被接受。

  • 由于服务器一次只能处理一个客户端请求,当处理完成并返回后(或者异常时),才能进行第二次请求的处理。很显然,这样的处理方式在高并发的情况下,是不能采用的。


上面说的情况是服务器只有一个线程的情况,那么读者会直接提出我们可以使用多线程技术来解决这个问题(笔者实际生产中就是使用的多线程去解决这种问题的。)


  • 当服务器收到客户端X的请求后,(读取到所有请求数据后)将这个请求送入一个独立线程进行处理,然后主线程继续接受客户端Y的请求。

  • 客户端一侧,也可以使用一个子线程和服务器端进行通信。这样客户端主线程的其他工作就不受影响了,当服务器端有响应信息的时候再由这个子线程通过 监听模式/观察模式(等其他设计模式)通知主线程。

但是使用线程来解决这个问题实际上是有局限性的(见下文非阻塞同步IO)

BIO的问题关键不在于是否使用了多线程(包括线程池)处理这次请求,而在于accept()、read()的操作点都是被阻塞

异步IO模式就是为了解决这样的并发性存在的。

阻塞式同步IO的工作原理

  • 服务器线程发起一个accept动作,询问操作系统是否有新的scoket套接字信息从端口X发送过来。
    注意,是询问操作系统。也就是说socket套接字的IO模式支持是基于操作系统的.那么自然同步IO/异步IO的支持就是需要操作系统级别的了。

  • 如果操作系统没有发现有套接字从指定的端口X来,那么操作系统就会等待。这样serverSocket.accept()方法就会一直等待。这就是为什么accept()方法会阻塞:它内部的实现是使用的操作系统级别的同步IO

阻塞IO和非阻塞IO这两个概念是程序级别的。主要描述的是程序请求操作系统IO操作后,如果IO资源没有准备好,那么程序该如何处理的问题:
前者等待;后者继续执行(并且使用线程一直轮询,直到有IO资源准备好了)
同步IO和非同步IO这两个概念是操作系统级别的。主要描述的是操作系统在收到程序请求IO操作后,如果IO资源没有准备好,该如何响应程序的问题。
前者不响应,直到IO资源准备好以后;后者返回一个标记(好让程序和自己知道以后的数据往哪里通知),当IO资源准备好以后,再用事件机制返回给程序。

非阻塞同步IO

注:阻塞/非阻塞的描述是针对应用程序中的线程进行的,对于阻塞方式的一种改进是引用程序将其"一直等待"的状态主动打开
这种模式下,应用程序的线程不再一直等待操作系统的IO状态,而是在等待一段时间后,就解除阻塞。如果没有得到想要的结果,则再次进行相同的操作。
这样的工作方式,使得应用程序的线程不会一直阻塞,而是可以进行一些其他工作。

在这种模式下,等待数据的过程是非阻塞的,但是数据拷贝时,仍然是阻塞的,他更多是通过多线程去使得socket套接字的处理互相不受影响。

在这种模式下,依然存在以下问题:

  • 虽然在服务器端,请求的处理交给了一个独立线程进行,但是操作系统通知accept()的方式还是单个的。也就是,实际上是服务器接收到数据报文后的“业务处理过程”可以多线程,但是数据报文的接受还是需要一个一个的来

  • 在linux系统中,可以创建的线程是有限的。我们可以通过cat /proc/sys/kernel/threads-max 命令查看可以创建的最大线程数。当然这个值是可以更改的,但是线程越多,CPU切换所需的时间也就越长,用来处理真正业务的需求也就越少。

  • 创建一个线程是有较大的资源消耗的。JVM创建一个线程的时候,即使这个线程不做任何的工作,JVM都会分配一个堆栈空间。这个空间的大小默认为128K,您可以通过-Xss参数进行调整。

  • 无论使用的多线程、还是加入了非阻塞模式,这都是在应用程序层面的处理,而底层socketServer所匹配的操作系统的IO模型始终是“同步IO”,最根本的问题并没有解决。

  • 当然您还可以使用ThreadPoolExecutor线程池来缓解线程的创建问题,但是又会造成BlockingQueue积压任务的持续增加,同样消耗了大量资源。

    • 另外,如果您的应用程序大量使用长连接的话,线程是不会关闭的。这样系统资源的消耗更容易失控。
  • 那么,如果你真想单纯使用线程解决阻塞的问题,那么您自己都可以算出来您一个服务器节点可以一次接受多大的并发了。看来,单纯使用线程解决这个问题不是最好的办法。

个人的理解,无论是阻塞式同步IO还是非阻塞式同步IO,他都没有跳出BIO,BIO的阻塞,是操作系统层面的阻塞,而不是在请求处理层面的阻塞!

NIO

NIO是同步非阻塞模型,服务端的一个线程可以处理多个请求,客户端发送的连接请求注册在多路复用器Selector上,服务端线程通过轮询多路复用器查看是否有IO请求,有则进行处理。

多路复用IO

多路复用IO,从本质上看还是一种同步IO,因为它没有100%消除IO_WAIT,操作系统也没有为它提供“主动通知”机制。但是多路复用IO的处理速度已经相当快了,利用设备执行IO操作的时间,操作系统可以继续执行IO请求。并同样采用周期性轮询的方式,获取一批IO操作请求的执行响应。

多路复用IO概念

多路复用IO技术最适用的是"高并发"场景,所谓高并发是指1毫秒内至少同时有上千个连接请求准备好。其他情况下多路复用IO技术发挥不出来它的优势。另一方面,使用JAVA NIO进行功能实现,相对于传统的Socket套接字实现要复杂一些,所以实际应用中,需要根据自己的业务需求进行技术选择。

重要概念如下:

  1. channel
    通道,被建立的一个应用程序和操作系统交互事件、传递内容的渠道(注意是连接到操作系统)。一个通道会有一个专属的文件状态描述符。那么既然是和操作系统进行内容的传递,那么说明应用程序可以通过通道读取数据,也可以通过通道向操作系统写数据。
    JAVA NIO框架中,自有的Channel通道包括:

    • ServerSocketChannel:应用服务器程序的监听通道。只有通过这个通道,应用程序才能向操作系统注册支持“多路复用IO”的端口监听。同时支持UDP协议和TCP协议。

    • SocketChannel:TCP Socket套接字的监听通道,一个Socket套接字对应了一个客户端IP:端口 到 服务器IP:端口的通信连接。

    • DatagramChannel:UDP 数据报文的监听通道。

  2. Buffer
    数据缓存区:在JAVA NIO 框架中,为了保证每个通道的数据读写速度JAVA NIO 框架为每一种需要支持数据读写的通道集成了Buffer的支持。
    这句话怎么理解呢?例如ServerSocketChannel通道它只支持对OP_ACCEPT事件的监听,所以它是不能直接进行网络数据内容的读写的。所以ServerSocketChannel是没有集成Buffer的。
    Buffer有两种工作模式:写模式和读模式。在读模式下,应用程序只能从Buffer中读取数据,不能进行写操作。但是在写模式下,应用程序是可以进行读操作的,这就表示可能会出现脏读的情况。所以一旦您决定要从Buffer中读取数据,一定要将Buffer的状态改为读模式。

  3. Selector
    Selector的英文含义是“选择器”,不过根据我们详细介绍的Selector的岗位职责,您可以把它称之为“轮询代理器”、“事件订阅器”、“channel容器管理机”都行。

    • 事件订阅和Channel管理
      应用程序将向Selector对象注册需要它关注的Channel,以及具体的某一个Channel会对哪些IO事件感兴趣。Selector中也会维护一个“已经注册的Channel”的容器。以下代码来自WindowsSelectorImpl实现类中,对已经注册的Channel的管理容器:
    • 轮询代理
      应用层不再通过阻塞模式或者非阻塞模式直接询问操作系统“事件有没有发生”,而是由Selector代其询问。
      在个人看来,这就是一种代理模式的应用,由Selector作为代理,将轮询操作交由其执行。

多路复用IO优缺点

  • 不用再使用多线程来进行IO处理了(包括操作系统内核IO管理模块和应用程序进程而言)。当然实际业务的处理中,应用程序进程还是可以引入线程池技术的

  • 同一个端口可以处理多种协议,例如,使用ServerSocketChannel的服务器端口监听,既可以处理TCP协议又可以处理UDP协议。

  • 操作系统级别的优化:多路复用IO技术可以是操作系统级别在一个端口上能够同时接受多个客户端的IO事件。同时具有之前我们讲到的阻塞式同步IO和非阻塞式同步IO的所有特点。Selector的一部分作用更相当于“轮询代理器”。

  • 都是同步IO:目前我们介绍的 阻塞式IO、非阻塞式IO甚至包括多路复用IO,这些都是基于操作系统级别对“同步IO”的实现。我们一直在说“同步IO”,一直都没有详细说,什么叫做“同步IO”。实际上一句话就可以说清楚:只有上层(包括上层的某种代理机制)系统询问我是否有某个事件发生了,否则我不会主动告诉上层系统事件发生了。

目前流行的多路复用IO实现主要包括四种:select、poll、epoll、kqueue

IO模型相对性能关键思路操作系统Java支持情况
select较高Reactorwindows/Linux支持,Reactor模式(反应器设计模式)。Linux操作系统的 kernels 2.4内核版本之前,默认使用select;而目前windows下对同步IO的支持,都是select模型
poll较高ReactorLinuxLinux下的JAVA NIO框架,Linux kernels 2.6内核版本之前使用poll进行支持。也是使用的Reactor模式
epollReactor/ProactorLinuxLinux kernels 2.6内核版本及以后使用epoll进行支持;Linux kernels 2.6内核版本之前使用poll进行支持;另外一定注意,由于Linux下没有Windows下的IOCP技术提供真正的 异步IO 支持,所以Linux下使用epoll模拟异步IO
kqueueProactorLinux目前JAVA的版本不支持

select、poll、epoll比较

select 基于轮询机制
fd: linux中, 每一个进程在内核中,都对应有一个“打开文件”数组,存放指向文件对象的指针,而 fd 是这个数组的下标。
我们对文件进行操作时,系统调用,将fd传入内核,内核通过fd找到文件,对文件进行操作。
select本质上是通过设置或检查存放fd标志位的数据结构进行下一步处理。
select模型的缺点:

  1. 单个进程可监视的fd数量被限制

  2. 对socket是线性扫描,即轮询,效率较低: 仅知道有I/O事件发生,却不知是哪几个流,只会无差异轮询所有流,找出能读数据或写数据的流进行操作。同时处理的流越多,无差别轮询时间越长

当socket较多时,每次select都要通过遍历FD_SETSIZE个socket,不管是否活跃,这会浪费很多CPU时间。如果能给 socket 注册某个回调函数,当他们活跃时,自动完成相关操作,即可避免轮询。

poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的.

epoll基于操作系统支持的I/O通知机制,支持水平触发和边缘触发两种模式
epoll模型修改主动轮询为被动通知,当有事件发生时,被动接收通知。所以epoll模型注册套接字后,主程序可做其他事情,当事件发生时,接收到通知后再去处理。
epoll支持EPOLLLT和EPOLLET两种触发模式:

  • LT,默认的模式(水平触发) 只要该fd还有数据可读,每次 epoll_wait 都会返回它的事件,提醒用户程序去操作,
  • ET是“高速”模式(边缘触发)只会提示一次,直到下次再有数据流入之前都不会再提示,无论fd中是否还有数据可读。所以在ET模式下,read一个fd的时候一定要把它的buffer读完,即读到read返回值小于请求值或遇到EAGAIN错误

poll为什么要有EPOLL ET触发模式?
如果采用EPOLL LT模式的话,系统中一旦有大量你不需要读写的就绪文件描述符,它们每次调用epoll_wait都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率。
而采用EPOLL ET这种边沿触发模式的话,当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。
如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!
这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符。

因为epoll内核中实现是根据每个fd上的callback函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll没有前面两者的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。

Reactor模式

Reactor模式是基于事件驱动开发的,服务端程序处理传入多路请求,并将它们同步分派给请求对应的处理线程。
Reactor模式也叫Dispatcher模式,即I/O多路复用统一监听事件,收到事件后分发(Dispatch给某进程),这是编写高性能网络服务器的必备技术之一。

Reactor模式以NIO为底层支持,核心组成部分包括Reactor和Handler

  • Reactor:Reactor在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对I/O事件做出反应
  • Handlers:处理程序执行I/O事件要完成的实际事件,Reactor通过调度适当的处理程序来响应I/O事件,处理程序执行非阻塞操作.

根据Reactor的数量和Handler线程数量,可以将Reactor分为三种模型:

  • 单线程模型 (单Reactor单线程)


    Reactor内部通过Selector监控连接事件,收到事件后通过dispatch进行分发,如果是连接建立的事件,则由Acceptor处理,Acceptor通过accept接受连接,并创建一个Handler来处理连接后续的各种事件,如果是读写事件,直接调用连接对应的Handler来处理。

Handler完成read -> (decode -> compute -> encode) ->send的业务流程。

这种模型好处是简单,坏处却很明显,当某个Handler阻塞时,会导致其他客户端的handler和accpetor都得不到执行,无法做到高性能,只适用于业务处理非常快速的场景,如redis读写操作。

  • 多线程模型 (单Reactor多线程)

主线程中,Reactor对象通过Selector监控连接事件,收到事件后通过dispatch进行分发,如果是连接建立事件,则由Acceptor处理,Acceptor通过accept接收连接,并创建一个Handler来处理后续事件,而Handler只负责响应事件,不进行业务操作,也就是只进行read读取数据和write写出数据,业务处理交给一个线程池进行处理。

线程池分配一个线程完成真正的业务处理,然后将响应结果交给主进程的Handler处理,Handler将结果send给client。

单Reactor承担所有事件的监听和响应,而当我们的服务端遇到大量的客户端同时进行连接,或者在请求连接时执行一些耗时操作,比如身份认证,权限检查等,这种瞬时的高并发就容易成为性能瓶颈。

  • 主从多线程模型 (多Reactor多线程)
    正在上传…重新上传取消

存在多个Reactor,每个Reactor都有自己的Selector选择器,线程和dispatch。

主线程中的mainReactor通过自己的Selector监控连接建立事件,收到事件后通过Accpetor接收,将新的连接分配给某个子线程。

子线程中的subReactor将mainReactor分配的连接加入连接队列中通过自己的Selector进行监听,并创建一个Handler用于处理后续事件。

Handler完成read -> 业务处理 -> send的完整业务流程。

在Reactor中,被拆分的小线程或者子过程对应的是handler,每一种handler会出处理一种event。这里会有一个全局的管理者selector,我们需要把channel注册感兴趣的事件,那么这个selector就会不断在channel上检测是否有该类型的事件发生,如果没有,那么主线程就会被阻塞,否则就会调用相应的事件处理函数即handler来处理。

Redis中的IO多路复用机制(基于Reactor模式)

Redis基于Reactor模式开发了自己的网络事件处理器,称之为文件事件处理器(File Event Hanlder)。文件事件处理器由Socket、IO多路复用程序、文件事件分派器(dispather),事件处理器(handler)四部分组成。

IO多路复用程序会同时监听多个socket,当被监听的socket准备好执行accept、read、write、close等操作时,与这些操作相对应的文件事件就会产生。IO多路复用程序会把所有产生事件的socket压入一个队列中,然后有序地每次仅一个socket的方式传送给文件事件分派器,文件事件分派器接收到socket之后会根据socket产生的事件类型调用对应的事件处理器进行处理。

AIO

异步IO

IO模型是由操作系统提供支持,且上文提到的三种IO模型都是同步IO,都是采用的“应用程序不询问我,我绝不会主动通知”的方式。

异步IO则是采用“订阅-通知”模式:即应用程序向操作系统注册IO监听,然后继续做自己的事情。当操作系统发生IO事件,并且准备好数据后,在主动通知应用程序,触发相应的函数:

  • 和同步IO一样,异步IO也是由操作系统进行支持的。微软的windows系统提供了一种异步IO技术:IOCP(I/O Completion Port,I/O完成端口);

  • Linux下由于没有这种异步IO技术,所以使用的是epoll(上文介绍过的一种多路复用IO技术的实现)对异步IO进行模拟。

注意在JAVA NIO框架中,我们说到了一个重要概念“selector”(选择器)。它负责代替应用查询中所有已注册的通道到操作系统中进行IO事件轮询、管理当前注册的通道集合,定位发生事件的通道等操操作;但是在JAVA AIO框架中,由于应用程序不是“轮询”方式,而是订阅-通知方式,所以不再需要“selector”(选择器)了,改由channel通道直接到操作系统注册监听。

JAVA AIO框架中,只实现了两种网络IO通道“AsynchronousServerSocketChannel”(服务器监听通道)、“AsynchronousSocketChannel”(socket套接字通道)。但是无论哪种通道他们都有独立的fileDescriptor(文件标识符)、attachment(附件,附件可以使任意对象,类似“通道上下文”),并被独立的SocketChannelReadHandle类实例引用。

JAVA NIO和JAVA AIO框架,除了因为操作系统的实现不一样而去掉了Selector外,其他的重要概念都是存在的,例如上文中提到的Channel的概念,还有演示代码中使用的Buffer缓存方式。实际上JAVA NIO和JAVA AIO框架您可以看成是一套完整的“高并发IO处理”的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/95040.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Excel表格的打开密码如何设置和取消?

给Excel表格设置“打开密码”是保护表格的其中一种方法,这样只有输入正确的密码才能打开表格。 那Excel表格的打开密码如何设置和取消呢? 首先,打开Excel表格,点击菜单栏的【文件】选项,然后依次选择【信息】-【保护…

java项目-第175期ssm高校校园点餐系统-java毕业设计

java项目-第175期ssm高校校园点餐系统-java毕业设计 【源码请到下载专栏下载】 今天分享的项目是《ssm高校校园点餐系统》 该项目分为2个角色,管理员、用户和食堂。 用户可以浏览前台,查看菜品,并进行预约和选座; 同时可以跳转到后台查看自己…

基于jsp+mysql+ssm矿场仓储管理系统-计算机毕业设计

项目介绍 本系统采用了BS架构,利用web技术实现了矿场信息的后台管理,针对矿物质的相关信息,销售情况进行管理。是一款后台信息管理系统,具有管理员和员工两个用户权限,系统设计简单,主要是学习资源&#x…

[R语言]正态分布

目录 分布 连续型变量的分布 正态分布 正态分布的推导 正态分布密度曲线 dnorm 正态分布的概率计算 正态分布累积曲线 总体分位数和尾概率 正态分布案例之一 R语言正态分布函数 正态分布相应的概率计算 正态分布的检验 shapiro.test()函数 Kolmogorov-Smirnov连续…

5.3 10篇美食类小红书爆文拆解【玩赚小红书】

案例一:金牌保姆分享12个万能做饭小技巧 ​ 标题: 万能做饭小技巧这个词可以看的出这个方法都是偏向技巧类,对于人人都有做饭的需求来说,也忍不住让人想看看到底是什么内容。“金牌保姆”四个字可谓是将“万能”这2个字完美诠释&…

首次曝光,Alibaba大佬手撸堪称神级的SpringSecurity全彩手册

有人调侃我们说: 程序员不如送外卖。送外卖是搬运食物,自己是搬运代码,都不产出新的东西……透支体力,又消耗健康,可替代性极强,30岁之后就要面临被优化的危险……想跳槽,但是更高的平台难进&a…

2023年你应该了解的五大采购管理趋势

采购的未来看起来非常具有前景。随着新技术的出现,采购专业人员有许多新的机会来简化他们的工作并节省企业的资金。 以下是一些你应该了解的2023年采购领域趋势。 1、自动化 采购的最大趋势之一是各种任务的自动化。这可以是任何事情,从自动化询价&am…

STC15 - C51 - 操作寄存器时, 不要操作不相关的位

文章目录STC15 - C51 - 操作寄存器时, 不要操作不相关的位概述笔记生成.i文件的选项编译工程后, 查看.list文件和.i文件.c文件相关内容.list文件.i文件通过.i文件(预处理文件), 就可以看到最终实现代码有啥区别了不好使的代码好使的代码总结ENDSTC15 - C51 - 操作寄存器时, 不要…

分布式系统(故障、恢复)

文章目录故障模型可靠组播基于基本组播基于 IP 组播协定问题ConsensusByzantine generalsInteractive Consistency一些重要结论分布式恢复后向恢复Checkpointing AlgorithmCoordinated CheckpointingIndependent CheckpointingMessage Logging AlgorithmPessimistic message lo…

[附源码]Node.js计算机毕业设计高校运动会管理系统 Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

95.(leaflet之家)leaflet态势标绘-进攻方向采集(燕尾)

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html> <

快速传输大文件,怎么通过网络传大文件给对方(1G以上)

在生活和工作中&#xff0c;我们总是要发送一些比较大的文件给别人&#xff0c;或者在自己的设备之间。在互联网日益发达的今天&#xff0c;我们可以用什么方法通过互联网快速传输大文件&#xff0c;发送1G以上的文件&#xff1f; 一、使用QQ传 在电脑上打开QQ&#xff0c;选…

【技术评论】大数据时代,区块链如何解决数据安全和隐私问题

发表时间&#xff1a;2022年6月23日 信息来源&#xff1a;bsvblockchain.org 在这个时代&#xff0c;像GDPR和HIPAA这样的措施为消费者带来了前所未有的数据保护水平&#xff0c;人们理所当然地想知道&#xff0c;由区块链驱动的数据解决方案如何能够符合这些法规的要求。 (全…

PHP代码审计系列(四)

PHP代码审计系列&#xff08;四&#xff09; 本系列将收集多个PHP代码安全审计项目从易到难&#xff0c;并加入个人详细的源码解读。此系列将进行持续更新。 SQL注入or绕过 源码如下 <?php#GOAL: login as admin,then get the flag; error_reporting(0); require db.in…

Java用户线程和守护线程,线程默认Daemon值是false吗?

文章目录用户线程守护线程必须要在start()方法之前设置守护线程线程默认的daemon值总结Java中通常有两种线程&#xff1a; 用户线程和 守护线程&#xff08;也被称为服务线程&#xff09;通过 Thread.setDaemon(false)设置为 用户线程&#xff08;默认为用户线程&#xff09;通…

【鸿蒙应用开发系列】- 应用置灰方案实现讲解

在某些特殊的日子里&#xff0c;有时候需要对应用进行一个置灰显示处理&#xff0c;在Android中&#xff0c;提供了一些很方便的方法&#xff0c;可以对控件或者应用进行灰色的展示 Android应用置灰方式 1、使用灰色主题皮肤&#xff08;这个开发量比较大&#xff09; 2、图…

LOAM论文阅读

1. 摘要 本文提出一种实现激光雷达里程计与建图方法&#xff0c;使用6自由度的双轴激光雷达进行距离测量。问题的难点在于激光雷达的每一个点的时间戳都不同&#xff0c;运动估计的误差会影响激光点云的配准。目前相关的3D地图一般使用离线批处理方法构建&#xff0c;且使用闭…

回归预测 | MATLAB实现SSA-BiLSTM麻雀算法优化双向长短期记忆神经网络多输入单输出

回归预测 | MATLAB实现SSA-BiLSTM麻雀算法优化双向长短期记忆神经网络多输入单输出 目录回归预测 | MATLAB实现SSA-BiLSTM麻雀算法优化双向长短期记忆神经网络多输入单输出预测效果基本介绍程序设计参考资料预测效果 基本介绍 麻雀搜索算法(Sparrow Search Algorithm, SSA)是于…

2_Oracle_手工建库

一、手工建库的目的 1、方便理解Oracle的体系结构 2、更快更好的创建数据库 3、方便了解建库的每步细节 4、手工建库的实用性 二、dbca生成的脚本 /app/oracle/admin/orcl/scripts/ orcl.sh #!/bin/sh OLD_UMASKumask umask 0027 mkdir -p /app/oracle/admin/orcl/adump mkdi…

2022年度调味品十大热门品牌排行

调味品行业总量大&#xff0c;种类繁多&#xff0c;需求量大&#xff0c;且调味品作为生活必需品&#xff0c;与饮食文化紧密联系&#xff0c;也与人们的生活息息相关&#xff0c;如近日各省陆续全面放开后&#xff0c;也出现了北方抢黄头罐头南方抢醋的风潮。总体来说&#xf…