Java大师成长计划之第27天:RESTful API设计与实现
📢 友情提示:
本文由银河易创AI(https://ai.eaigx.com)平台gpt-4-turbo模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。
在现代软件架构中,RESTful API(Representational State Transfer)已经成为了一种广泛使用的架构风格,它以简单、灵活和可扩展的特性,成为服务端与客户端之间进行通信的重要方式。本篇博文将详细探讨RESTful API的设计原则,以及在Java中如何实现它们。
一、RESTful API概述
在现代的软件开发中,API(应用程序编程接口)已经成为系统间通信的核心。随着互联网应用的快速发展,如何高效且灵活地设计API成为了开发者面临的一个重要课题。RESTful API作为一种基于HTTP协议的轻量级架构风格,以其简洁、易用和高效的特点,成为了当前最流行的API设计方式之一。本章将深入探讨RESTful API的基本概念、特性以及它的核心优势。
1.1 什么是REST?
REST(Representational State Transfer,表现层状态转移)是一种架构风格,它定义了一组约定和约束来指导API的设计与实现。REST并不是一种标准或者协议,而是一种基于Web的设计思想,依赖于HTTP协议和它的请求方法来实现客户端与服务器之间的通信。REST的核心思想是通过资源的标识符(URI)来操作资源,而资源的表现(representation)则由数据格式(如JSON、XML等)来表达。
REST的设计初衷是简化客户端与服务器之间的交互过程,提供一种轻量级的、无需额外状态维护的服务接口。REST强调无状态性(Stateless)和基于资源的操作,这使得RESTful API具备了高度的可扩展性和灵活性。
1.1.1 REST的定义
REST的全名是“Representational State Transfer”,它指的是客户端通过表示资源的某种“状态”来与服务器进行交互的过程。客户端每次发起请求时,都会包含对资源的完整或部分表示,而服务器通过这个表示来处理请求。根据Roy Fielding在其博士论文中的定义,REST具有以下几项关键约束:
- 客户端-服务器架构(Client-Server) :客户端和服务器之间的职责是分离的。客户端负责界面呈现和用户交互,服务器负责处理业务逻辑和数据存储。二者的解耦提高了灵活性和可扩展性。
- 无状态性(Stateless) :每个请求都是独立的,服务器不存储关于客户端的任何状态信息。每个请求必须包含所有必要的信息,服务器不会保存客户端的上下文状态。
- 可缓存性(Cacheable) :响应数据可以被缓存,以提高系统的性能。客户端和中间层都可以缓存响应结果,避免重复计算。
- 统一接口(Uniform Interface) :通过一个统一的接口设计,简化了系统间的交互。通过HTTP协议中定义的标准方法(GET、POST、PUT、DELETE等)来对资源进行操作。
- 分层系统(Layered System) :客户端无法直接感知服务器的实际架构,可能是由多个中间层(如负载均衡器、防火墙等)组成。中间层可以优化系统的性能和可伸缩性。
- 按需代码(Code on Demand,可选) :服务器可以向客户端提供代码(如JavaScript),以便客户端扩展其功能。
这些约束使得RESTful API具有高度的灵活性和可扩展性,尤其适用于互联网应用。
1.2 RESTful API的特点
RESTful API的设计遵循一些基本的原则和特性,下面我们将详细介绍这些特性。
1.2.1 资源导向
RESTful API的核心是“资源”(Resource)。每一个资源都被赋予一个唯一的URI(统一资源标识符),通过这个URI客户端可以访问和操作该资源。在REST中,资源通常是指能够被操作的数据对象,如用户、文章、商品等。
资源的操作通过HTTP方法(GET、POST、PUT、DELETE等)来实现。通过这些方法,客户端可以:
- GET:从服务器获取资源的表现(例如,获取某个用户的信息)。
- POST:创建一个新的资源(例如,创建一个新的用户)。
- PUT:更新已有的资源(例如,修改某个用户的信息)。
- DELETE:删除某个资源(例如,删除某个用户)。
1.2.2 无状态性(Stateless)
RESTful API要求每个请求都必须包含完成请求所需的全部信息,服务器不会在请求之间存储客户端的状态。这意味着每个请求都是独立的,服务器不会记住上一个请求的任何上下文或状态。
这种无状态性特性使得系统具有更高的扩展性,因为服务器不需要为每个客户端请求维护复杂的会话或状态信息。每个请求都是自包含的,便于负载均衡、缓存等优化。
1.2.3 可缓存性(Cacheable)
HTTP协议本身就支持缓存机制,RESTful API利用这一特性,能够通过对响应数据进行缓存来提高系统的性能。当客户端请求某个资源时,如果该资源的数据没有变化,可以直接从缓存中返回数据,而不需要每次都向服务器发起请求。
这一特性不仅减少了服务器的负担,还能降低延迟,提高用户体验。为了确保缓存的有效性,HTTP头部中的Cache-Control
字段和ETag
标签通常被用来控制缓存策略。
1.2.4 统一接口(Uniform Interface)
RESTful API的一个重要特点是它的统一接口,意味着API的使用方式在所有资源之间是一致的。这种统一的设计简化了系统的架构,使得API的学习和使用变得更为容易。RESTful API通过统一的URI和HTTP方法来进行操作,开发者可以快速理解API的设计和使用。
此外,RESTful API还推荐在资源设计时遵循“RESTful资源”的命名规范,例如使用名词表示资源类型,避免动词。这使得API的设计更加直观和易懂。例如:
- 不推荐:
/api/getUserDetails
- 推荐:
/api/users/1
(GET请求获取ID为1的用户)
1.2.5 分层系统(Layered System)
RESTful API架构允许在客户端和服务器之间添加中间层。中间层可以是代理、负载均衡器、缓存服务器等,用于优化请求的处理、提升性能和增强可扩展性。
客户端与服务器之间的每一层都是独立的,客户端只需关心最上层的接口,服务器只需关注自己的业务逻辑,而不必关心中间层的具体实现。通过分层系统,RESTful API能够更好地进行横向扩展,提升系统的可维护性。
1.2.6 按需代码(Code on Demand,选项)
虽然这一特性是可选的,但RESTful架构允许服务器向客户端传递代码(如JavaScript),从而在客户端动态扩展其功能。例如,在Web应用中,服务器可以通过响应返回一些JavaScript代码,客户端接收到代码后可以执行这些代码来实现某些特定的功能。
虽然这一特性并不常用,但它为RESTful架构提供了额外的灵活性,使得服务器可以根据需要向客户端提供更多的功能。
1.3 RESTful API的优势
与传统的SOAP等Web服务协议相比,RESTful API具有以下显著优势:
- 简洁易用:RESTful API设计基于HTTP协议,使用标准的HTTP方法(如GET、POST、PUT、DELETE等),无须复杂的XML解析或SOAP封装,易于理解和使用。
- 无状态性:每个请求都包含所需的所有信息,简化了服务端的实现,避免了复杂的会话管理和状态存储。
- 灵活性和扩展性:RESTful API具有高度的灵活性和可扩展性。随着需求的变化,可以轻松地对API进行版本管理和扩展,而不会破坏现有的系统。
- 易于集成:由于RESTful API基于HTTP协议,几乎所有的编程语言和开发框架都可以轻松地与RESTful API进行集成。
- 性能优化:支持缓存机制,通过HTTP的
Cache-Control
等头部字段优化性能,减少服务器压力。
RESTful API的这些优势使其在Web服务、移动应用、微服务等领域得到了广泛应用。随着互联网应用的不断发展,RESTful API将继续在系统架构中发挥重要作用。
在接下来的章节中,我们将深入探讨如何设计一个符合RESTful原则的API,并介绍如何在Java中实现它。
二、RESTful API设计原则
设计一个高效、清晰且易于维护的RESTful API,不仅仅是简单地使用HTTP请求方法,它需要遵循一系列的设计原则。遵循这些原则,能够确保API具有高可用性、易于扩展性、以及清晰的结构,减少开发过程中出现的问题。本章将详细介绍RESTful API设计的几个重要原则,帮助开发者构建出符合最佳实践的API。
2.1 资源导向
在REST架构中,资源(Resource)是核心概念。资源是系统中的可操作对象,通常对应于数据库中的实体,例如用户、文章、订单、图片等。每个资源都会通过一个唯一的URI(统一资源标识符)来标识。在设计RESTful API时,资源的表示应简洁、明确,并且能够准确反映系统的业务模型。
2.1.1 资源的URI设计
RESTful API强调资源是中心,URI(统一资源标识符)是客户端访问和操作资源的关键。一个良好的URI设计应具有语义化、简洁性、以及易于理解性。以下是一些设计建议:
- 使用名词而非动词:URI应代表资源,而不是操作。例如,表示获取某个用户的信息,应该使用
/api/users/1
,而不是/api/getUser/1
。 - 保持简洁与一致性:URI应该简洁且一致,遵循常见的命名规则。例如,资源名使用复数形式,表示多个资源,如
/api/users
代表所有用户资源,/api/articles
代表所有文章资源。 - 避免层次过深:URI的层级结构应尽量避免过深,过多的嵌套层次会使得API难以管理。应将资源组织得简洁明了,避免不必要的路径嵌套。
例如:
- 获取所有用户信息:
GET /api/users
- 获取单个用户信息:
GET /api/users/{id}
- 创建用户:
POST /api/users
- 更新用户信息:
PUT /api/users/{id}
- 删除用户:
DELETE /api/users/{id}
2.1.2 资源的表现形式(Representation)
RESTful API通过HTTP的请求和响应来交换资源。每个资源都可以有多种表现形式(如JSON、XML、HTML等)。常见的RESTful API多使用JSON作为资源的表现形式,因为它简洁且易于解析。
客户端在向服务器请求资源时,会通过HTTP头部的Accept
字段告知服务器自己希望接收的数据格式,而服务器则通过Content-Type
字段在响应中告知客户端返回的数据格式。
例如,客户端请求一个资源时,可能会带上如下HTTP头部:
Accept: application/json
服务器响应时,返回的数据格式可以是:
Content-Type: application/json
2.2 使用HTTP方法
在RESTful API设计中,HTTP方法是操作资源的基本手段。通过使用不同的HTTP方法,客户端可以对服务器上的资源进行创建、读取、更新和删除(即CRUD操作)。这些HTTP方法对应着不同的操作语义,以下是常见HTTP方法的应用场景:
2.2.1 GET - 获取资源
GET
方法用于从服务器获取资源的表示,通常不会对服务器上的数据进行修改。使用GET
时,客户端应确保请求是幂等的(即多次执行不会改变结果),且不应包含请求体。
- 获取所有资源:
GET /api/users
获取所有用户 - 获取单个资源:
GET /api/users/{id}
获取指定ID的用户
2.2.2 POST - 创建资源
POST
方法用于向服务器提交数据,通常用于创建新的资源。POST
请求可能会改变服务器的状态,因此它通常是非幂等的。
- 创建一个新用户:
POST /api/users
提交新用户的相关信息
2.2.3 PUT - 更新资源
PUT
方法用于更新服务器上的资源。PUT
请求应包含整个资源的表现,它是幂等的,即无论执行多少次,结果是相同的。
- 更新用户信息:
PUT /api/users/{id}
使用新的数据替换指定ID的用户
2.2.4 DELETE - 删除资源
DELETE
方法用于从服务器删除资源。DELETE
请求应确保资源在删除后不再存在,并且是幂等的。
- 删除用户:
DELETE /api/users/{id}
删除指定ID的用户
2.2.5 PATCH - 部分更新资源
PATCH
方法用于对资源进行部分更新。与PUT
不同,PATCH
只更新资源的部分字段,而不是整个资源。它通常用于修改资源的某些属性,而不是替换整个资源。
- 更新用户的某些信息:
PATCH /api/users/{id}
更新指定ID用户的部分信息
通过合理使用这些HTTP方法,可以确保API的操作符合RESTful的原则,简化客户端和服务器的交互,并使得API更加直观和易于理解。
2.3 使用HTTP状态码
在设计RESTful API时,合理使用HTTP状态码能够明确表达请求的结果,使客户端能够根据状态码作出相应的处理。HTTP状态码大致可以分为五类:
-
2xx:成功:请求已成功处理。常见的状态码有:
200 OK
:请求成功,响应中包含所请求的资源。201 Created
:成功创建了资源。204 No Content
:请求成功,但没有返回内容。
-
3xx:重定向:需要进一步操作才能完成请求。
301 Moved Permanently
:资源已被永久移动。302 Found
:资源临时移动。
-
4xx:客户端错误:请求存在问题,客户端应当修改请求后重试。常见的状态码有:
400 Bad Request
:请求无效,服务器无法处理。404 Not Found
:请求的资源未找到。401 Unauthorized
:请求未授权,缺少认证信息。
-
5xx:服务器错误:服务器处理请求时发生错误。常见的状态码有:
500 Internal Server Error
:服务器内部错误,无法完成请求。502 Bad Gateway
:服务器作为网关或代理时收到无效响应。
状态码的使用不仅能准确传达请求的结果,还能帮助开发者在调试过程中更好地识别问题,提升系统的可维护性。
2.4 描述性URL
RESTful API的URI设计应当清晰、简洁,并且有语义性,能够准确反映资源的类型和层次关系。一个良好的URI设计应避免包含动词或操作,而应该通过HTTP方法来表示对资源的操作。这里有几点设计建议:
- 避免冗余信息:URI应该简洁明了,不应包含不必要的参数或信息。例如,
/api/getUserDetails?id=1
是不推荐的设计,应改为/api/users/1
。 - 使用复数形式:表示多个资源时,URI中的资源名称通常使用复数形式。比如,
/api/users
表示所有用户资源,/api/articles
表示所有文章资源。
2.4.1 URI设计示例
- 获取所有用户:
GET /api/users
- 获取特定用户:
GET /api/users/{id}
- 创建用户:
POST /api/users
- 更新用户:
PUT /api/users/{id}
- 删除用户:
DELETE /api/users/{id}
通过这种方式,API的设计更加一致且易于理解,也能减少开发和维护中的混乱。
2.5 文档和版本控制
在API设计完成后,为了确保开发者和使用者能够清晰理解和使用API,提供良好的API文档是非常重要的。文档应包括以下内容:
- API的基本功能和使用方法。
- 请求的URI、请求方法、请求参数和响应格式。
- 状态码的意义及使用场景。
另外,版本控制也是RESTful API设计中不可忽视的一部分。随着API功能的演变,旧版本可能会被废弃或者发生不兼容的变化,因此应当在API路径中加入版本号,如/api/v1/users
,以便将来进行版本迭代而不影响现有用户。
RESTful API设计原则为我们提供了一套清晰的架构设计规范,遵循这些原则可以确保我们设计出的API是高效、可维护且易于扩展的。通过合理的资源设计、HTTP方法的使用、状态码的处理、URI的设计以及良好的文档和版本控制,可以极大地提升API的可用性和可理解性,帮助开发者高效地构建高质量的API服务。
三、Java实现RESTful API
在上一章中,我们详细讨论了RESTful API的设计原则和最佳实践。本章将带你一步步通过Java实现RESTful API,主要借助Spring Boot框架来构建高效、可扩展的API服务。Spring Boot作为当前最流行的Java开发框架之一,凭借其简洁的配置和强大的功能,极大地简化了RESTful API的开发过程。
3.1 构建项目
3.1.1 使用Spring Initializr创建项目
首先,我们需要创建一个新的Spring Boot项目。Spring Boot的启动工具Spring Initializr(https://start.spring.io/)可以帮助我们快速生成一个基本的项目框架。
- 打开Spring Initializr网站。
- 在项目选项中,选择:
- Project: Maven Project(或Gradle Project,根据个人偏好选择)。
- Language: Java。
- Spring Boot: 选择最新的稳定版本。
- Project Metadata:
- Group: com.example
- Artifact: demo
- Name: demo
- Package name: com.example.demo
- Packaging: Jar
- Java: 选择适合的Java版本。
- 在“Dependencies”中,选择“Spring Web”依赖。
- 点击“Generate”按钮,下载并解压生成的项目。
3.1.2 导入到IDE中
下载的Spring Boot项目可以使用IDE(如IntelliJ IDEA、Eclipse等)进行导入。打开IDE并导入解压后的项目,IDE会自动识别并下载所需的依赖。
此时,你已经准备好了一个基础的Spring Boot项目,我们可以开始编写实现RESTful API的代码。
3.2 编写模型类
在RESTful API中,资源通常以对象的形式存在。因此,我们需要为每一个资源创建一个模型类,用于表示资源的属性。这里,我们以用户(User)为例,来说明如何设计模型类。
3.2.1 创建用户模型类
java
package com.example.demo.model;public class User {private Long id;private String name;private String email;// 无参构造函数public User() {}// 带参构造函数public User(Long id, String name, String email) {this.id = id;this.name = name;this.email = email;}// Getters and Setterspublic Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}
}
在这个模型类中,我们定义了User
类,该类具有id
、name
和email
三个属性,分别对应用户的ID、姓名和邮箱地址。通过getters
和setters
方法来访问和修改这些属性。
3.3 编写控制器
RESTful API的核心部分是控制器(Controller),它负责接收客户端的请求,并返回响应。在Spring Boot中,我们可以使用@RestController
注解来定义RESTful API控制器。控制器中的每个方法映射到一个HTTP请求,并返回相应的资源表现形式(通常是JSON)。
3.3.1 创建用户控制器
java
package com.example.demo.controller;import com.example.demo.model.User;
import org.springframework.web.bind.annotation.*;import java.util.ArrayList;
import java.util.List;@RestController
@RequestMapping("/api/users")
public class UserController {private List<User> userList = new ArrayList<>();// 获取所有用户@GetMappingpublic List<User> getAllUsers() {return userList;}// 创建用户@PostMappingpublic User createUser(@RequestBody User user) {userList.add(user);return user;}// 获取单个用户@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {return userList.stream().filter(user -> user.getId().equals(id)).findFirst().orElse(null); // 如果没有找到用户,返回null}// 更新用户@PutMapping("/{id}")public User updateUser(@PathVariable Long id, @RequestBody User user) {User existingUser = getUserById(id);if (existingUser != null) {existingUser.setName(user.getName());existingUser.setEmail(user.getEmail());}return existingUser;}// 删除用户@DeleteMapping("/{id}")public String deleteUser(@PathVariable Long id) {User user = getUserById(id);if (user != null) {userList.remove(user);return "User with id " + id + " has been deleted.";} else {return "User not found.";}}
}
3.3.2 控制器代码解析
@RestController
:该注解表示这是一个RESTful风格的控制器,所有返回值都会自动转换为JSON格式。@RequestMapping("/api/users")
:为控制器类设置基础路径,这样所有请求都以/api/users
为起始路径。@GetMapping
:用于处理HTTP GET请求,用于获取资源。@GetMapping("/{id}")
表示根据用户ID获取特定用户的信息。@PostMapping
:用于处理HTTP POST请求,用于创建资源。@RequestBody User user
注解表示请求体中的JSON数据会自动转换为User
对象。@PutMapping("/{id}")
:用于处理HTTP PUT请求,用于更新资源。@DeleteMapping("/{id}")
:用于处理HTTP DELETE请求,用于删除资源。
该控制器提供了一个简单的用户管理API,支持创建、读取、更新和删除用户。
3.4 配置应用程序
在Spring Boot中,通常会有一个application.properties
或者application.yml
文件用于配置应用程序的相关设置。以下是一个基础的application.properties
文件示例:
properties
# 配置服务器端口
server.port=8080# 配置Spring Boot的日志级别
logging.level.org.springframework.web=INFO
通过这些配置,我们可以设置应用的端口号、日志级别等,进一步优化我们的开发环境。
3.5 运行和测试
3.5.1 启动应用
使用IDE(如IntelliJ IDEA或Eclipse)启动Spring Boot应用。你可以右键点击DemoApplication.java
文件并选择Run
,或者在命令行中使用以下命令:
mvn spring-boot:run
应用启动后,Spring Boot会默认监听8080端口,你可以通过浏览器或Postman等工具访问API。
3.5.2 测试API
通过Postman或curl等工具测试我们的RESTful API:
-
GET 请求获取所有用户:
http
GET http://localhost:8080/api/users
-
POST 请求创建用户:
http
POST http://localhost:8080/api/users Content-Type: application/json {"id": 1,"name": "John Doe","email": "john.doe@example.com" }
-
GET 请求获取指定用户:
http
GET http://localhost:8080/api/users/1
-
PUT 请求更新用户信息:
http
PUT http://localhost:8080/api/users/1 Content-Type: application/json {"name": "John Doe Updated","email": "john.updated@example.com" }
-
DELETE 请求删除用户:
http
DELETE http://localhost:8080/api/users/1
通过这些请求,你可以验证API的功能是否正常。
3.6 小结
本章详细介绍了如何使用Spring Boot框架实现一个简单的RESTful API。通过创建用户模型类、控制器以及配置应用程序,我们实现了一个基本的用户管理API,能够处理常见的CRUD操作。Spring Boot的简洁性和强大的功能使得构建RESTful API变得更加高效和便捷。通过实际测试和验证,我们可以确保API的功能是健全的,且符合RESTful设计原则。
在未来的开发过程中,您可以根据需求扩展此API,增加更多的功能,如认证、分页、异常处理等,打造更强大的服务。
四、总结
RESTful API设计与实现是现代软件开发中的重要技能,合理的设计原则可以显著提高API的可用性与可维护性。在Java中,我们可以借助Spring Boot快速构建RESTful API,为应用的开发提供便利。通过持续学习和实践,成为Java大师并不遥远。
相关文章:
Java大师成长计划之第27天:RESTful API设计与实现
📢 友情提示: 本文由银河易创AI(https://ai.eaigx.com)平台gpt-4-turbo模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。 在现代软件架构中,RESTf…...
SEO长尾词与关键词优化策略
内容概要 在搜索引擎优化(SEO)实践中,长尾关键词与核心关键词的协同布局是提升网站可见性与流量的核心路径。本文系统性阐述从基础策略到高阶技术的全链路优化方案,重点剖析长尾关键词的挖掘逻辑与筛选标准,建立基于搜…...
Linux-进程信号
1.快速认识信号 1.1生活角度的信号 你在⽹上买了很多件商品,再等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临 时,你该怎么处理快递。也就是你能“识别快递” 当快递员到了你楼下,你也收到快递到来的通知&#…...
Trae生成 django5.2.1后台管理
安装django,采用的是5.2.1版本: pip install django Trae对话框中输入: 基于django框架,生成版本管理功能,版本管理模块命名为versions,工程项目命名为main 迁移数据库: python manage.py …...
Interrupt 2025 大会回顾:关于LangChain 的 AI Agent会议内容总结
Interrupt 2025 大会已圆满落下帷幕!今年,来自全球各地的 800 多位人士齐聚旧金山,参加了 LangChain 首次举办的行业盛会,共同聆听各团队分享构建 AI Agent 的经验故事——会议的精彩和余温至今仍令人振奋! 思科、优步…...
C#学习9——接口、抽象类
一、接口 1.什么是接口 官方话:是一种定义契约(一组方法、属性、事件或索引器的抽象声明)的机制,它规定了实现该接口的类或结构必须提供这些成员的具体实现。接口是面向对象编程中实现多态和抽象的重要工具。 个人理解…...
【高德开放平台-注册安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
Xshell实战:远程连接VMware CentOS7虚拟机与高效运维指南——从零配置到自动化操作,解锁Xshell的核心价值
一、实战背景与目标 在开发与运维工作中,常需通过本地Windows主机远程管理虚拟机中的Linux系统。Xshell作为专业终端工具,能快速建立安全连接,执行高效操作。 场景需求: 在Windows系统中,通过Xshell远程连接VMware中的…...
C#编写软件添加菜单栏
将MenuStrip控件拖动到窗体,可以直接在工具箱搜索menu,我是先在窗体上上加了一个panel,把MenuStrip拖动到panel上面,点击即可输入自己需要的文本。...
【C++】map和multimap的常用接口详解
map和multimap的文档:<map> - C Reference 1.map类的介绍 map 有两个模板参数,是 key/value的场景。 这里的Key就是key,T就是value,命名不同而已。map默认要求Key⽀持⼩于⽐较(升序),如…...
线程池模式与C#中用法
一、线程池模式解析 1. 核心概念 线程池是一种 管理线程生命周期的技术,主要解决以下问题: 减少线程创建/销毁开销:复用已存在的线程 控制并发度:避免无限制创建线程导致资源耗尽 任务队列:有序处理异步请求 2. …...
47、C#可否对内存进⾏直接的操作?
是的,C# 可以通过几种方式对内存进行直接操作,尽管它主要是一门托管语言,内存管理通常由.NET运行时自动处理。 主要方法 1.unsafe 代码和指针 使用 unsafe 关键字可以启用指针操作需要项目启用"允许不安全代码"选项示例…...
精益数据分析(70/126):MVP迭代中的数据驱动决策与功能取舍
精益数据分析(70/126):MVP迭代中的数据驱动决策与功能取舍 在创业过程中,最小可行化产品(MVP)的迭代优化是从验证假设到实现产品市场契合的关键环节。今天,我们结合《精益数据分析》中的方法论…...
大数据与数据库服务器参数调优方法
1 硬件配置优化 存储与磁盘 优先选择 SSD固态硬盘替代机械硬盘,显著降低I/O延迟,提升随机读写性能。 采用 RAID 10阵列实现高性能与冗余的平衡,适用于高并发数据库场景。 大数据场景中,通过多磁盘并行挂载(如HDFS)提升吞吐量,规避单盘性能瓶颈。 I/…...
【Fifty Project - D28】
今日完成记录 TimePlan完成情况9:30 - 11:30Leetcode√14:00 - 15:30练胸√15:30 - 16:30Leetcode√19:40 - 21:20有氧√ Leetcode 今天是周赛复盘篇,昨天的周赛太刺激…...
Image and depth from a conventional camera with a coded aperture论文阅读
Image and depth from a conventional camera with a coded aperture 1. 研究目标与实际意义1.1 研究目标1.2 实际问题与产业意义2. 创新方法:编码光圈设计与统计模型2.1 核心思路2.2 关键公式与模型架构2.2.1 图像形成模型2.2.2 深度可区分性准则2.2.3 统计模型与优化框架2.2…...
vue3 vite 项目中自动导入图片
vue3 vite 项目中自动导入图片 安装插件配置插件使用方法 安装插件 yarn add vite-plugin-vue-images -D 或者 npm install vite-plugin-vue-images -D配置插件 在 vite.config.js 文件中配置插件 // 引入 import ViteImages from vite-plugin-vue-images;plugins: [vue(),/…...
软考-软件工程开发模型
软考-软件工程开发模型 参考视频: 软件工程概述&开发模型 ,配合视频理解更清晰~ 软件的生命周期为:需求分析、软件设计、软件开发、运行维护直至被淘汰 几个阶段。 软件工程支持 4 个活动,简称 PDCA,…...
纸上流年:Linux基础IO的文件理解与操作
文章目录 前言:数字世界的窗口🌇序章🏙️正文一、文件理解二、C语言文件操作2.1、文件打开2.2、文件关闭2.3、文件写入2.4、文件读取 三、系统级文件操作3.1、打开 open3.1.1、函数理解 3.2、关闭 close3.3、写入 write3.4、读取 read 四、小…...
基础深度补全模型DepthLab: From Partial to Complete
许多任务本身就包含部分深度信息,例如:(1)三维高斯图像修复;(2)激光雷达深度补全;(3)利用 Dust3R 进行稀疏视角重建;以及(4࿰…...
15 秒写一首歌?AI 音乐生成模型 ACE-Step 上手体验!
在人工智能技术持续突破的浪潮中,音乐创作领域迎来了革命性的变革。近日,阶跃星辰与ACE Studio联合发布的开源音乐大模型ACE-Step(中文名:音跃)正式亮相,标志着AI音乐创作技术迈入全新阶段。这款集成了最新…...
如何在数据库中正确存储金额?
无论是开发电商平台、财务系统还是支付应用,金额的存储都是核心需求。但许多新手开发者常因字段类型选择不当,导致金额计算错误甚至资金损失。本文将用最通俗的语言,详细讲解如何专业地设计数据库中的金额字段。 一、为什么不能随便选字段类型…...
网络请求和状态管理
安装axios 创建项目,输入名称 新建文件夹: 在文件夹下输入cmd 运行 最后在复制到浏览器中 得到页面 使用axios axios封装成模块 实现一个学生信息案例 模拟数据,请求数据 安装完成后新建一个mock文件夹,制作一个模拟数据 配置…...
TIF导入TWF坐标方法
TIF坐标导入 1、打开Arcmap,将影像拖入界面,点击确定 2、点击工具箱→投影变换→定义投影 国家2000,WGS84坐标系 点击确定 显示已完成,即可 3、批处理 将需要定义的tif拖入到ARCMAP中,点击定义投影,右键…...
系统思考:动态性复杂
我们是否有遇到过这样的困境?做决策时,总觉得问题很简单,但总是看不清楚全貌。越做越复杂,最后好像什么都没解决,反而把事情弄得更糟。 其实,这就是动态性复杂的表现。它包含了两个关键因素:细节…...
智能体应用如何重塑未来生活?全面解析技术场景与实在Agent突破
智能体应用有哪些?在科技飞速发展的当下,人工智能正以前所未有的速度渗透到我们生活的方方面面。而智能体技术,作为人工智能领域的一颗璀璨新星,正逐渐展现出其重塑未来生活的巨大潜力。从办公效率的提升到医疗服务的优化…...
20.自动化测试框架开发之Excel配置文件的IO开发
20.自动化测试框架开发之Excel配置文件的IO开发 一、核心架构解析 1.1 类继承体系 class File: # 文件基类# 基础文件验证和路径管理class ExcelReader(File): # Excel读取器# 实现Excel数据解析逻辑1.2 版本依赖说明 # 必须安装1.2.0版本(支持xlsx格式&#…...
1.1 Epson机器人常用指令1-Print函数、RobotInfo$
本文介绍Print, RobotInfo的使用. 主要总结如下: 1. Print可以向串口、网口、手操器TP1,RC软件等发送数据 2. RobotInfo$(4)可以得到机器人序列号。用于防止程序下载到其他机器人上。 3. CX, CY, CZ可以返回点的XYZ坐标值。 Rea…...
【机器人】复现 3D-Mem 具身探索和推理 | 3D场景记忆 CVPR 2025
3D-Mem 是用于具体探索和推理的3D场景记忆,来自CVPR 2025. 使用信息丰富的多视角图像,来表示场景并捕捉已探索区域的丰富视觉信息, 整合了基于前沿的探索,使智能体能够通过考虑已知和潜在的新信息,做出明智的决策。 …...
视觉-语言导航:综述与类别
22年4月来自国防科大的论文“Vision-Language Navigation: A Survey and Taxonomy”。 视觉-语言导航 (VLN) 任务要求智体遵循人类语言指令,在未曾见过的环境中导航。这个充满挑战的领域涉及自然语言处理、计算机视觉、机器人技术等领域,并催生了众多专…...
基于SpringBoot的家政预约系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
什么是子网委派?
Azure 子网委派的概念 子网委托使您能够为所选的 Azure PaaS 服务指定一个特定的子网,并将其注入到您的虚拟网络中。子网委托为客户提供了完全的控制权,可以管理 Azure 服务与其虚拟网络的集成。 当您将子网委托给 Azure 服务时,您允许该服务为该子网建立一些基本的网络配…...
5个yyds的.Net商城开源项目
今天一起来盘点下5个商城开源项目。 1、支持多语言、多商店的商城,.Net7 EF7领域驱动设计架构(Smartstore) 项目简介 Smartstore 支持桌面和移动平台、多语言、多商店、多货币的商城,并支持SEO优化,支持无限数量的…...
如何快速隔离被攻击的服务器以防止横向渗透
网络延迟过高会显著影响用户体验和服务性能,以下是系统化的排查思路和解决方案: --- ### **1. 快速定位问题范围** #### **基础检查** - **测试延迟目标**: bash ping <目标IP或域名> # 检查基础延迟(ICMP…...
【解决】自己的域名任何端口都访问不到,公网地址正常访问,服务器报错500。
一、问题描述 后端项目部署在服务器上,通过域名访问接口服务器报错500,通过浏览器访问殒命的任何端口都是无法访问此网站。 但是通过公网地址访问是可以正常访问到的,感觉是域名出现了问题 二、解决过程 先说结论:问题原因是…...
Kubernetes MCP服务器(K8s MCP):如何使用?
#作者:曹付江 文章目录 1、什么是 Kubernetes MCP 服务器?1.1、K8s MCP 服务器 2、开始前的准备工作2.1. Kubernetes集群2.2. 安装并运行 kubectl2.3. Node.js 和 Bun2.4. (可选)Helm v3 3、如何设置 K8s MCP 服务器3.1. 克隆存储…...
RHCE 练习三:架设一台 NFS 服务器
一、题目要求 1、开放 /nfs/shared 目录,供所有用户查询资料 2、开放 /nfs/upload 目录,为 192.168.xxx.0/24 网段主机可以上传目录,并将所有用户及所属的组映射为 nfs-upload,其 UID 和 GID 均为 210 3.将 /home/tom 目录仅共享给 192.16…...
SpringBoot(二)--- SpringBoot基础(http协议、分层解耦)
目录 前言 一、SpringBoot入门 1.入门程序 2.解析 二、HTTP协议 1.HTTP概述 2.HTTP请求协议 2.1 GET方式的请求协议 2.2 POST方式的请求协议 2.3 两者的区别 2.4 获取请求数据 3.HTTP响应协议 三、分层解耦 1.三层架构 2.IOC&DI 2.1 入门 2.2 IOC详解 2.…...
mongodb部署Shard Cluster
一、创建集群认证文件 mkdir ./data ./confopenssl rand -base64 756 > ./conf/keyfilechmod 400 ./conf/keyfiledocker network create mongo-cluster二、部署configsever副本集 #!/bin/bash inamemongodb:8.0.9 conf_namemongo_conf_ replset_nameconfrsecho "…...
【大数据】MapReduce 编程--索引倒排--根据“内容 ➜ 出现在哪些文件里(某个单词出现在了哪些文件中,以及在每个文件中出现了多少次)
将 Hadoop 所需的 JAR 文件添加到项目中,确保可以使用 Hadoop 的 API JAR (Java Archive) 文件是一种用于打包多个 Java 类文件、资源文件(如图片、配置文件等)以及元数据的压缩文件格式。它类似于 ZIP 文件,但 JAR 文件通常用于 …...
使用PHP对接东南亚、日本、印度和印度尼西亚股票数据源
本文将介绍如何通过StockTV提供的API接口,使用PHP语言来获取并处理东南亚(包括马来西亚、新加坡等)、日本、印度以及印度尼西亚的股票市场数据。我们将以获取市场列表、查询公司信息、查看涨跌排行榜为例,展示具体的操作流程。 准…...
从基础到高级:网站反爬技术全景解析与第三方工具对比
网站反爬与用户行为检测实战指南:从基础防护到智能识别 在当今数据驱动的互联网时代,网站面临着日益复杂的爬虫攻击和恶意行为威胁。本文将系统性地介绍网站反爬与用户行为检测的技术体系,包括基本原理、防护策略、第三方组件选型以及真实案例分析,帮助开发者构建更加安全…...
docker安装Prometheus+Grafana
docker 安装Prometheus 下载镜像 很多镜像服务器都不行了,我用的这个地址还可以 查看可用docker镜像地址:https://cloud.tencent.com/developer/article/2485043 docker pull docker.xuanyuan.me/prom/prometheus:latest启动 docker run -itd --name…...
解决 Linux Bash 脚本因换行符问题导致的 “bash^M: No such file or directory“ 错误
一、问题重现 最近在部署一个 Bash 脚本时遇到一个诡异的问题: bash $ chmod x deploy.sh $ ./deploy.sh /usr/bin/env: ‘bash\r’: No such file or directory 明明脚本内容正确,权限也设置好了,为什么会出现这样的错误? 二…...
DS1302实时时钟模块
目录 0.单片机定时器时钟的几个缺点: 1.DS1302介绍 2.引脚定义和应用电路 3.原理图 4.内部结果框图,RAM(寄存器) 5.寄存器定义 6.时序定义 7.DS1302时钟代码 第一步: 第二步: 第三步:…...
redis的List为什么用ziplist和quicklist
redis的List为什么用ziplist和quicklist 压缩列表(ziplist) 是一种节省内存的数据结构,最早是 Redis 中为了减少内存开销而引入的一种顺序存储结构。它不是标准库里的内容,而是某些底层系统(比如 Redis)在…...
Java 后端基础 Maven
Maven 1.什么是Maven 2.Maven的作用 Maven核心 Maven概述 IDEA集成Maven 1.创建Maven项目 点击设置里的 Project Structure 将jdk和编译语言进行设置 随后点击apply点击ok 2.Maven坐标 3.导入Maven项目 将文件夹复制到当前项目的目录下 在这个目录下,在磁盘中…...
开源情报的发展前景与行业运用
开源情报系统在实际中的应用正随着技术进步和社会需求的增长而不断拓展,其在国家安全、军事、经济、公共卫生等多个领域展现出显著价值。以下是结合最新动态与案例的综合分析: 一、国家安全:从传统到现代的情报体系升级 开源情报在国家安全…...
《黑马前端ajax+node.js+webpack+git教程》(笔记)——node.js教程+webpack教程(nodejs教程)
黑马程序员前端AJAX入门到实战全套教程,包含学前端框架必会的(ajaxnode.jswebpackgit),一套全覆盖 文章目录 Node.js与Webpack-01.Node.js入门定义和作用什么是前端工程化?(离不开node.js)Node.…...
Canvas设计图片编辑器全讲解(一)Canvas基础(万字图文讲解)
一、前序 近两年AI发展太过迅速,各类AI产品层出不穷,AI绘图/AI工作流/AI视频等平台的蓬勃发展,促使图片/视频等复杂内容的创作更加简单,让更多普通人有了图片和视频创作的机会。另一方面用户内容消费也逐渐向图片和视频倾斜。在“…...