从0开始,手搓Tomcat
一、什么是Tomcat
Tomcat 是一款开源的、轻量级的 Web 服务器,它不仅能够提供 HTTP 服务,还能够运行 Java Servlet 和 JavaServer Pages(JSP)。对于许多开发者来说,理解 Tomcat 的目录结构以及如何在该结构中组织应用,往往是入门的第一步。
1、Tomcat目录结构
Tomcat 的目录结构相对简单,但每个目录和文件都有其明确的用途。
1. bin 目录
bin 目录包含启动和停止 Tomcat 所需的脚本。它的内容包括:
startup.sh/startup.bat:启动 Tomcat。
shutdown.sh/shutdown.bat:停止 Tomcat。
catalina.sh/catalina.bat:Tomcat 启动时的核心脚本,包含了一些启动参数的设置。
setenv.sh/setenv.bat:用于设置 Tomcat 环境变量,通常用于配置 Java 堆大小、日志设置等。
2. conf 目录
conf 目录包含 Tomcat 的核心配置文件,这些文件直接影响 Tomcat 的行为。常见的配置文件有:
server.xml:Tomcat 的主要配置文件,定义了服务器的端口、连接器、虚拟主机等。
web.xml:Web 应用的默认部署描述符。
context.xml:为每个 Web 应用提供额外的配置。
3. lib 目录
lib 目录存放 Tomcat 运行时所需要的 Java 类库和 JAR 包,包括:
servlet-api.jar:Java Servlet API 的实现。
jsp-api.jar:Java Server Pages(JSP)API 的实现。
其他第三方库和 Tomcat 特有的库文件。
4. logs 目录
logs 目录用于存储 Tomcat 启动、运行过程中的日志文件。常见的日志文件有:
catalina.out:Tomcat 启动和运行时的主要日志文件。
localhost_access_log.*.txt:记录每个请求的访问日志。
5. webapps 目录
webapps 目录是 Tomcat 的应用目录,所有部署的 Web 应用都应该放在此目录下。每个应用通常以一个文件夹的形式存在,目录中包含了应用的 WEB-INF 和 META-INF 等文件夹。
6. work 目录
work 目录用于存放 Tomcat 编译 JSP 文件后的中间文件。每当 Tomcat 运行一个 JSP 文件时,都会将其编译成 Java 类文件并存放在这个目录中。
7. temp 目录
temp 目录是 Tomcat 用来存放临时文件的地方。例如,Tomcat 会将文件上传的内容存放在该目录中,处理过程中生成的临时数据也会保存在这里。
2、Tomcat的工作目录
在apache的Tomcat中,工作目录可以简化成上图,即在webapps中进行资源的访问。资源的访问可以简单的理解为对网页的操作。
二、Tomcat工作原理简介
1、Tomcat中Servlet的生命周期
在一个实现具体操作的Servlet类中,具有如下图的继承关系
javax.servlet.Servlet 是所有 Servlet 的基本接口。任何自定义的 Servlet 都必须实现这个接口或者继承一个实现了它的类。该接口定义了 Servlet 的生命周期方法,例如 init(), service(), 和 destroy(),这些方法体现了Servlet的生命周期
init(..):当servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来
service(...):每当请求Servlet时,Servlet容器就会调用这个方法service(...)
destroy(...):当要销毁Servlet时,Servlet容器就会调用这个方法
getservletInfo(...):这个方法会返回Servlet的一段描述,可以返回一段字符串。
getServletconfig(...):这个方法会返回由Servlet容器传给init()方法的Servletconfig对象。
javax.servlet.GenericServlet 是 Servlet 接口的一个抽象实现类。它实现了 Servlet 接口,但提供了空实现的 service() 方法。通常,自定义的 Servlet 会继承 GenericServlet,并重写 service() 方法来处理客户端请求。
javax.servlet.http.HttpServlet 是处理 HTTP 请求的抽象类,继承自 GenericServlet。大多数 Web 应用中的 Servlet 会继承 HttpServlet,因为它提供了简化的 HTTP 请求处理方法,如 doGet(), doPost(), doPut() 和 doDelete(),这些方法可以根据请求类型进行重写。同时 HttpServlet 中重写了service() 方法,对于不同的请求进行判断并划分到不同的操作中,将其拆分成doGet()方法和doPost()等七种方法,其目的是为了更好的匹配http请求。
2、Tomcat对待资源
Tomcat将资源分为动态资源和静态资源。
1.静态资源
指内容在服务器上不会发生变化的资源,通常这些资源由服务器直接提供给客户端,不需要任何动态处理。常见的静态资源有:
- HTML 文件:静态的网页内容,直接通过浏览器访问即可展示。
- CSS 文件:样式表文件,用于定义网页的外观。
- JavaScript 文件:脚本文件,用于网页的交互行为。
- 图片文件:如 PNG、JPEG、GIF、SVG 等图片文件。
- 字体文件:例如 .woff, .ttf 等字体文件。
- 视频文件:如 .mp4, .avi 等文件。
Tomcat 处理静态资源的方式:
Tomcat 会直接通过文件系统(例如 /webapps/ROOT 目录)读取静态资源,然后返回给客户端。静态资源通常会被配置在 Web 应用的 webapps 目录下。
默认情况下,Tomcat 会直接将这些资源返回给客户端,除非配置了 URL 映射或者过滤器,否则不涉及任何额外的处理逻辑。
2.动态资源
动态资源 是指在客户端请求时,服务器需要根据请求的不同,动态生成或者处理后才返回的内容。这类资源的内容是可变的,通常与用户的输入、数据库等外部数据源有关。动态资源的常见形式包括:
- Servlet:通过 Java 编写的后端代码,接收客户端请求并生成响应内容。
- JSP (JavaServer Pages):与 Servlet 类似,但通过模板方式生成 HTML 内容。JSP 是动态生成 HTML 页面的一种方法。
- RESTful API:通常由 Servlet 或其他 Java 后端框架实现,用于为前端应用提供数据接口。
- WebSocket:允许在客户端与服务器之间进行双向通信的技术。
Tomcat 处理动态资源的方式:
Tomcat 会将动态请求交给相应的 Servlet 或 JSP 进行处理。Servlet/JSP 会根据请求生成动态内容。请求 URL 会映射到特定的 Servlet 或 JSP,Tomcat 通过 web.xml 或注解来配置这些映射。
动态资源通常通过 Servlet 或 JSP 来生成 HTTP 响应,这些响应可以是 HTML、JSON、XML 等格式,具体取决于请求和后端代码的逻辑。
3.两种资源的区别
资源类型 | 需要服务器处理 | 变化性 | 典型示例 |
静态资源 | 无 | 不变 | HTML、CSS、JavaScript、图片、视频等 |
动态资源 | 需要处理 | 可变 | Servlet、JSP、REST API、WebSocket 等 |
静态资源 直接由 Tomcat 提供,客户端请求时无需任何额外的动态处理。
动态资源 需要通过 Servlet 或 JSP 等方式在服务器端进行处理,然后生成响应内容返回给客户端。
3、Tomcat的核心——Servlet容器
Tomcat的核心是servlet容器,本质是一个hashmap,Key值是servlet的访问路径,Value值是一般为servlet对象。在启动tomcat时,动态资源加载到servlet容器中
http请求打到servlet容器中,进行key值对比,如果访问动态资源,则调用servlet对象
需要注意的一点是,在Tomcat启动时,就需要把动态资源加载到Servlet容器中。
4、Tomcat处理http请求
Tomcat 生成一个socket对象,用于接收和处理http请求,从请求中解析出请求类型和需要的资源,交给Servlet容器中的Servlet对象去处理
三、简易Tomcat实现
1、目录结构
这样设计为区分不同功能的Java文件。
需要指出的是,这里创建项目不是普通的Java项目,需要选择Maven项目,只需设置项目名称即可,其他默认即可,项目名不要有中文。
2、实现继承关系
Servlet接口
package com.tom2.servlet;import com.tom2.servlet.Re.HttpRequest;
import com.tom2.servlet.Re.HttpResponse;public interface Servlet {public abstract void init();public abstract void destory();public abstract void service(HttpRequest request, HttpResponse response) throws Exception;
}
GenericServlet抽象类
package com.tom2.servlet;import com.tom2.servlet.Re.HttpRequest;
import com.tom2.servlet.Re.HttpResponse;public abstract class GenericServlet implements Servlet{@Overridepublic void init() {System.out.println("genservlet 的init");}@Overridepublic void destory() {System.out.println("genservlet 的destory");}
}
HttpServlet 抽象类
package com.tom2.servlet;import com.tom2.servlet.Re.HttpRequest;
import com.tom2.servlet.Re.HttpResponse;public abstract class HttpServlet extends GenericServlet{@Overridepublic void service(HttpRequest request, HttpResponse response) throws Exception {if(request.getMethod().equals("GET")){doGet(request,response);}else if(request.getMethod().equals("POST")){doPost(request,response);}}public abstract void doGet(HttpRequest request, HttpResponse response) throws Exception;public abstract void doPost(HttpRequest request, HttpResponse response) throws Exception;}
HttpRequest 和 HttpResponse
package com.tom2.servlet.Re;public class HttpRequest {private String path;private String method;public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}@Overridepublic String toString() {return "HttpRequest{" +"path='" + path + '\'' +", method='" + method + '\'' +'}';}
}package com.tom2.servlet.Re;import java.io.IOException;
import java.io.OutputStream;public class HttpResponse {private OutputStream outputStream;public HttpResponse(OutputStream outputStream){this.outputStream=outputStream;}public void writeResponse(String context) throws IOException {outputStream.write(context.getBytes());}}
3、工具类
SearchClassUtil :利用反射进行类信息的查找。扫描指定的 Java 包目录,查找所有 .class 文件,并提取每个 .class 文件的全类名,将这些类名存储在一个 List 列表中。
package com.tom2.Util;import java.io.File;
import java.util.ArrayList;
import java.util.List;/*** 扫描 com.qcby.webapps 目录下的 Java 文件并获取每个类的全名*/
public class SearchClassUtil {public static List<String> classPaths = new ArrayList<String>();public static List<String> searchClass() {// 需要扫描的包名String basePack = "com.tom2.webapps";// 将包名转换为路径格式String classPath = SearchClassUtil.class.getClassLoader().getResource("").getPath();basePack = basePack.replace(".", File.separator);if(classPath.startsWith("file:")){classPath.substring(5);}String searchPath = classPath + basePack;// 确保路径在开发环境和打包后的环境下都能正确处理File searchDir = new File(searchPath);if (!searchDir.exists()) {// 如果路径不存在,尝试扫描 target/classes 目录searchPath = "target/classes"+File.separator+basePack;searchDir = new File(searchPath);}// 调用 doPath 方法递归扫描文件doPath(searchDir, classPath);// 返回扫描到的类路径列表return classPaths;}/*** 递归处理文件,找到 .class 文件并将其全类名添加到 classPaths 列表中*/private static void doPath(File file, String classpath) {if (file.isDirectory()) {// 如果是目录,递归处理子目录File[] files = file.listFiles();if (files != null) {for (File f1 : files) {doPath(f1, classpath);}}} else {// 如果是 .class 文件,提取类名if (file.getName().endsWith(".class")) {// 修正路径替换:不使用 replaceFirst,而直接使用 replaceString path = file.getPath().replace(classpath, "") // 直接使用 classpath,不再替换 "/" 为 File.separator.replace(File.separator, ".").replace(".class", "");if(path.startsWith("targetes.")){path = path.substring("targetes.".length());}// 将类名添加到 classPaths 列表classPaths.add(path);}}}public static void main(String[] args) {List<String> classes = SearchClassUtil.searchClass();for (String s : classes) {System.out.println(s);}}
}
WebServlet:注解
package com.tom2.Util;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WebServlet {String urlMapping() default "";
}
ResponseUtil
package com.tom2.Util;public class ResponseUtil {public static final String responseHeader200 = "HTTP/1.1 200 \r\n"+"Content-Type:text/html; charset=utf-8 \r\n"+"\r\n";public static String getResponseHeader404(){return "HTTP/1.1 404 \r\n"+"Content-Type:text/html; charset=utf-8 \r\n"+"\r\n" + "404";}public static String getResponseHeader200(String context){return "HTTP/1.1 200 \r\n"+"Content-Type:text/html; charset=utf-8 \r\n"+"\r\n" + context;}
}
5、模拟Servlet容器
SearchServlet
package com.tom2;import com.tom2.Util.SearchClassUtil;
import com.tom2.Util.WebServlet;
import com.tom2.servlet.HttpServlet;
import java.util.*;public class SearchServlet {public static Map<String, HttpServlet> servletmap = new HashMap<>();static {List<String> classpath = SearchClassUtil.searchClass();for(String path:classpath){System.out.println(path);}for(String path:classpath){try{Class clazz = Class.forName(path);WebServlet webServlet = (WebServlet) clazz.getDeclaredAnnotation(WebServlet.class);HttpServlet httpServlet = (HttpServlet) clazz.getDeclaredConstructor().newInstance();servletmap.put(webServlet.urlMapping(),httpServlet);}catch(Exception e){e.printStackTrace();}}}}
6、动态资源
Login
package com.tom2.webapps.myweb;import com.tom2.Util.WebServlet;
import com.tom2.servlet.HttpServlet;
import com.tom2.servlet.Re.HttpRequest;
import com.tom2.servlet.Re.HttpResponse;
@WebServlet(urlMapping = "/login")
public class Login extends HttpServlet {@Overridepublic void doGet(HttpRequest request, HttpResponse response) throws Exception {System.out.println("俺是login的doGet");}@Overridepublic void doPost(HttpRequest request, HttpResponse response) throws Exception {}
}
Show
package com.tom2.webapps.myweb;
import com.tom2.Util.ResponseUtil;
import com.tom2.Util.WebServlet;
import com.tom2.servlet.HttpServlet;
import com.tom2.servlet.Re.HttpRequest;
import com.tom2.servlet.Re.HttpResponse;
@WebServlet(urlMapping = "/show")
public class Show extends HttpServlet {@Overridepublic void doGet(HttpRequest request, HttpResponse response) throws Exception {response.writeResponse(ResponseUtil.getResponseHeader200("俺是Show的doGet"));}@Overridepublic void doPost(HttpRequest request, HttpResponse response) throws Exception {}
}
7、主方法
MyTomcat
package com.tom2;import com.tom2.servlet.HttpServlet;
import com.tom2.servlet.Re.HttpRequest;
import com.tom2.servlet.Re.HttpResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class MyTomcat {private static HttpRequest httpRequest = new HttpRequest();public static void main(String[] args) throws Exception {ServerSocket serverSocket = new ServerSocket(8080);while(true){Socket socket = serverSocket.accept();InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream();HttpResponse httpResponse = new HttpResponse(outputStream);int len = 0;while(len==0){len = inputStream.available();}byte[] bytes = new byte[len];inputStream.read(bytes);String context = new String(bytes);System.out.println(context);if(context.equals("")){System.out.println("空请求");}else{String line1 = context.split("\\n")[0];String method = line1.split("\\s")[0];String path = line1.split("\\s")[1];httpRequest.setMethod(method);httpRequest.setPath(path);}System.out.println(SearchServlet.servletmap.containsKey(httpRequest.getPath()));if(SearchServlet.servletmap.containsKey(httpRequest.getPath())){HttpServlet httpServlet = SearchServlet.servletmap.get(httpRequest.getPath());httpServlet.service(httpRequest,httpResponse);}}}
}
8、模拟效果
在浏览器地址栏中输入:localhost:8080/login
在浏览器地址栏中输入:localhost:8080/show
相关文章:
从0开始,手搓Tomcat
一、什么是Tomcat Tomcat 是一款开源的、轻量级的 Web 服务器,它不仅能够提供 HTTP 服务,还能够运行 Java Servlet 和 JavaServer Pages(JSP)。对于许多开发者来说,理解 Tomcat 的目录结构以及如何在该结构中组织应用…...
数列分块入门2
题目描述 给出一个长为 n n n 的数列,以及 n n n 个操作,操作涉及区间加法,询问区间内小于某个值 x x x 的元素个数。 输入格式 第一行输入一个数字 n n n。 第二行输入 n n n 个数字,第 i i i 个数字为 a i a_i ai&a…...
【ThreeJS Basics 06】Camera
文章目录 Camera 相机PerspectiveCamera 透视相机正交相机用鼠标控制相机大幅度转动(可以看到后面) 控制组件FlyControls 飞行组件控制FirstPersonControls 第一人称控制PointerLockControls 指针锁定控制OrbitControls 轨道控制TrackballControls 轨迹球…...
postman接口请求中的 Raw是什么
前言 在现代的网络开发中,API 的使用已经成为数据交换的核心方式之一。然而,在与 API 打交道时,关于如何发送请求体(body)内容类型的问题常常困扰着开发者们,尤其是“raw”和“json”这两个术语之间的区别…...
docker1
前言 技术架构 单机架构 应用数据分离架构 应用服务集群架构 读写分离/主从分离架构 写入主的时候,要同步Mysql从的数据才可以 冷热分离架构 写的时候要写入主和缓存数据库 读的时候先去缓存看有没有,没有的话就去从数据库读数据 主要就是看这个数据是…...
RocketMQ延迟消息深度解析:原理、实践与性能调优
RocketMQ延迟消息深度解析:原理、实践与性能调优 编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793 DeepSeek使用技巧pdf资料分享:https://blog.csdn.net/weixin_47763579/article/details/145884039 一、…...
RabbitMQ 高级特性解析:RabbitMQ 消息可靠性保障 (上)
RabbitMQ 核心功能 RabbitMQ 高级特性解析:RabbitMQ 消息可靠性保障 (上)-CSDN博客 RabbitMQ 高级特性:从 TTL 到消息分发的全面解析 (下)-CSDN博客 前言 最近再看 RabbitMQ,看了看自己之前写…...
大白话JavaScript实现一个函数,将数组中的元素进行去重
大白话JavaScript实现一个函数,将数组中的元素进行去重 答题思路 要实现数组元素去重的函数,核心思路是遍历数组,然后判断每个元素是否已经在新数组里存在,如果不存在就添加进去,存在则跳过。下面会介绍几种不同的实…...
PQL查询和监控各类中间件
1 prometheus的PQL查询 1.1 Metrics数据介绍 prometheus监控中采集过来的数据统一称为Metrics数据,其并不是代表具体的数据格式,而是一种统计度量计算单位当需要为某个系统或者某个服务做监控时,就需要使用到 metrics prometheus支持的met…...
uni_app实现下拉刷新
1. 在页面配置中启用下拉刷新 首先,你需要在页面的 pages.json 文件中启用下拉刷新功能。 {"pages": [{"path": "pages/index/index","style": {"navigationBarTitleText": "首页","enablePull…...
C#类型转换基本概念
一、基本定义 C# 类型转换是将数据从一种类型转换为另一种类型的过程,分为 隐式转换 和 显式转换 两类。 强类型语言特性:C# 要求变量类型在编译时确定,类型转换需满足兼容性或显式规则。目的:处理不同数据类…...
【学习笔记】【DeepSeek AI 医生】2-2 AI家庭医生课程内容介绍
【DeepSeek AI 医生】2-4 项目详细分析及DeepSeek适用场景 一、Ollama部署二、可视化UI三、构建项目环境四、搭建项目架构五、Spring Al六、SSE服务端推送事件七、数据持久化八、线上部署 一、Ollama部署 Mac部署windows 部署ollama脚本、常用命令DeepSeek 提示词、角色、适用…...
DeepSeek使用教程--让DeepSeek生成精准题库
想让DeepSeek出好题,关键在于提示词的设计。总结了一个基本模板: 请帮我生成一套关于[学科/知识点]的题目,包括[题型],难度为[简单/中等/困难],适合[年级/学习阶段]的学生,总共[数量]道题。每道题请提供详细…...
数学之约数个数定理-阶乘约数
题目: 定义阶乘 n!123⋅⋅⋅n。 请问 100!(100的阶乘)有多少个正约数。 们需要计算 100! 的正约数的个数。阶乘 100! 的定义是: 100!123⋯100 直接计算 100!的值是不现实的,因为它是一个非常大的数。因此…...
C语言学习笔记-进阶(7)字符串函数3
1. strstr的使用和模拟实现 char * strstr ( const char * str1, const char * str2); Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1. (函数返回字符串str2在字符串str1中第⼀次出现的位置&#x…...
快乐数 力扣202
一、题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&…...
Cpu100%问题(包括-线上docker服务以及Arthas方式进行处理)
🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…...
近三年图像超分辨率研究进展综述(轻量化方向)
一、图像超分辨率技术的近三年核心进展 1. 轻量化网络设计突破 轻量化模型是端侧部署的关键,近三年研究主要围绕参数压缩与计算效率提升展开: 11卷积与通道优化:SCNet提出全11卷积架构,通过逐点卷积替代传统33卷积,在保持重建质量的同时将模型参数减少60%以上。该设计通…...
成都亚恒云知教育咨询公司:绘画的风格如何学习与确定?
宝子们,好久不见! 最近收到好多同学发给我们成都亚恒云知教育咨询有限公司创作的作品,同时也收到了有很多乖乖的询问:关于绘画,老师我没有属于自己的风格,怎么才能画出属于自己的风格的作品啊,…...
数据结构篇——串(String)
一、引入 在计算机中的处理的数据内容大致可分为以整形、浮点型等的数值处理和字符、字符串等的非数值处理。 今天我们主要学习的就是字符串数据。本章主要围绕“串的定义、串的类型、串的结构及其运算”来进行串介绍与学习。 二、串的定义 2.1、串的基本定义 串(s…...
Qwen架构与Llama架构的核心区别
我们在讨论Deepseek不同版本之间的区别时了解到,DeepSeek-R1的蒸馏模型分为Qwen和Llama两个系列,包括Qwen系列的0.5B、1.5B、3B、7B、14B、32B、72B和Llama系列的8B、70B。Qwen系列以阿里通义千问(Qwen)为基础模型架构(具体是Qwen-2.5),Llama系列以Meta的Llama为基础模型…...
uniapp或者vue 使用serialport
参考https://blog.csdn.net/ykee126/article/details/90440499 版本是第一位:否则容易编译失败 node 版本 18.14.0 npm 版本 9.3.1 electron 版本 30.0.8 electron-rebuild 版本 3.2.9 serialport 版本 10.0.0 需要python环境 main.js // Modules to control app…...
Linux和gcc/g++常用命令总结
目录 Linux命令总结 文件操作相关命令 ls cd pwd cp mv rm cat mkdir rmdir touch 文本处理操作命令 grep awk sed 进程管理操作相关命令 ps top htop kill pkill killall chmod chown 网络操作相关命令 ping ifconfig netstat ss lsof curl …...
Vue3路由组件和一般组件 切换路由时组件挂载和卸载 路由的工作模式
路由组件和一般组件 路由组件 一般放到pages或view目录 一般组件 一般放到component目录 切换路由 切换路由时,组件和执行挂载和卸载 路由的工作模式 Hash模式 缺点 1.不美观,路径带#号 优点 1.兼容性好 一般适用于管理系统 History模式 缺点…...
MySQL如何给其他账号分配权限?
目录 基础权限分配流程 权限级别对照表 安全事项 MySQL数据库使用root账号为test账号分配权限的标准操作流程及注意事项: 基础权限分配 1、root用户登录, 输入root密码后进入MySQL命令行环境 mysql -u root -p2、用户存在性校验 SELECT user,host FROM …...
记录一些面试遇到的问题
重载和重写的区别 重载是overload,覆盖是override 重载属于编译时多态,覆盖属于运行时多态 运行时多态和编译时多态 运行时多态指的是在运行的时候才知道要调用哪一个函数,编译时多态是指在编译的时候就知道调用哪一个函数。 运行时多态…...
Windows 系统 Docker Desktop 入门教程:从零开始掌握容器化技术
文章目录 前言一、Docker 简介二、Docker Desktop 安装2.1 系统要求2.2 安装步骤 三、Docker 基本概念四、Docker 常用命令五、实战:运行你的第一个容器5.1 拉取并运行 Nginx 容器5.2 查看容器日志5.3 停止并删除容器 六、总结 前言 随着云计算和微服务架构的普及&…...
量子计算测试挑战:软件测试将如何迎接新纪元?
引言 在计算机技术的飞速发展中,量子计算(Quantum Computing)正成为下一个颠覆性的科技热点。随着谷歌、IBM、微软等科技巨头纷纷投入巨资研究量子计算,其应用场景正逐步扩展,从优化计算到密码安全,再到人工智能和材料科学。然而…...
Matlab实现车牌识别
车牌识别技术作为现代智能交通系统、安防监控以及诸多车辆管理应用场景中的关键环节,正发挥着日益重要的作用,它能够自动、快速且精准地从车辆图像或视频流中提取车牌信息,实现车辆身份的智能化识别。 技术原理 车牌识别主要依托于图像处理、…...
Autosar 诊断开发-CAN到CANFD的更改-基于ETAS软件
文章目录 前言CanIf配置CanTp配置EcuC配置生成代码差异总结 前言 从CAN切换到CANFD,如果不想重新进行cfggen的话,手动更改配置或许会更快一些,本文介绍诊断报文从CAN变为CANFD后,BSW模块中的更改。 注:本文不介绍MCAL…...
八、排序算法
一些简单的排序算法 8.1 冒泡排序 void Bubble_sort(int a[] , int len){int i,j,flag,tmp;for(i=0 ; i < len-1 ; i++){flag = 1;for(j=0 ; j < len-1-i ; j++){if(a[j] > a[j+1]){tmp = a[j];a[j] = a[j+1];a[j+1] = tmp;flag = 0;}}if(flag == 1){break;}}…...
TON基金会确认冠名赞助2025香港Web3嘉年华,并将于4月8日重磅呈现“TON生态日”
近日,由万向区块链实验室与HashKey Group联合推出的Web3年度盛典——2025香港Web3嘉年华正式宣布,TON基金会确认成为本届嘉年华的冠名赞助商,并将于4月8日在主会场特别举办“TON生态日”专题Side Event,集中展现TON生态的最新技术…...
《A++ 敏捷开发》- 18 软件需求
需求并不是关于需求 (Requirements are not really about requirements) 大家去公共图书馆寄存物品,以前都是扫二维码开箱,有些图书馆升级了使用指纹识别。 “是否新方法比以前好?”我问年轻的开发人员。 “当然用指纹识别好。新技术&#x…...
RAG技术深度解析:从基础Agent到复杂推理Deep Search的架构实践
重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…...
智谱AI-FunctionCall
智谱AI-FunctionCall 编写FuncationCall大模型的函数调用,先直观的感受一下的感受下FunctionCall的魅力 文章目录 智谱AI-FunctionCall[toc]1-参考网址2-思路整理3-代码拆件1-[非核心]两个业务函数2-[非核心]业务函数的JsonSchema定义3-[核心]FunctionCall的调用1-打…...
[HTTP协议]应用层协议HTTP从入门到深刻理解并落地部署自己的云服务(2)实操部署
标题:[HTTP协议]应用层协议HTTP从入门到深刻理解并落地部署自己的云服务(2)实操部署 水墨不写bug 文章目录 一、无法拷贝类(class uncopyable)的设计解释:重要思想:使用示例 二、锁的RAII设计解释重要考虑使用示例 三、基于RAII模式和互斥锁…...
【玩转MySQL数据字典】MySQL数据字典与常用操作指令
MySQL数据字典简介与常用操作指令 一、数据字典简介 数据字典是MySQL 5.7中用于存储数据库对象元数据的系统表。在MySQL的早期版本中,元数据存储在.frm文件及其他文件里。这种存储方式存在诸多弊端,例如元数据不一致问题,不同文件间元数据的…...
C语言 —— 愿此世如黄金般辉煌 - 进制转换与操作符详解
目录 1. 操作符的分类 2. ⼆进制和进制转换 2.1 2进制转10进制 2.2 10进制转2进制 2.3 2进制转8进制 2.4 2进制转16进制 3. 原码、反码、补码 4. 移位操作符 4.1 左移操作符 4.2 右移操作符 5. 位操作符:&、|、^、~ 5.1 & 按位与 5.2 | 按位或 …...
基于粒子群算法的配电网重构
一、配电网重构原理 定义: 配电网重构是指在满足运行约束的前提下,通过改变开关状态优化配电网性能,提高系统的经济效益和运行效率。 拓扑约束: 配电网必须保持径向拓扑,避免环网或孤岛。采用算法控制开关状态的选择&…...
【云岚到家】-实战问题(上)
【云岚到家】-实战问题(上) 基础架构项目涉及那些角色云岚的业务流程?云岚家政包括那些模块项目采用什么架构如何开发一个接口?RESTful风格的去定义一个接口如何开发一个接口的service方法接口的异常处理怎么实现的?Sp…...
005-获取内存占用率
获取内存占用率 windows平台 在Windows环境下使用C获取内存占用率,可以通过以下两种方式实现,分别针对系统整体和特定进程的内存监控: 一、获取系统整体内存占用率 核心函数:GlobalMemoryStatusEx 步骤: 定义MEMOR…...
python从入门到精通(二十二):python文件操作之Excel全攻略(基于pandas)
Python处理表格数据 1.表格的基础知识1.1 xls与xlsx格式详解1.2 表格内部结构的认识 2.表格的基础操作2.1 认识表格的基本库2.1.1 csv内置的标准库2.1.2 xlrd 和 xlwt2.1.3 openpyxl2.1.4 pandas 2.2 安装和环境配置2.3 xlrd 和 xlwt2.3.1 库的说明2.3.2 安装xlrd库2.3.3 导入模…...
html常用标签
文章说明 本文旨在总结 HTML 中常见的标签,并提供简洁的解释,方便大家快速查找和复习。我们假设读者已经具备一定的 HTML 基础知识。本文将持续更新和完善,欢迎大家参与续写和补充 一、 HTML 标签 整个网页从 <html> 开始到 </html…...
ROS分布式部署通信
目录 一、概念 二、设置 ROS 分布式网络 1. 环境要求 2. 主机(Master)设置 3. 从机(节点设备)设置 4. 测试是否正常通信 三、进阶启动多从机节点(launch)。 一、概念 ROS 分布式通信用于在多台计算机…...
.Net 6 上传文件接口 文件大小报错整体配置
/// <summary>/// 上传文件/// </summary>/// <param name"file"></param>/// <returns></returns>[HttpPost("UploadifyFile")][RequestSizeLimit(2000 * 1024 * 1024)] // 设置最大请求体大小为 100MBpublic async …...
12.【线性代数】——图和网络
十二 图和网络(线性代数的应用) 图 g r a p h { n o d e s , e d g e s } graph\{nodes, edges\} graph{nodes,edges}1.关联矩阵2. A A A矩阵的零空间,求解 A x 0 Ax0 Ax0 电势3. A T A^T AT矩阵的零空间,电流总结电流图结论 …...
游戏引擎学习第145天
仓库:https://gitee.com/mrxiao_com/2d_game_3 今天的计划 目前,我们正在完成遗留的工作。当时我们已经将声音混合器(sound mixer)集成到了 SIMD 中,但由于一个小插曲,没有及时完成循环内部的部分。这个小插曲主要是…...
Linux(Centos 7.6)命令详解:zip
1.命令作用 打包和压缩(存档)文件(package and compress (archive) files);该程序用于打包一组文件进行分发;存档文件;通过临时压缩未使用的文件或目录来节省磁盘空间;且压缩文件可以在Linux、Windows 和 macOS中轻松提取。 2.命…...
23年以后版本pycharm找不到conda可执行文件解决办法
这个问题很痛苦,折磨了我半天。 就是链接远程服务器的时候 就一直以为这三个都要配置 就这个conda环境这里怎么都找不到服务器的虚拟环境的python可执行文件,非常痛苦。 后面查找了资料,找了好久,才发现,原来只需要配…...
AGI(Artificial General Intelligence,通用人工智能)技术介绍
文章目录 **AGI的关键特点**1. **泛化能力**:2. **自主性和适应性**:3. **自我意识与推理**: **与当前AI的区别****AGI的挑战**1. **技术难点**:2. **伦理与安全**:3. **资源与算力**: **AGI的实现路径**- …...