SpringMVC-01 Web基础介绍

2023-05-16

文章目录

  • 1 CGI
    • 1.1 CGI原理
    • 1.2 输入/出
    • 1.3 环境变量
      • 1.3.1 与请求相关的环境变量
      • 1.3.2 与服务器相关的环境变量
      • 1.3.3 与客户端相关的环境变量
      • 1.3.4 详细说明
        • 1.3.4.1 REQUEST_METHOD
    • 1.4 各种语言的封装
      • 1.4.1 C语言
      • 1.4.2 C++
      • 1.4.3 PHP
      • 1.4.4 Perl
      • 1.4.5 Python
    • 1.5 现代CGI的编程范式
    • 1.6 缺点
  • 2 FastCGI
    • 2.1 FastCGI的工作流程
  • 3 Servlet
    • 3.1 Servlet有用的资源
    • 3.2 Servlet容器
  • 4 WSGI
    • 4.1 WSGI构成
      • 4.1.1 WSGI Server/gateway
      • 4.1.2 WSGI Application
      • 4.1.3 WSGI MiddleWare
  • 参考资料

简述下Web开发基础概念,从早期的CGI,FastCGI,再到Servlet,以及Python的WSGI,uWSGI等。

1 CGI

CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。

早期的Web服务器,只能响应浏览器发来的HTTP静态资源的请求,并将存储在服务器中的静态资源返回给浏览器。随着Web技术的发展,逐渐出现了动态技术,但是Web服务器并不能够直接运行动态脚本,为了解决Web服务器与外部应用程序(CGI程序)之间数据互通,于是出现了CGI(Common Gateway Interface)通用网关接口。简单理解,可以认为CGI是Web服务器和运行其上的应用程序进行“交流”的一种约定。

1.1 CGI原理

组成CGI通信系统的是两部分:一部分是html页面,就是在用户端浏览器上显示的页面。另一部分则是运行在服务器上的Cgi程序。它们之间的通讯方式如下图:

image.png

CGI通信中会包含两种通信协议:

  • 服务器和客户端之间的HTTP通信,即客户端的浏览器和服务器端的HTTP服务器之间的HTTP通信。
  • 服务器和CGI程序之间是通过标准输入输出来进行数据传递。

CGI则是Web服务器和一个独立的进程之间的协议,它肩负着网关Gateway的职责,把HTTP请求Request的Header头设置成进程的环境变量,HTTP请求的Body正文设置成进程的标准输入,进程的标准输出设置为HTTP响应Response,包含Header头和Body正文。

简单来说,CGI实际上是一个接口标准Interface。而通常所说的CGI指代其实是CGI程序,也就是实现了CGI接口标准的程序,只要编程语言具有标准输入、标准输出和环境变量,就可以用来编写CGI程序。

1.2 输入/出

Web服务器在接收到用户浏览器的HTTP请求,比如请求如下URL:

http://www.xxxx.me/cgi-bin/helloworld.cgi

此时在Web服务器调用helloworld.cgi之前,会把各类HTTP请求中的信息以环境变量的方式写入OS。CGI程序本质是OS上一个普通的可执行程序,它通过语言本身库函数来获取环境变量,从而获得数据输入。

环境变量外,另外一个CGI程序获取数据的方式就是标准输入(stdin)。如post请求一个CGI的URL,那么POST的数据,CGI是通过标准输入来获取到的。

CGI输出HTML页面,则是向标准输出去写入数据即可。比如printfcout,比如System.out.println,又比如printecho等。因为Web服务器已经做了重定向,将标准输出重定向给Web服务器的与浏览器连接的socket。CGI的输出承担的是HTTP协议的响应部分,因此除了正常的HTML页面内容,HTTP响应报头也要标准输出出来。

cout<<"Content-Type:text/html\n\n"<<endl;  

1.3 环境变量

CGI程序通过标准输入(STDIN)和标准输出(STDOUT)进行数据的输入输出,此外CGI程序还通过环境变量来得到输入,操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了一些环境变量,用来向CGI程序传递一些重要的参数。

对于CGI程序来说,它继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。

当一个CGI程序不是被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制。当这个CGI程序被HTTP服务器调用时,它的环境变量就会多了以下关于HTTP服务器、客户端、CGI传输过程等项目。

环境变量是一个保存用户信息的内存区。当客户端的用户通过浏览器发出CGI请求时,服务器就寻找本地的相应CGI程序并执行它。在执行CGI程序的同时,服务器把该用户的信息保存到环境变量里。接下来,CGI程序的执行流程是这样的:查询与该CGI程序进程相应的环境变量:第一步是request_method,如果是POST,就从环境变量的len,然后到该进程相应的标准输入取出len长的数据。如果是GET,则用户数据就在环境变量的QUERY_STRING里。

1.3.1 与请求相关的环境变量

变量名称说明
REQUEST_METHOD服务器与CGI程序之间的信息传输方式。一般包括两种:POSTGET,其他方式也要考虑。
QUERY_STRING采用GET时所传输的信息,GET方法还通过此变量向CGI程序传递Form表单中的数据
CONTENT_LENGTHSTDIO中的有效信息长度
CONTENT_TYPE指示所传来的信息的MIME类型,例如application/x-www-form-urlencoded,表示数据来自HTML表单,并且经过了URL编码。
CONTENT_FILE使用Windows HTTPd/WinCGI标准时,用来传送数据的文件名
PATH_INFO路径信息
PATH_TRANSLATEDCGI程序的完整路径名
SCRIPT_NAME所调用的CGI程序的名字

1.3.2 与服务器相关的环境变量

变量名称说明
GATEWAY_INTERFACE服务器所实现的CGI版本
SERVER_NAME服务器的IP或名字
SERVER_PORT主机的端口号
SERVER_SOFTWARE调用CGI程序的HTTP服务器的名称和版本号

1.3.3 与客户端相关的环境变量

变量名称说明
REMOTE_ADDR客户机的主机名
REMOTE_HOST客户机的IP地址
ACCEPT列出能被次请求接受的应答方式。客户机所支持的MIME类型清单,内容如:image/gif,image/jpeg
ACCEPT_ENCODING列出客户机支持的编码方式
AUTORIZATION表明被证实了的用户
FORM列出客户机的EMAIL地址
IF_MODIFIED_SINGCE当用GET方式请求并且只有当文档比指定日期更早时才返回数据
PRAGMA设定将来要用到的服务器代码
REFFERER指出连接到当前文档的文档URL
USER_AGENT客户端浏览器的消息

1.3.4 详细说明

1.3.4.1 REQUEST_METHOD

它的值一般包括两种:POSTGET,但编写CGI程序时,最后还要考虑其他的情况。

1.POST方法

如果采用POST方法,那么客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH。客户端用POST方式发送数据有一个相应的MIME类型(通用Internet邮件扩充服务:Multi-purpose Internet Mail Extensions)。目前,MIME类型一般是:application/x-wwww-form-urlencoded,该类型表示数据来自HTML表单。该类型记录在环境变量CONTENT_TYPE中,CGI程序应该检查该变量的值。

2.GET方法

在该方法下,CGI程序无法直接从服务器的标准输入中获取数据,因为服务器把它从标准输入接收到得数据编码到环境变量QUERY_STRING(或PATH_INFO)。

3.POST与GET的区别:

以GET方式接收的数据是有长度限制,而用POST方式接收的数据是没有长度限制的。并且,以GET方式发送数据,可以通过URL的形式来发送,但POST方式发送的数据必须要通过 Form 才到发送。

1.4 各种语言的封装

1.4.1 C语言

C语言中如果想要实现CGI编程,一般均自行开发,可以参考以下文章,这里不做赘述。

c语言实现cgi

1.4.2 C++

C++开发CGI可以使用GUN的一个开源库 Cgicc。可以满足常用的各类需求,除了解析get/post请求外,还能重定向,还可以设置Cookie,还可以上传文件等等等等。

美中不足的就是Cgicc库不支持SESSION。但是这个问题不大,我们可以很容易使用Cookie来实现SESSION功能。由于CGI本身是请求一次就创建一个进程,返回之后进程就结束(下文的FastCGI除外)。这时要在服务端维持一个SESSION的变量可选的解决方案是:用文件存储或者在Redis、Memcached等内存数据库中存储。而发给客户端的SESSIONID就用Cgicc已经支持的Cookie功能来完成,就可以了。

以下网络中的一个demo示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int get_inputs()
{
int length;
char *method;
char *inputstring;
 
method = getenv("REQUEST_METHOD"); //将返回结果赋予指针

if(method == NULL)
    return 1;       //找不到环境变量REQUEST_METHOD
    
if(!strcmp(method, "POST"))  // POST方法
{
    length = atoi(getenv("CONTENT_LENGTH")); //结果是字符,需要转换
    if(length != 0)
    {
        inputstring = malloc(sizeof(char)*length + 1) //必须申请缓存,因为stdin是不带缓存的。
        fread(inputstring, sizeof(char), length, stdin); //从标准输入读取一定数据
    }
} 
else if(!strcmp(method, "GET"))
{
 
    Inputstring = getenv("QUERY_STRING");   
    length = strlen(inputstring);
}
 
if(length == 0)
    return 0;
}

1.4.3 PHP

PHP-CGI是PHP自带的FastCGI管理器。

而PHP-FPM(FastCGI Process Manager),它是比旧的FastCGI更好的FastCGI实现。它作为独立的 FastCGI 服务器运行。一般来说,它是Web服务器(Apache,Nginx…)的PHP接口,允许Web Server与PHP交互。

1.4.4 Perl

这里也是给出一个网络上的demo示例:

$method = $ENV{'REQUEST_METHOD'};
 
if($method eq 'POST')
{
    Read(STDIN, $input, $ENV{'CONTENT_LENGTH'});
}
 
if($method eq 'GET' || $method eq 'HEAD')
{
    $input = $ENV{'QUERY_STRING'};
}
 
if($input eq "")
{
    &print_form;
    exit;
}

1.4.5 Python

Python代码实现更简单,cgi.FieldStorage()返回一个字典,字典的每一个key就是变量名,key对应的值就是变量名的值,更本无需用户再去进行数据解码!

获取环境变量的时候,如果先判断REQUEST_METHOD是否存在,程序会更健壮,否则在某些情况下可能会造成程序崩溃。因为假若CGI程序不是由服务器调用的,那么环境变量集里就没有与CGI相关的环境变量(如REQUEST_METHODREMOTE_ADDR等)添加进来,也就是说getenv("REQUEST_METHOD")将返回NULL!

#!/usr/local/bin/python
 
import cgi

def main():
    form = cgi.FieldStorage()

1.5 现代CGI的编程范式

CGI可以直接返回一个html网页。CGI程序本身也可以进行各种计算、逻辑处理任务。随着各类web前后端技术的发展,以及大数据、高并发的Server使用场景越来越多。现代的CGI的用法,在发生变化。

现在,越来越多的任务从后端转移到前端,前端页面利用丰富的Js技术来进行更多的处理。

  1. JS可以使用Ajax技术来向后台CGI发起数据请求。Ajax完成的是不需要刷新整个页面就可以加载后端数据(比如从数据库中取出)。
  2. CGI一般不再用于直接返回html页面,同时将复杂的计算、IO任务下沉到后端(后端可以进一步进行路由转发,实现负载均衡)。使CGI作为前后端之间的中间层。彼时CGI的职能是完成基本的数据交换:解析前端数据请求,再转发给对应后端;然后从后端取回数据,给前端返回XML或JSON。
  3. 前端JS利用XML/JSON中的数据来进行填充,绘制出丰富的页面。

1.6 缺点

CGI有一大硬伤。每次HTTP请求CGI,Web服务器都有启动一个新的进程去执行这个CGI程序,即颇具Unix特色的fork-and-execute。当用户请求量大的时候,这个fork-and-execute的操作会严重拖慢Web服务器的性能。

时势造英雄,FastCGI(简称FCGI)技术应运而生。简单来说,其本质就是一个常驻内存的进程池技术,由调度器负责将传递过来的CGI请求发送给处理CGI的handler进程来处理。在一个请求处理完成之后,该处理进程不销毁,继续等待下一个请求的到来。

当然FCGI其实也并不是什么惊世骇俗的创意,很容易联想到的解决思路。资源池是后台性能优化中的常见套路。Java发明的Servlet技术也是一种常驻内存的网关通信技术,只不过它采用的是多线程而非进程。

2 FastCGI

FastCGI是Web服务器与处理程序之间通信的一种协议,是CGI的改进版本。由于CGI程序反复加载CGI而造成性能低下,如果CGI程序保持在内存中并接收FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等。

FastCGI就是常驻型的CGI,可以一直运行。在请求到达时不会耗费时间去Fork创建一个进程来处理。FastCGI是语言无关的、可伸缩架构的CGI开放扩展,它将CGI解释器进程保持在内存中,因此获得较高的性能。

2.1 FastCGI的工作流程

  1. Web服务器启动时载入FastCGI进程管理,如IIS的ISAPI、Apache的Module…
  2. FastCGI进程管理器自身初始化,并启动多个CGI解释器进程php-cgi并等待Web服务器的连接。
  3. 当客户端请求到达Web服务器时,FastCGI进程管理器选择并连接一个CGI解释器,Web服务器将CGI环境变量和标准输入发送到FastCGI子进程PHP-CGI。
  4. FastCGI子进程完成处理后将标准输出和错误信息,从同一连接返回给Web服务器。当FastCGI子进程关闭连接时请求便处理完毕。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web服务器中)的下一个连接。在CGI模式中,PHP-CGI在此便退出了。

针对CGI中Web Server和CGI程序必须在同一个主机上的问题,FastCGI也进行了改进,允许FastCGI程序运行在不同的主机之上,而Web Server和FastCGI之间通过TCP连接进行通信,这种方式可以使Web Server和FastCGI程序独立配置和启动,也可以通过负载均衡提高系统的伸缩性和扩展性,当然两者仍然也可以同时部署在同一个主机上。此点可以参考nginx中配置的FastCGI程序的运行:

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
# 
# location ~ \.php$ {
#       root        html;
#       fastcgi_pass    127.0.0.1:9000;
#       fastcgi_index   index.php
#       fastcgi_param   SCRIPT_FILENAME /scripts$fastcgi_script_name;
#       include         fastcgi_params;
# }

3 Servlet

Servlet就是Java语言为了在Web中生成动态内容的定义的用于开发Web应用程序的基础技术标准,实现这个标准接口的类称为Servlet。它和CGI一样,都是Web低层通信的标准。

与CGI不同,CGI对每个Http请求生成一个CGI请求,然后将针对CGI请求生成一个单独的进程。Servlet运行在一个进程中,对于每个请求则会生成一个单独的线程,由这些独立的线程处理对应的http请求,Servlet执行完毕后不会销毁,而是驻留在内存中直到Servlet Container关闭,以便能随时处理http请求。

还有个不同点就是CGI程序是直接面向OS,而不像Servlet面向的是JVM虚拟机,所以Servlet的移植性更好。

一个Servlet应用程序经常包括一个或者多个Servlet,Servlet是运行在Servlet容器中的,它不能自动运行。

目前最新的Servlet标准应该是4.0。

Servlet在1999年所发布的J2SE1.2版本中首次面世,Servlet在JavaWEB的开发中发挥着重要的作用。JavaEE8对Servlet4.0进行了重要的更新。其中服务器推送是最主要的更新,如果要使用服务器推送的功能,则我们必须使用HTTP/2.0版本的协议。JavaEE8提供了对Servlet映射的运行时发现,在运行时我们可以获取Servlet的名称,Servlet的映射路径。JavaEE8简化了对Filter的开发。

3.1 Servlet有用的资源

  • Servlet 有用的资源
  • Java Servlet4.0
  • Java Servlet3.1
  • Servlet规范_一文概括所有

3.2 Servlet容器

在JavaWeb中,Web容器和Servlet容器的概念容易混淆。Servlet容器是Web服务器或应用程序服务器的一部分,它提供网络服务,通过这些服务发送请求和响应,解码基于MIME的请求,并格式化基于MIME的响应。Servlet容器还包含并管理Servlet的整个生命周期。

在这里插入图片描述

Servlet/JSP容器已经很成熟,并且被广泛的独立部署。Apache Tomcat和Jetty作为最流行的Servlet/JSP容器。

像Tomcat就是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,具有处理HTML页面的功能。另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式,这样就兼具了处理JSP的功能。

4 WSGI

WSGI,全称Python Web Server Gateway Interface,是Python语言中类似与CGI的标准。指定了Web服务器和PythonWeb应用或Web框架之间的标准接口,以提高Web应用在一系列Web服务器间的移植性。官方文档

通俗的讲,WSGI规范了一种简单的接口,解耦了Web服务器和PythonWeb应用程序,使得双边的开发者更加专注自身特性的开发。

WSGI是作为Web服务器与Web应用程序或应用框架之间的一种低级别的接口,以提升可移植Web应用开发的共同点。WSGI是基于现存的CGI标准而设计的。WSGI就是Python的CGI包装,相对于Fastcgi是PHP的CGI包装。

在这里插入图片描述

4.1 WSGI构成

WSGI将web组件分为三类: web服务器,web中间件,web应用程序, wsgi基本处理模式为 : WSGI Server -> (WSGI Middleware)* -> WSGI Application

WSGI协议其实是定义了一种server与application解耦的规范,即可以有多个实现WSGI server的服务器,也可以有多个实现WSGI application的框架,那么就可以选择任意的server和application组合实现自己的web应用。例如uWSGI和Gunicorn都是实现了WSGI server协议的服务器,Django,Flask是实现了WSGI application协议的web框架,可以根据项目实际情况搭配使用。

4.1.1 WSGI Server/gateway

WsgiServer可以理解为一个符合WSGI规范的WebServer,负责接收request请求和提供并发,封装一系列环境变量,按照WSGI规范调用注册的Wsgi Application并将request转发给application,最后将Application返回的response返回给客户端。

  • 接收 HTTP 请求,但是不关心 HTTP url, HTTP method 等
  • 为 environ 提供必要的参数,实现一个回调函数 start_response,并传给 callable object
  • 调用 callable object

以Python自带的wsgiref为例,wsgiref是按照WSGI规范实现的一个简单WSGI Server。

在这里插入图片描述

  • 服务器创建socket,监听端口,等待客户端连接。
  • 当有请求来时,服务器解析客户端信息放到环境变量environ中,并调用绑定的handler来处理请求。
  • handler解析这个http请求,将请求信息例如method,path等放到environ中。
  • wsgi handler再将一些服务器端信息也放到environ中,最后服务器信息,客户端信息,本次请求信息全部都保存到了环境变量environ中。
  • wsgi handler 调用注册的wsgi app,并将environ和回调函数传给wsgi app
  • wsgi app 将reponse header/status/body 回传给wsgi handler
  • 最终handler还是通过socket将response信息塞回给客户端。

直接使用支持 WSGI 框架的 wsgiref 库,编写一个样例:

# server/gateway side
if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server = make_server('0.0.0.0', 8080, application)
    server.serve_forever()

4.1.2 WSGI Application

WSGI Application接收由server转发的request,处理请求,并将处理结果返回给server。其实就是一个普通的callable对象,当有请求到来时,wsgi server会调用这个wsgi application。

Callable对象可以是以下三者之一:

  • function, method
  • class
  • instance with a __call__ method

Callable对象必须满足以下两个条件:

  • 接受两个参数:
    • 字典(environ),可以理解为环境变量,跟一次请求相关的所有信息都保存在了这个环境变量中,包括服务器信息,客户端信息,请求信息。
    • 回调函数(start_response),是一个callback函数,wsgi application通过调用`start_response·将response headers/Http status 返回给wsgi server。
  • 返回一个可迭代的值:wsgi app会return一个iterator对象 ,这个iterator就是response body。

基于callable function的application/framework样例:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['This is a python application!']

基于callable class的application/framework样例:

class ApplicationClass(object):
    def __init__(self, environ, start_response):
        self.environ = environ
        self.start_response = start_response
 
    def __iter__(self):
        self.start_response('200 OK', [('Content-type', 'text/plain')])
        yield "Hello world!n"

4.1.3 WSGI MiddleWare

application中可以包括多个栈式的中间件(middlewares),这些中间件需要同时实现server与application,因此可以在WSGI服务器与WSGI应用之间起调节作用:对服务器来说,中间件扮演应用程序,对应用程序来说,中间件扮演服务器。

Middleware处于server/gateway和application/framework之间,对server/gateway来说,它相当于 application/framework;对application/framework来说,它相当于server/gateway。每个middleware实现不同的功能,我们通常根据需求选择相应的middleware并组合起来,实现所需的功能。比如,可在middleware中实现以下功能:

  • 根据 url 把用户请求调度到不同的 application 中。
  • 负载均衡,转发用户请求
  • 预处理 XSL 等相关数据
  • 限制请求速率,设置白名单

本例实现了一个 IPBlacklist 的 middleware:

class IPBlacklistMiddleware(object):
    def __init__(self, app):
        self.app = app
 
    def __call__(self, environ, start_response):
        ip_addr = environ.get('HTTP_HOST').split(':')[0]
        if ip_addr not in ('127.0.0.1'):
            return forbidden(start_response)
 
        return self.app(environ, start_response)
 
def forbidden(start_response):
    start_response('403 Forbidden', [('Content-Type', 'text/plain')])
    return ['Forbidden']
 
def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['This is a python application!']
 
if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    application = IPBlacklistMiddleware(application)
    server = make_server('0.0.0.0', 8080, application)
    server.serve_forever()

参考资料

  • CGI是什么
  • 网关协议CGI、FastCGI、WSGI的区别
  • python WSGI框架详解
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMVC-01 Web基础介绍 的相关文章

  • [Linux容器]手把手搭建Stable-Diffusion容器

    最近的AI绘画可谓是特别火呀 这一期带大家使用容器搭建Stable Diffusion 1 首先我们安装Docker Debian sudo apt update amp amp sudo apt install y docker io R
  • [开源]一篇文章带你搭建自己的开源镜像站

    前言 在使用编程语言 开源软件 类UNIX系统时 我们常常会用到各类包管理器 Package Manager eg apt yum dnf pip pacman 而这些包管理器的源一般在各类网络镜像站 但在实际生产环境时 我们往往需要使用公
  • Kubernetes 集群 Worker 节点启停

    说明 有时候某一台服务器需要关机或者维护 xff0c 就需要停止上面的集群 保证其他节点上资源充足 停止节点 1 停止节点调度 span class token comment 等同于 span kubectl uncordon lt 节点
  • 利用栈简单实现回文串判断

    题目 编程实现程序 xff0c 相关功能包括 xff1a 输入一串字符 xff0c 使用单链表进行存储 xff0c 然后设计算法通过数据结构栈来帮助判断上述已知单链表中字符序列是否为回文 xff0c 如果是 xff0c 则输出 此链表中的字
  • WSL2运行stable-diffsuion容器

    首先安装wsl2 debian发行版 更新源安装docker sudo sed i 39 s deb debian org mirrors tuna Tsinghua edu cn 39 etc apt sources list amp a
  • Debian编译安装PHP8.1

    wget c https www php net distributions php 8 2 0 tar xz amp amp sudo sed i 39 s deb debian org mirrors tuna tsinghua edu
  • C语言之洛谷刷题之路---顺序结构

    一顺序结构 B2002 Hello World include lt stdio h gt int main printf 34 Hello World n 34 return 0 B2025 输出字符菱形 include lt stdio
  • C++ 百钱百鸡问题

    百钱百鸡问题 xff0c 又叫百钱买百鸡 xff0c 是一个著名的数学问题 xff0c 主要内容是 xff1a 用100元钱买100只鸡 xff0c 公鸡 母鸡 小鸡都要有 公鸡5元1只 xff1b 母鸡3元1只 xff1b 小鸡1元3只
  • 2022最新VMware虚拟机下载·Linux系统装配·镜像文件下载·联网使用一条龙--------希望可以帮到你们

    小新一枚 xff0c 请前辈赐教 xff0c 友友批评 xff0c 这是我小小的经验 xff0c 如有纰漏 xff0c 还望海涵 前期工作准备 xff1a 1 下好VMware安装包和镜像文件 xff08 Windows11建议vm17兼容
  • C++用怎么把一个字符串和一个字符数组拼接到一起

    第一种方法用到 xff1a copy函数 xff1a 字符串名 copy 数组名 xff0c 截取字符长度 xff0c 从第几个字符的前一位截取 xff1b xff08 因为数组arr第一个元素是arr 0 xff09 strlen函数 x
  • 虚拟机Linux中目录的命令(2)

    今天想和大家分享 xff0c 我们在远程登陆Linux中进行的一些命令 分为创建目录 xff0c 删除空目录 xff0c 创建文件 xff0c 删除目录和文件 xff0c 复制 xff0c 移动 名称功能参数是否有重命名功能mkdir 创建
  • C语言初阶小练习(7)——指针(1)

    以下所有题都是用指针实现的 xff0c 你可能会想 xff0c 这些题目不用指针也可以写出来 xff0c 干嘛要多次一举呢 xff1f 非也 xff0c 这些只是初级指针 xff0c 先把基础打好 xff0c 后来指针的用途可大着呢 xff
  • C语言初阶小练习(8)——指针(2)

    还是一些指针小练习 xff0c 接上次 C语言小练习 xff08 7 xff09 指针 xff08 1 xff09 一起来看看吧 目录 编写程序输入n个整数 xff0c 查找并删除重复的数字 xff0c 打印结果 查找其中出现了多少个连续数
  • 推荐几个代码自动生成器,神器!!!

    20个代码生成框架 老的代码生成器的地址 xff1a https www cnblogs com skyme archive 2011 12 22 2297592 html 以下是大家推荐的最近很火爆的代码生成器神器 如果有更好的希望大家多
  • linux 安装discuz出现“ mysqli_connect()不支持advice_mysqli_connect ”解决方法

    由于不了解php相关技术 xff0c 所以在安装discuz的时候遇到了很多麻烦 xff0c 记录下 首先 xff0c 我的环境是CentOS6 5 xff0c 在安装discuz的时候需要yum很多东西 yum install php p
  • Ubuntu 22.04 LTS下Miniconda安装+换源(踩坑向)

    1 安装Miniconda 我使用的是Python3 8 xff0c 如果需要去其他对应版本 xff0c 请查看 Miniconda conda documentation 下载 wget https repo anaconda com m
  • FreeBSD修改为国内源

    禁用原来的FreeBSD conf ee etc pkg FreeBSD conf 将 enabled yes 改为 enabled no 保存 ESC 然后 a gt a 即可 创建另外一个 FreeBSD conf mkdir p us
  • 关于51单片机的中断

    1 中断的要求 1 中断源有中断请求 Ask for instructions of the CPU interrupt request source called interrupt source 2 此中断源的中断允许位为1 The i
  • 华为机试_HJ5 进制转换【简单】

    描述 写出一个程序 xff0c 接受一个十六进制的数 xff0c 输出该数值的十进制表示 数据范围 xff1a 保证结果在 1 le n le 2 31 1 1 n 231 1 输入描述 xff1a 输入一个十六进制的数值字符串 输出描述
  • bootstrap实现 — 个人简介

    实现 xff1a bootstrap 效果图 xff1a 源码 xff1a lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt titl

随机推荐

  • 计蒜客--T1079--打表+控制输出

    假设有 N 盏灯 xff08 NN为不大于 5000 的正整数 xff09 xff0c 从 1 到 N 按顺序依次编号 xff0c 初始时全部处于开启状态 xff1b 有 M 个人 xff08 M 为不大于 N的正整数 xff09 也从 1
  • Authentication plugin ‘caching_sha2_password‘ 服务端也无法连接问题彻底解决

    在网上搜索了很多的帖子 xff0c 发现描述的都是外部客户端无法登录到mysql上 xff0c 登录上服务器以后连接更改配置的方式 xff0c 但是 xff01 xff01 xff01 xff01 xff01 我现在是服务器连接也报错啊啊啊
  • Hexo分类及标签显示

    Hexo根目录配置 config yml category map Blogs categories Blogs Tech categories Tech Tools categories Tools Other categories Ot
  • IDEA查看历史记录

    方法一 文件内 Ctrl 43 右键 Local History Show History xff0c 显示当前文件的本地修改历史 方法二 一 xff1a 在文件内 xff0c 按 Ctrl 43 Shift 43 A 弹出全部搜索对话框
  • SpringBoot-JPA整合ShardingShpere自定义分布式主键

    分布式主键简介 在分布式环境下 xff0c 由于分库分表导致数据水平拆分后无法使用单表自增主键 xff0c 因此我们需要一种全局唯一id生成策略作为分布式主键 当前有如下解决方案 UUID xff08 Universally Unique
  • Gitlab的安装与配置

    安装开始时 xff0c 需确认服务器最小配置是2核4G xff0c 因为gitlab软件比较大 1 配置yum源 xff1a vim etc yum repos d gitlab repo gitlab name 61 gitlab ce
  • Error creating bean with name ‘org.springframework.aop.aspectj.AspectJPointcutAdvisor#0

    问题 xff1a nested exception is org springframework beans factory BeanCreationException Error creating bean with name 39 or
  • Vue前端项目开发页面(二)

    前端界面开发 开发工具版本 64 vue cli 4 5 13 新建Login vue登陆页 1 在 vue exemples 项目 xff0c 选中components目录右键 New Vue Component xff0c 名称为 Lo
  • SpringBoot整合WebSocket

    概述 HTTP 协议是一种无状态的 无连接的 单向的应用层协议 它采用了请求 响应模型 通信请求只能由客户端发起 xff0c 服务端对请求做出应答处理 WebSocket和HTTP一样 xff0c 都是一种网络通信协议 比起HTTP只能由客
  • SpringBoot整合MybatisPlus使用IPage实现分页

    概述 MybatisPlus 提供了分页的功能 IPage内部原理是基于拦截器 xff0c 但是这个拦截的是方法以及方法中的参数 xff0c 这个也会判断是否是查询操作 如果是查询操作 xff0c 才会进入分页的处理逻辑 进入分页逻辑处理后
  • SpringBoot统一异常处理

    概述 SpringBoot 提供了 64 ControllerAdvice 64 RestControllerAdvice 注解可以实现统一异常处理 xff0c 只需要在定义异常类加上以上注解即可 自定义异常处理 定义统一异常处理 span
  • 萌新学习算法——并查集基础

    并查集 在算法设计中 xff0c 将一个集合和另外一个集合合并时 xff0c 就会用到并查集 假如不用并查集 xff0c 你可能会用到集合和列表来实现 xff0c 这样会使代码看起来很复杂 xff0c 而且执行效率不高 xff0c 下面用洛
  • linux中断及其底半部-s5p6818开发平台

    中断分为两个部分 xff1a 中断顶部 xff08 top half xff09 和中断底半部 xff08 bootom half xff09 一 中断顶部 xff08 top half xff09 中断上半部需要处理一下三种情况 xff1
  • Windows如何查看.db数据库文件

    从android应用导出的 db文件 xff0c 想在Windows电脑端看 xff0c 可以用SQLite Expert Professional这个软件查看 xff0c 网上说用FireFox的插件sqlite manager xff0
  • Ubuntu工具-01 UEX

    UltraEdit是Windows旗下一款流行的老牌文本 HEX编辑器 xff08 非开源 xff09 UltraEdit正被移植到Linux平台 该移植名为UEX xff0c 意即UltraEdit for Linux UltraEdit
  • Ubuntu工具-2 OBS Studio

    文章目录 1 下载并安装1 1 Flathub安装1 2 Snap安装1 3 PPA源方式安装1 3 1 检查OpenGL版本 xff0c 其版本必须高于 96 3 3 96 1 3 2 安装虚拟摄像机驱动1 3 3 安装ffmpeg库1
  • Docker build创建指定容器镜像

    Docker build xff1a Build an image from a Dockerfile 按照Dockerfile文件所定义内容创建临时性容器 xff0c 把Docker中所定义的每行命令在临时容器中执行 xff0c 然后生成
  • Ubuntu工具-03 VLC

    文章目录 1 安装VLC Media Player的方法1 1 apt安装1 2 snap安装 xff08 未测试 xff09 2 启动VLC Media Player并设置为默认媒体播放器 VLC Media Player xff08 V
  • MySQL笔记-07 常用函数

    文章目录 1 数学函数1 1 ABS1 2 CEIL和CEILIN1 3 FLOOR1 4 MOD1 5 ROUND1 6 TRUNCATE 2 字符串函数2 1 CONCAT2 2 CONCAT WS2 3 INSERT2 4 LOWER
  • SpringMVC-01 Web基础介绍

    文章目录 1 CGI1 1 CGI原理1 2 输入 出1 3 环境变量1 3 1 与请求相关的环境变量1 3 2 与服务器相关的环境变量1 3 3 与客户端相关的环境变量1 3 4 详细说明1 3 4 1 REQUEST METHOD 1