【系统架构】REST风格

系列文章目录

第一章 系统架构的演进
第二章 REST风格架构


文章目录

  • 系列文章目录
  • 前言
  • 一、进程间的通信
    • 普通管道(Pipe)或者具名管道(Named Pipe)
    • 信号(Signal)
    • 信号量(Semaphore)
    • 消息队列(Message Queue)
    • 共享内存(Shared Memory)
    • 套接字接口(Socket)
  • 二、RPC协议需要解决的基本问题
  • 三、Rest设计风格
    • 什么是Rest?
    • REST的由来
    • 什么是web
    • REST中的几个概念
    • RESTful 的系统
  • 总结


前言

远程服务调用(Remote Service Call, RSC)是一种分布式系统架构中的关键技术,它允许运行在一个网络环境中的不同进程或服务之间进行直接的方法调用,即使这些进程或服务分布在不同的硬件设备或者操作系统上。这一机制是构建微服务架构、云服务集成、以及分布式应用的基础。

关于RPC这种技术,笔者本人也只是从字面上去理解它,尽管实际开发中也经常用到,比如rest远程调用,涉及到的协议http。web Service远程调用,涉及到的协议是SOAP。但我对于RPC 本身解决什么问题、怎么去解决这些问题、为什么要这样解决都或多或少存在认知模糊,一句话就是会用现成的RPC技术,各类支持库和框架,我也是信手拈来,随便看看也能上马应用到项目中去,但对于其本质仍然不了解。本篇文章记录了笔者的学习探索过程,部分内容来源于专业书籍和网络搜索。


一、进程间的通信

先来了解下同一台计算机中的不同进程间该如何通信。我们知道,由于操作系统为每个进程分配独立的内存空间,因此进程间无法直接访问对方的内存区域,需要借助特定的通信机制来实现数据传输和同步。比如说我们的微服务,即使多个服务部署在同一台服务器,但是每个服务的启动运行都是一个独立的进程,端口号也不同。进程里的用户空间都是独立的,无法直接访问。

任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。

在这里插入图片描述

进程间通信大概有如下几种方式

普通管道(Pipe)或者具名管道(Named Pipe)

管道类似于两个进程间的桥梁,可通过管道在进程间传递少量的字符流或字节流。普通管道(匿名管道)只用于有亲缘关系进程(由一个进程启动的另外一个进程)间的通信,具名管道摆脱了普通管道没有名字的限制,除具有管道所有的功能外,它还允许无亲缘关系进程间的通信。管道典型的应用就是命令行中的|操作符,比如:

ps -ef | grep java

这个命令是列出linux或者unix服务器上正在运行的包含java字符串的进程。
在这里插入图片描述
ps与grep都有独立的进程,以上命令就通过管道操作符|将ps命令的标准输出连接到grep命令的标准输入上。

信号(Signal)

信号是一种比较原始的进程间通信方式,用于通知接收进程某个事件已经发生,常用于中断或异常处理,如终止进程、挂起进程等。譬如:

kill -9 pid

以上就是由 Shell 进程向指定 PID 的进程发送 SIGKILL 信号。

信号量(Semaphore)

信号量用于两个进程之间同步协作手段,它相当于操作系统提供的一个特殊变量,程序可以在上面进行wait()和notify()操作。

消息队列(Message Queue)

上面的三种方式只适合传递少量信息,POSIX 标准中定义了消息队列用于进程间数据量较多的通信。进程可以向队列添加消息,被赋予读权限的进程则可以从队列消费消息。消息队列克服了信号承载信息量少,管道只能用于无格式字节流以及缓冲区大小受限等缺点,但实时性相对受限

共享内存(Shared Memory)

允许多个进程访问同一块公共的内存空间,这是效率最高的进程间通信形式。原本每个进程的内存地址空间都是相互隔离的,但操作系统提供了让进程主动创建、映射、分离、控制某一块内存的程序接口。当一块内存被多进程共享时,各个进程往往会与其它通信机制,譬如信号量结合使用,来达到进程间同步及互斥的协调操作。

套接字接口(Socket)

消息队列和共享内存只适合单机多进程间的通信,套接字接口是更为普适的进程间通信机制,可用于不同机器之间的进程通信。套接字(Socket)起初是由 UNIX 系统的 BSD 分支开发出来的,现在已经移植到所有主流的操作系统上。出于效率考虑,当仅限于本机进程间通信时,套接字接口是被优化过的,不会经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等操作,只是简单地将应用层数据从一个进程拷贝到另一个进程,这种进程间通信方式有个专名的名称:UNIX Domain Socket,又叫做 IPC Socket。


二、RPC协议需要解决的基本问题

  • 如何表示数据:这里数据包括了传递给方法的参数,以及方法执行后的返回值。无论是将参数传递给另外一个进程,还是从另外一个进程中取回执行结果,都涉及到它们应该如何表示。进程内的方法调用,使用程序语言预置的和程序员自定义的数据类型,就很容易解决数据表示问题,远程方法调用则完全可能面临交互双方各自使用不同程序语言的情况;即使只支持一种程序语言的 RPC 协议,在不同硬件指令集、不同操作系统下,同样的数据类型也完全可能有不一样表现细节,譬如数据宽度、字节序的差异等等。有效的做法是将交互双方所涉及的数据转换为某种事先约定好的中立数据流格式来进行传输,将数据流转换回不同语言中对应的数据类型来进行使用,这个过程说起来拗口,但相信大家一定很熟悉,就是序列化与反序列化。每种 RPC 协议都应该要有对应的序列化协议,譬如:
    ONC RPC 的External Data Representation (XDR)
    CORBA 的Common Data Representation(CDR)
    Java RMI 的Java Object Serialization Stream Protocol
    gRPC 的Protocol Buffers
    Web Service 的XML Serialization
    众多轻量级 RPC 支持的JSON Serialization
    ……

  • 如何传递数据:准确地说,是指如何通过网络,在两个服务的 Endpoint 之间相互操作、交换数据。这里“交换数据”通常指的是应用层协议,实际传输一般是基于标准的 TCP、UDP 等标准的传输层协议来完成的。两个服务交互不是只扔个序列化数据流来表示参数和结果就行的,许多在此之外信息,譬如异常、超时、安全、认证、授权、事务,等等,都可能产生双方需要交换信息的需求。在计算机科学中,专门有一个名称“Wire Protocol”来用于表示这种两个 Endpoint 之间交换这类数据的行为,常见的 Wire Protocol 有:
    Java RMI 的Java Remote Message Protocol(JRMP,也支持RMI-IIOP)
    CORBA 的Internet Inter ORB Protocol(IIOP,是 GIOP 协议在 IP 协议上的实现版本)
    DDS 的Real Time Publish Subscribe Protocol(RTPS)
    Web Service 的Simple Object Access Protocol(SOAP)
    如果要求足够简单,双方都是 HTTP Endpoint,直接使用 HTTP 协议也是可以的(如 JSON-RPC)
    ……

  • 如何确定方法:这在本地方法调用中并不是太大的问题,编译器或者解释器会根据语言规范,将调用的方法签名转换为进程空间中子过程入口位置的指针。不过一旦要考虑不同语言,事情又立刻麻烦起来,每门语言的方法签名都可能有所差别,所以“如何表示同一个方法”,“如何找到对应的方法”还是得弄个跨语言的统一的标准才行。这个标准做起来可以非常简单,譬如直接给程序的每个方法都规定一个唯一的、在任何机器上都绝不重复的编号,调用时压根不管它什么方法签名是如何定义的,直接传这个编号就能找到对应的方法。这种听起既粗鲁又寒碜的办法,还真的就是 DCE/RPC 当初准备的解决方案。虽然最终 DCE 还是弄出了一套语言无关的接口描述语言(Interface Description Language,IDL),成为此后许多 RPC 参考或依赖的基础(如 CORBA 的 OMG IDL),但那个唯一的绝不重复的编码方案UUID(Universally Unique Identifier)却也被保留且广为流传开来,今天已广泛应用于程序开发的方方面面。类似地,用于表示方法的协议还有:
    Android 的Android Interface Definition Language(AIDL)
    CORBA 的OMG Interface Definition Language(OMG IDL)
    Web Service 的Web Service Description Language(WSDL)
    JSON-RPC 的JSON Web Service Protocol(JSON-WSP)
    ……

以上 RPC 中的三个基本问题,全部都可以在本地方法调用过程中找到相对应的操作。RPC 的想法始于本地方法调用,尽管早已不再追求实现成与本地方法调用完全一致,但其设计思路仍然带有本地方法调用的深刻烙印,抓住两者间的联系来类比,对我们更深刻地理解 RPC 的本质会很有好处。


三、Rest设计风格

什么是Rest?

百度百科定义如下:

REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。

  • 我们更多的将REST称为表述性状态转移。
  • 所谓的表述性状态转移,是对什么的表述?——资源
  • REST省略了主语Resource(资源),全称是 Resource Representational State Transfer,即资源表述性状态转移。通俗来讲就是:资源在网络中以某种表现形式进行状态转移。
  • 如果一个架构符合REST原则,就称它为RESTful架构。

REST的由来

首先简单了解一下作者——Roy Thomas Fielding

  • HTTP/1.0协议专家组成员
  • HTTP/1.1协议专家组负责人
  • Apache HTTP服务器的核心开发者
  • Apache软件基金会合作创始人

什么是web

想要理解Rest,需要知道什么是web,因为Rest就是在web基础上提出来的一种架构风格。

同样的百度百科的一段话:

web(World Wide Web)即全球广域网,也称为万维网,它是一种基于超文本和HTTP的、全球性的、动态交互的、跨平台的分布式图形信息系统。是建立在Internet上的一种网络服务,为浏览者在Internet上查找和浏览信息提供了图形化的、易于访问的直观界面,其中的文档及超级链接将Internet上的信息节点组织成一个互为关联的网状结构。

维基百科
万维网(英语:World Wide Web),亦作“WWW”、“Web”,是一个由许多互相链接的超文本组成的系统,通过互联网访问。
万维网并不等同互联网,万维网只是互联网所能提供的服务其中之一,是靠着互联网运行的一项服务。
互联网和万维网用语经常被使用且没有太多区别。然而,两者是不一样的。互联网是电脑网络互相连接的全球系统。相较之下,万维网是全球收集的文件和其他资源,通过超链接和URIs连接。万维网资源通常使用HTTP访问,这是互联网通信协议的一种。
万维网的核心部分是由三个标准构成的:

统一资源标识符(URI),这是一个统一的为资源定位的系统。
超文本传送协议(HTTP),它负责规定客户端和服务器怎样互相交流。
超文本标记语言(HTML),作用是定义超文本文档的结构和格式。

web是一个由许多相互链接的超文本组成的系统,它使用URI来定位系统中的每一个资源,并通过HTTP协议进行数据的交互。
更抽象的说,Web是一个分布式信息系统,为超文本文件和其他对象(资源)提供访问接口和访问机制。
理解了什么是web,我们便可以更好地理解什么是REST了。作为web自身的架构风格,我们直接给出结论:REST本质上是一种分布式超媒体系统的应用层解决方案,它为资源互通和资源管理的分离提出了一系列架构约束和原则,得到一个功能强、性能好、适宜通信的以网络为基础的应用软件架构。

REST中的几个概念

  • 资源(Resource):比如你现在正在阅读一篇名为《REST 设计风格》的文章,这篇文章的内容本身(你可以将其理解为其蕴含的信息、数据)我们称之为“资源”。无论你是购买的书籍、是在浏览器看的网页、是打印出来看的文稿、是在电脑屏幕上阅读抑或是手机上浏览,尽管呈现的样子各不相同,但其中的信息是不变的,你所阅读的仍是同一份“资源”。

  • 表征(Representation):当你通过电脑浏览器阅读此文章时,浏览器向服务端发出请求“我需要这个资源的 HTML 格式”,服务端向浏览器返回的这个 HTML 就被称之为“表征”,你可能通过其他方式拿到本文的 PDF、Markdown、RSS 等其他形式的版本,它们也同样是一个资源的多种表征。可见“表征”这个概念是指信息与用户交互时的表示形式,这与我们软件分层架构中常说的“表示层”(Presentation Layer)的语义其实是一致的。

  • 状态(State):当你读完了这篇文章,想看后面是什么内容时,你向服务器发出请求“给我下一篇文章”。但是“下一篇”是个相对概念,必须依赖“当前你正在阅读的文章是哪一篇”才能正确回应,这类在特定语境中才能产生的上下文信息即被称为“状态”。我们所说的有状态(Stateful)抑或是无状态(Stateless),都是只相对于服务端来说的,服务器要完成“取下一篇”的请求,要么自己记住用户的状态:这个用户现在阅读的是哪一篇文章,这称为有状态;要么客户端来记住状态,在请求的时候明确告诉服务器:我正在阅读某某文章,现在要读它的下一篇,这称为无状态。

  • 转移(Transfer):无论状态是由服务端还是客户端来提供的,“取下一篇文章”这个行为逻辑必然只能由服务端来提供,因为只有服务端拥有该资源及其表征形式。服务器通过某种方式,把“用户当前阅读的文章”转变成“下一篇文章”,这就被称为“表征状态转移”。

RESTful 的系统

满足REST风格的系统应该满足以下六大原则:

  1. 资源(Resources): 在RESTful系统中,每个URL都代表一个唯一的资源。资源可以是服务器上的文件、数据库中的记录或者任何可以通过网络访问的数据对象。例如,/users/123 可能代表ID为123的用户资源。

  2. 统一接口(Uniform Interface): REST架构的核心就是其统一的接口。它要求系统架构遵循一组标准的、预定义的操作,主要包括HTTP方法(GET, POST, PUT, DELETE等),以及如何通过HTTP状态码传达结果信息。这些规则使得客户端和服务器之间的交互更为简洁且可预测。

  3. 无状态(Stateless): 服务器不存储关于客户端上下文的信息,每次请求都是独立的。会话状态(如认证信息、页面浏览历史)应该由客户端负责维护,并在每次请求时附带发送给服务器。

  4. 可缓存(Cacheable): 利用HTTP协议的缓存机制,客户端可以缓存响应,减少不必要的网络请求,提高效率。通过HTTP响应头,服务器可以指示哪些响应是可以被缓存的。

  5. 分层系统(Layered System): REST架构允许存在中间层(如代理服务器、负载均衡器),而无需客户端了解或关心这些中间层的存在。每一层只需知道与之直接相邻的层次,从而简化了系统的复杂性。

  6. 按需代码(Code-On-Demand,可选): 这一原则是指服务器可以向客户端发送执行代码(通常是JavaScript),动态地增强客户端的功能。但这不是必须的,许多RESTful服务不需要此特性。


总结

关于REST风格架构,笔者学习总结到了如下几个观点:

  • 面向资源的编程思想只适合做 CRUD,面向过程、面向对象编程才能处理真正复杂的业务逻辑

    • 面向过程编程时,为什么要以算法和处理过程为中心,输入数据,输出结果?当然是为了符合计算机世界中主流的交互方式。
    • 面向对象编程时,为什么要将数据和行为统一起来、封装成对象?当然是为了符合现实世界的主流的交互方式。
    • 面向资源编程时,为什么要将数据(资源)作为抽象的主体,把行为看作是统一的接口?当然是为了符合网络世界的主流的交互方式。
  • REST 与 HTTP 完全绑定,不适合应用于要求高性能传输的场景中

    • 带宽和延迟:HTTP协议本身包含较多的开销,比如请求头、响应头等,这些在高频率、低延迟需求的场景下可能会成为瓶颈。

    • 连接建立:每次HTTP请求都需要建立TCP连接(虽然有HTTP Keep-Alive机制减少连接建立的开销),对于需要频繁交互的场景,这会增加额外的延迟。

    • 无状态性:虽然无状态性使得服务端更易于扩展,但每次请求都需携带所有上下文信息,可能增加数据传输量。

    • 协议选择:对于那些对实时性、吞吐量、低延迟有严格要求的应用,如在线游戏、金融交易、实时音视频通信等,REST+HTTP的组合可能不是最佳选择。这些场景可能更适合采用更轻量级的协议或二进制协议(如WebSocket、protobuf配合gRPC、MQTT等),它们能够提供更低的延迟、更高的数据压缩效率和更优的二进制编码性能。

  • REST 不利于事务支持

如果“事务”指的是数据库那种的狭义的刚性 ACID 事务,那除非完全不持有状态,否则分布式系统本身与此就是有矛盾的(CAP 不可兼得),这是分布式的问题而不是 REST 的问题。如果“事务”是指通过服务协议或架构,在分布式服务中,获得对多个数据同时提交的统一协调能力(2PC/3PC),譬如WS-AtomicTransaction、WS-Coordination这样的功能性协议,这 REST 确实不支持,假如你已经理解了这样做的代价,仍决定要这样做的话,Web Service 是比较好的选择。如果“事务”只是指希望保障数据的最终一致性,说明你已经放弃刚性事务了,这才是分布式系统中的正常交互方式,使用 REST 肯定不会有什么阻碍,谈不上“不利于”。

  • REST 没有传输可靠性支持

REST(Representational State Transfer)本身作为一种架构风格,并不直接涉及传输层的可靠性保证。REST关注的是如何设计分布式系统中的组件,以便它们可以以一种统一且可预测的方式相互通信,特别是通过HTTP等应用层协议。关于传输的可靠性,实际上是底层传输协议的责任,而非REST架构直接提供的功能。
为什么这么说?

  • 层次分离:REST架构遵循网络分层原则,其中传输可靠性通常由传输层(如TCP/IP模型中的TCP协议)处理。TCP协议提供了数据包的确认、重传和排序等机制,确保数据的可靠传输,而HTTP协议构建于TCP之上,享受这些可靠性保障。
  • 无状态性:REST的一个核心原则是无状态性,服务器不保存关于客户端的上下文信息,每个请求都是独立的。这要求每个请求都携带完成操作所需的所有信息,但并不直接涉及传输可靠性。
  • HTTP的错误处理:虽然HTTP协议(REST常用协议)提供了一些机制来处理请求失败的情况,如通过状态码(如4xx和5xx系列)来表示客户端或服务器错误,但这更多是关于请求处理的结果反馈,而非传输过程的可靠性保证。
  • 可选的可靠性增强机制:对于需要更高可靠性的RESTful服务,开发者可以采用应用层的解决方案,如幂等性设计、事务补偿逻辑、重试策略、消息队列等,来增强最终的业务操作可靠性,但这已经超出了REST架构本身的范畴。

因此,说REST没有传输可靠性支持,是因为它作为一个架构风格,专注于资源表述和操作,而传输可靠性是由 其下层的网络协议(如TCP)以及上层的应用设计策略共同提供的。

  • REST 缺乏对资源进行“部分”和“批量”的处理能力

REST 开创了面向资源的服务风格,却肯定仍并不完美。以 HTTP 协议为基础给 REST 带来了极大的便捷(不需要额外协议,不需要重复解决一堆基础网络问题,等等),但也是 HTTP 本身成了束缚 REST 的无形牢笼。譬如你仅仅想获得某个用户的姓名,RPC 风格中可以设计一个“getUsernameById”的服务,返回一个字符串,尽管这种服务的通用性实在称不上“设计”二字,但确实可以工作;而 REST 风格中你将向服务端请求整个用户对象,然后丢弃掉返回的结果中该用户除用户名外的其他属性,这便是一种“过度获取”(Overfetching)。

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

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

相关文章

温泉镇旅游微信小程序的设计与实现(论文+源码)_kaic

摘要 旅游业随着经济的快速发展呈现出一派欣欣向荣的景象,尤其是近两年来,各个行业运用科技以及因特网来促进旅游迅速发展,逐渐都显示出了的问题,特别突出的是在线上推广,其缺点也是特别明显。尽管在新冠肺炎的冲击下&…

uni-app前端,社区团购系统搭建部署

目录 前言: 一、社区团购模式: 二、社区团购系统功能: 三、总结: 前言: 区团购系统是一种利用互联网技术和组织力量,通过线上线下结合的方式,为社区居民提供方便快捷的商品和服务采购平台。…

案例学习-存量更新规划实施探索(武汉)

案例学习-存量更新规划实施探索(武汉) 武汉市在早期旧城更新实践中发现零散化的更新往往导致资源配置分散、城市建设破碎化等弊病,特别是由于过于强调项目自身“经济平衡”,在实施过程中也逐步暴露出住宅占比过大、强度偏高、公服…

算法day32

第一题 207. 课程表 步骤一: 通过下图的课程数组,首先画出DAG图(有向无环图) 步骤二: 其次我们按照DAG图,来构建该图的拓扑排序,等有效的点都按照规则排完序后,观察是否有剩下的点的入度不为0&…

MAC M1系统编译ffmpeg-gl-transition

MAC M1系统编译ffmpeg-gl-transition 1. 本人系统2. 编译💰系统准备2.1. 下载【ffmpeg-gl-transition】到用户家目录下,并解压2.2 下载ffmpeg源码2.3. brew安装GLEW glfw32.4 复制vf_gltransition.c文件到ffmpeg2.5 修改ffmpeg源码文件2.6 设置库目录和…

qmt量化交易策略小白学习笔记第32期【qmt编程之获取行业概念数据--如何获取迅投行业成分股数据】

qmt编程之获取迅投行业成分股数据 qmt更加详细的教程方法,会持续慢慢梳理。 也可找寻博主的历史文章,搜索关键词查看解决方案 ! 感谢关注,咨询免费开通量化回测与获取实盘权限,欢迎和博主联系! 获取迅投…

JAVA学习01

8个二进制位代表1字节 不能超出这个范围 文档注释 生成api文档 编码:保存数据的过程 解码:读数据 notic: 编码解码遵循的规范是一样的 gbk:中文 ansi代表gbk - 一个中文字占两个字节 udf-8 一个汉字占三个字节

一文了解Spark引擎的优势及应用场景

Spark引擎诞生的背景 Spark的发展历程可以追溯到2009年,由加州大学伯克利分校的AMPLab研究团队发起。成为Apache软件基金会的孵化项目后,于2012年发布了第一个稳定版本。 以下是Spark的主要发展里程碑: 初始版本发布:2010年开发…

2024全新仿麻豆视频苹果cms源码v10影视模板

下载地址:2024全新仿麻豆视频苹果cms源码v10影视模板 高端大气的设计,适合做电影、连续剧、综艺、动漫、微电影、纪录片、海外剧等视频网站

N3 中文文本分类

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊# 前言 前言 前面学习了相关自然语言编码,这周进行相关实战 导入依赖库和设置设备 import torch import torch.nn as nn import torchvision fro…

虚函数机制-动态绑定的应用

虚函数使得程序在运行的时候根据指针指向对象的类型来确定调用哪个函数。 下图中:都为静态绑定。因为在编译器就确定了可以调用的函数 此时当基类指针指向派生类对象时,因为没有virtual关键字,所以在编译阶段就根据指针类型确定了要指向的函…

秋招突击——第四弹——Java的SSN框架快速入门——Maven

文章目录 引言Maven分模块开发与设计分模块开发的过程 依赖管理可选依赖与排除依赖 继承与聚合聚合继承 属性和版本管理属性扩大集中管理的范围版本管理 多环境开发多环境开发 私服简介安装私服资源操作流程分析上传和下载 总结 引言 前一个部分花了太多时间,后续得…

【Pandas驯化-02】pd.read_csv读取中文出现error解决方法

【Pandas】驯化-02pd.read_csv读取中文出现error解决方法 本次修炼方法请往下查看 🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地! 🎇 相关内容文档获取 微信公众号 &…

MEMS:Lecture 17 Noise MDS

讲义 Minimum Detectable Signal (MDS) Minimum Detectable Signal(最小可检测信号)是指当信号-噪声比(Signal-to-Noise Ratio, SNR)等于1时的输入信号水平。简单来说,MDS 是一个系统能够分辨出信号存在的最低输入信号…

视频网站下载利器yt-dlp参数详解

yt-dlp 是一个强大的命令行工具,用来下载 YouTube 和其他网站上的视频和音频。它拥有丰富的参数,可以定制下载行为,满足各种需求。本文将详细介绍 yt-dlp 的参数使用。 一、基本参数 -f, –format FORMAT: 指定下载格式,可以用视…

mysql:1205-Lock wait timeout exceeded;try restarting transaction

1.现象 2.分析 使用下面sql在自带数据库的information_schema中查询,注意观察那些长时间开启事务又没完成的进程,然后根据进程的db、操作人、主机、事务开启时间和状态,来排查是什么情况导致的事务未完成(代码异常、执行时间超时等等);我这里是异步作业事务执行时间过长导致的 …

H5拟态个人主页

演示地址:科技语者个人主页 (chgskj.cn) 文末有该项目的源码~ 这张图片的效果你是不是非常想要get同款? 源码就是这个样子 这段HTML代码构建了一个个人主页,结合了CSS样式和JavaScript功能。 下面是对代码的主要组成部分的详细解释&#x…

苏姿丰回忆IBM工作经历 曾参与PS3 Cell处理器开发

AMD首席执行官苏姿丰博士曾在IBM工作了13年,先后担任IBM纽约半导体研发中心的副主管、研发部门主管和CEO特别助理。1998年苹果发布的iMac G3里,使用的PowerPC 750是首个采用铜互连技术的处理器,取代了铝互连技术。此前相关报道中曾提及&#…

深入理解计算机系统 CSAPP 家庭作业6.37

S256 N64时: sumA:这个很简单了,不说了 sumB:如下表. i递增时一直不命中 读到j1,i0 即读a[0][1]时 组0存放的是a[48][0] -a[48][3] 接着读a[1][1]时,组16放的是a[49][0]-a[49][3],j递增之后还是一直不命中 组0:a[0][0]a[16][0]a[32][0]a[48][0]a[0][1]组16:a[1][0]a[17][…