【SpringBoot实战专题】「开发实战系列」深入迁出探索剖析SpringBoot服务容器特性的利器之Actuator(Web端点)

news2025/1/30 16:35:09

深入迁出探索剖析SpringBoot服务容器特性的利器之Actuator

  • 内容简介
    • 内容大纲
    • Actuator Web端点
      • 洞察应用程序内部状况的关键
        • Actuator提供了13个端点
        • 启用Actuator
            • Maven依赖
            • Gradle依赖
        • Actuator透视组件装配过程
          • 获得Bean装配报告(/beans)
            • Bean属性概览
            • Bean报告与自动配置洞察
            • `positiveMatches`部分
            • `negativeMatches`部分
          • 查看配置属性(/env)
            • /env端点会报告所有可用的属性
            • 隐藏敏感信息
            • 配置属性信息
          • 端点到控制器的映射(/mappings)
        • 运行时度量
          • 查看应用程序的度量值
            • /metrics端点提供了很多有用的运行时数据
            • 获取指定的metrics的指标度量值
          • 追踪Web请求(/trace)
            • /trace端点会记录下Web请求的细节
      • 关闭应用程序(/shutdown)

内容简介

Spring Boot的Actuator模块在生产环境中为应用程序提供了关键的监控和度量功能。这些功能主要通过REST端点、远程shell和JMX等技术实现,其中REST端点是最为人们所熟知的,并且提供了全面的功能集。通过Actuator,开发人员可以轻松地管理和监控运行中的Spring Boot应用程序,确保其稳定性和性能。

内容大纲

生产环境监控与度量

Actuator Web端点

Actuator是Spring Boot的一个子项目,它为Spring Boot应用提供了管理和监控功能。通过Actuator的Web端点,开发人员可以轻松地查看和管理运行中的Spring Boot应用程序。

2. 调整Actuator

为了更好地适应不同的应用场景和需求,Actuator提供了许多可配置的参数。开发人员可以根据实际需要对这些参数进行调整,如修改端点的安全性设置、调整监控数据的收集频率等。

3. 通过shell连入运行中的应用程序

对于正在运行的应用程序,可以通过shell进行连接和交互。这使得开发人员可以执行特定的命令或脚本,以获取应用程序的实时状态或进行故障排查。

4. 保护Actuator

为了确保Actuator的安全性,开发人员应采取必要的保护措施。例如,限制对Actuator端点的访问权限、使用HTTPS进行通信等。这样可以防止未经授权的访问和潜在的安全风险。

Actuator Web端点

Spring Boot Actuator的核心优势在于其提供的众多Web端点,这些端点为开发人员提供了应用程序运行时的内部状况的详细信息。

洞察应用程序内部状况的关键

通过Actuator,你可以深入了解Spring应用程序上下文中的Bean如何组装在一起,掌握应用程序的环境属性,以及获取运行时的度量信息快照。

Actuator提供了13个端点

这些功能对于监控、调试和优化应用程序的性能至关重要,端点可以分为三大类:配置端点、度量端点和其他端点。让我们分别了解一下这些端点,从提供应用程序配置信息的端点看起。

HTTP方法路径描述
GET/autoconfig提供了丰富的监控和度量功能,还为用户提供了一份详细的自动配置报告。这份报告记录了哪些自动配置条件已通过,哪些未通过
GET/configprops配置属性,这些配置属性可以设置默认值,并在运行时根据需要进行调整
GET/beans描述应用程序上下文里全部的Bean,以及它们的关系
GET/dump获取线程活动快照的功能
GET/env获取全部环境属性
GET/env/{name}根据名称获取特定的环境属性值
GET/health报告应用程序的健康指标,这些值由HealthIndicator的实现类提供
GET/info获取应用程序的定制信息,这些信息由info打头的属性提供
GET/mappings描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系
GET/metrics报告各种应用程序度量信息,比如内存用量和HTTP请求计数
GET/metrics/{name}报告指定名称的应用程序度量值
GET/shutdown关闭应用程序,要求endpoints.shutdown.enabled设置为true
GET/trace提供基本的HTTP请求跟踪信息(时间戳、HTTP头等)
启用Actuator

要启用Actuator的端点,只需在项目中引入Actuator的起步依赖即可。

Maven依赖
<dependency> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-actuator</artifactId> 
</dependency>
Gradle依赖
compile 'org.springframework.boot:spring-boot-starter-actuator'

无论Actuator是如何添加的,在应用程序运行时自动配置都会生效,Actuator会开启。

Actuator透视组件装配过程

在Spring开发中,组件扫描和自动织入是常见的功能,但如何清晰地看到应用程序中的组件是如何装配起来的,却一直是困扰开发人员的问题。

Spring Boot Actuator的出现,为解决这一问题提供了新的途径。通过Actuator提供的Web端点,开发人员可以直观地查看组件的装配过程,深入了解Bean在Spring应用程序上下文中的关系和行为。这不仅有助于解决配置和装配过程中的问题,还能为性能优化和故障排查提供关键的信息。

获得Bean装配报告(/beans)

了解应用程序中Spring上下文的情况,最重要的端点就是/beans。它会返回一个JSON数据,描述上下文里每个Bean的情况,包括其Java类型以及注入的其他Bean。

向/beans(在本地运行时是http://ip:port/beans)发起GET请求后。

{
    "beans": [
        {
            "bean": "application",
            "dependencies": [],
            "resource": "null",
            "scope": "singleton",
            "type": "test.Application$$EnhancerBySpringCGLIB$$f363c202"
        }
 ...
],
"context": "application",
"parent": null
}
]
Bean属性概览

所有的Bean模型下面都有五个属性:

Bean报告与自动配置洞察

Spring Boot Actuator的beans端点提供了一份详尽的报告,让你清楚了解Spring应用程序上下文中都包含了哪些Bean。这份报告不仅列出了Bean的名称或ID,还提供了关于Bean的其他关键信息。

与此同时,autoconfig端点则深入解析了Bean的来源。它解释了为什么某个特定的Bean会出现,或者为什么某个Bean没有出现。这对于理解自动配置的逻辑和决策过程非常有价值,有助于解决配置和依赖注入过程中的问题。

{
	"positiveMatches": {
		...
"DataSourceAutoConfiguration.JdbcTemplateConfiguration #
		jdbcTemplate ": [  {
			"condition": "OnBeanCondition",
			"message": "@ConditionalOnMissingBean (types: 
			org.springframework.jdbc.core.JdbcOperations;
			SearchStrategy: all) found no beans " 
	}
],
...
},
"negativeMatches": {
	"ActiveMQAutoConfiguration": [{
		"condition": "OnClassCondition",
		"message": "required @ConditionalOnClass classes not found: 
		javax.jms.ConnectionFactory,
		 org.apache.activemq
		.ActiveMQConnectionFactory " 
	}],
	...
}
}
positiveMatches部分

会发现一个决定Spring Boot是否自动配置JdbcTemplate Bean的条件。该条件匹配项被称为DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate,这表明满足特定条件的自动配置类已被应用。

条件类型为OnBeanCondition,这意味着是否满足该条件取决于是否存在特定的Bean。

在这个例子中,message属性明确指出,该条件正在检查系统中是否存在JdbcOperations类型的Bean(JdbcTemplate实现了这个接口)。如果系统中未配置此类型的Bean,那么该条件将被满足,并将创建一个新的JdbcTemplate Bean。

negativeMatches部分

有一个条件用于决定是否应当配置ActiveMQ。这是基于OnClassCondition的条件,其检查目标类路径(Classpath)是否含有ActiveMQConnectionFactory类。由于类路径中不存在此类,因此条件不成立,Spring Boot将不会自动配置ActiveMQ。

查看配置属性(/env)

通过访问 /env 端点,你能够查看应用程序中所有可用的环境属性清单,不论这些属性是否被实际使用。这包含从多个来源汇总而来的信息,如环境变量、JVM 系统属性、命令行参数,以及来自 application.propertiesapplication.yml 文件的配置属性。这项特性为理解和调试应用程序提供了一个全面的视角。

/env端点会报告所有可用的属性

基本上,任何能给Spring Boot应用程序提供属性的属性源都会列在/env的结果里,同时会显示具体的属性。

属性的来源构成了一个多层次、多维度的体系,涉及从应用程序配置文件(例如application.yml)的基础参数设定到Spring Profile的精细化策略定制。进一步扩展,属性可能源自Web应用的Servlet上下文初始化参数,亦或是更广泛的系统环境变量,以及与Java虚拟机(JVM)相关的系统属性。

{
    "applicationConfig: [classpath:/application.yml]": {
        "amazon.associate_id": "habuma-20",
        "error.whitelabel.enabled": false,
        "logging.level.root": "INFO"
    },
    "profiles": [],
    "servletContextInitParams": {},
    "systemEnvironment": {
        "BOOK_HOME": "/Users/habuma/Projects/BookProjects/walls6",
        "GRADLE_HOME": "/Users/habuma/.sdkman/gradle/current",
        "GRAILS_HOME": "/Users/habuma/.sdkman/grails/current",
        "GROOVY_HOME": "/Users/habuma/.sdkman/groovy/current", 
         ...
    },
    "systemProperties": {
        "PID": "682",
        "file.encoding": "UTF-8",
        "file.encoding.pkg": "sun.io",
        "file.separator": "/", 
         ...
    }
}
隐藏敏感信息

属性在应用程序中承担着配置和敏感数据传递的重要角色,其中包括但不限于数据库凭据或API访问密钥。出于安全考虑,确保这些敏感信息不被无意间泄露至系统外部至关重要。为此,Actuator的/env端点在展示环境属性时采用了一项隐蔽措施:任何包含关键词如passwordsecretkey,或其变量名的最后一部分含有这些关键词的属性值,都将在/env端点中以星号(*)显示,以此来马赛克敏感内容。例如,如果存在一个属性名为database.password,在/env端点中,其值将不会直接显示,而是如下所示:

"database.password": "******"

这种措施能有效地减少敏感信息通过系统监控工具被不当访问或泄漏的风险。

配置属性信息

/env 端点不仅提供了查看环境属性的能力,还可以用来检索特定的属性值。例如,想要获取阅读列表应用程序中 amazon.associate_id 的值,可以简单地向 /env/amazon.associate_id 发起请求,这将返回 habuma-20。

提到环境属性的使用可以通过@ConfigurationProperties 注解实现极高的便捷性。通过此注解,相关属性会自动填充至标有 @ConfigurationProperties 的 Bean 的相应字段中。 /configprops 端点则提供了一个详细报告,展示了这些属性是如何设置的。

 "management.endpoints.web-org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties": {
          "prefix": "management.endpoints.web",
          "properties": {
            "pathMapping": {},
            "exposure": {
              "include": [
                "*"
              ],
              "exclude": []
            },
            "basePath": "/actuator",
            "discovery": {
              "enabled": true
            }
          },
          "inputs": {
            "pathMapping": {},
            "exposure": {
              "include": [
                {
                  "value": "*",
                  "origin": "class path resource [application.properties] - 4:43"
                }
              ],
              "exclude": []
            },
            "basePath": {},
            "discovery": {
              "enabled": {}
            }
          }
        }
端点到控制器的映射(/mappings)

在小型应用程序中,跟踪控制器映射到的端点相对简单。但随着应用程序的扩展,Web界面的控制器和请求处理方法数量可能会快速增长,此时若能有一个清晰的列表显示应用程序公开的所有端点,则大大有助于管理和维护。为此,/mappings 端点提供了一个实用的解决方案,它生成了一个详细的端点映射列表,使开发者和管理员能够一目了然地掌握整个应用程序的接口结构。

{
  "contexts": {
    "application": {
      "mappings": {
        "dispatcherServlets": {
          "dispatcherServlet": [
            {
              "handler": "Actuator web endpoint 'scheduledtasks'",
              "predicate": "{GET [/actuator/scheduledtasks], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}",
              "details": {
                "handlerMethod": {
                  "className": "org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler",
                  "name": "handle",
                  "descriptor": "(Ljakarta/servlet/http/HttpServletRequest;Ljava/util/Map;)Ljava/lang/Object;"
                },
                "requestMappingConditions": {
                  "consumes": [],
                  "headers": [],
                  "methods": [
                    "GET"
                  ],
                  "params": [],
                  "patterns": [
                    "/actuator/scheduledtasks"
                  ],
                  "produces": [
                    {
                      "mediaType": "application/vnd.spring-boot.actuator.v3+json",
                      "negated": false
                    },
                    {
                      "mediaType": "application/vnd.spring-boot.actuator.v2+json",
                      "negated": false
                    },
                    {
                      "mediaType": "application/json",
                      "negated": false
                    }
                  ]
                }
              }
            },
        "servletFilters": [
          {
            "servletNameMappings": [],
            "urlPatternMappings": [
              "/*"
            ],
            "name": "requestContextFilter",
            "className": "org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter"
          },
          {
            "servletNameMappings": [],
            "urlPatternMappings": [
              "/*"
            ],
            "name": "webMvcObservationFilter",
            "className": "org.springframework.web.filter.ServerHttpObservationFilter"
          },
          {
            "servletNameMappings": [],
            "urlPatternMappings": [
              "/*"
            ],
            "name": "Tomcat WebSocket (JSR356) Filter",
            "className": "org.apache.tomcat.websocket.server.WsFilter"
          },
          {
            "servletNameMappings": [],
            "urlPatternMappings": [
              "/*"
            ],
            "name": "characterEncodingFilter",
            "className": "org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter"
          },
          {
            "servletNameMappings": [],
            "urlPatternMappings": [
              "/*"
            ],
            "name": "formContentFilter",
            "className": "org.springframework.boot.web.servlet.filter.OrderedFormContentFilter"
          }
        ],
        "servlets": [
          {
            "mappings": [
              "/"
            ],
            "name": "dispatcherServlet",
            "className": "org.springframework.web.servlet.DispatcherServlet"
          }
        ]
      }
    }
  }
}

在上面的内容中,我们可以观察到众多的端点映射。每一个映射实体都以字符串形式作为键,这些字符串反映了Spring MVC中@RequestMapping注解所定义的属性。这些映射字符串为我们提供了透彻的视角,即使不查阅源代码,也能清楚地理解控制器的映射机制。映射实体的值包含两个关键属性:beanmethod

Actuator的配置端点能很方便地让你了解应用程序是如何配置的。能看到应用程序在运行时究竟发生了什么,这很有趣、很实用。度量端点能展示应用程序运行时内部状况的快照。

运行时度量

为了有效评估应用程序的健康状况,进行实时度量数据的快照至关重要。Actuator设计了一系列端点,使得您可以在应用程序运行期间进行便捷地检查。让我们深入探究这些端点的功能,特别是从 /metrics 端点开始。

查看应用程序的度量值

对于正在运行的应用程序,我们可以获取许多有趣且实用的信息。例如,对应用程序的内存使用情况(包括可用内存或剩余内存)的了解,可以帮助我们决策合适的JVM内存分配量。对于Web应用程序,不必翻阅繁杂的Web服务器日志,我们就能通过监测请求失败或响应时间过长的情况,大致推断内存使用的状态。

在应用程序运行期间,众多的计数器和度量工具正实时记录着关键的性能指标。/metrics 端点就提供了这样一个方便的窗口,让我们能够随时抓取这些关键数据的即时快照。

/metrics端点提供了很多有用的运行时数据
{ 
	 mem: 198144, 
	 mem.free: 144029, 
	 processors: 8, 
	 uptime: 1887794, 
	 instance.uptime: 1871237, 
	 systemload.average: 1.33251953125, 
	 heap.committed: 198144, 
	 heap.init: 131072, 
	 heap.used: 54114, 
	 heap: 1864192, 
	 threads.peak: 21, 
	 threads.daemon: 19, 
	 threads: 21, 
	 classes: 9749, 
	 classes.loaded: 9749, 
	 classes.unloaded: 0, 
	 gc.ps_scavenge.count: 22, 
	 gc.ps_scavenge.time: 122, 
	 gc.ps_marksweep.count: 2, 
	 gc.ps_marksweep.time: 156, 
	 httpsessions.max: -1, 
	 httpsessions.active: 1, 
	 datasource.primary.active: 0, 
	 datasource.primary.usage: 0, 
	 counter.status.200.beans: 1, 
	 counter.status.200.env: 1, 
	 counter.status.200.login: 3, 
	 counter.status.200.metrics: 2, 
	 counter.status.200.root: 6, 
	 counter.status.200.star-star: 9, 
	 counter.status.302.login: 3, 
	 counter.status.302.logout: 1, 
	 counter.status.302.root: 5, 
	 gauge.response.beans: 169, 
	 gauge.response.env: 165, 
	 gauge.response.login: 3, 
	 gauge.response.logout: 0, 
	 gauge.response.metrics: 2, 
	 gauge.response.root: 11, 
	 gauge.response.star-star: 2 
}

/metrics端点提供了很多信息,在此我们进行了分类,如下表所示:

分 类前 缀报告内容
垃圾收集器gc.*已经发生过的垃圾收集次数,以及垃圾收集所耗费的时间,适用于标记-清理垃圾收集器和并行垃圾收集器(数据源自 java.lang.management.GarbageCollectorMXBean
内存mem.*分配给应用程序的内存数量和空闲的内存数量(数据源自java.lang.Runtime
heap.*当前内存用量(数据源自java.lang.management.MemoryUsage
类加载器classes.*JVM类加载器加载与卸载的类的数量(数据源自java.lang.management.ClassLoadingMXBean
系统processorsuptimeinstance.uptimesystemload.average系统信息,例如处理器数量(数据源自java.lang.Runtime)、运行时间(数据源自java.lang.management.RuntimeMXBean)、平均负载(数据源自java.lang.management.OperatingSystemMXBean
线程池threads.*线程、守护线程的数量,以及JVM启动后的线程数量峰值(数据源自java.lang.management.ThreadMXBean
数据源datasource.*数据源连接的数量(源自数据源的元数据,仅当Spring应用程序上下文里存在DataSource Bean的时候才会有这个信息)
Tomcat会话httpsessions.*Tomcat的活跃会话数和最大会话数(数据源自嵌入式Tomcat的Bean,仅在使用嵌入式Tomcat服务器运行应用程序时才有这个信息)
HTTP计数器counter.status.*gauge.response.*多种应用程序服务HTTP请求的度量值与计数器

HTTP的计数器和度量值需要做一点说明。counter.status后的值是HTTP状态码,随后是所请求的路径。举个例子,counter.status.200.metrics表明/metrics端点返回200(OK)状态码的次数。

需要特别注意的是,有几个特殊的路径值。root 路径指的是根目录,即 /**(双星)代表了Spring框架认定的静态资源的路径,这些静态资源包括图片、JavaScript 文件和样式表等。此外,双星路径还涵盖了那些无法找到的资源。这解释了为什么我们常常会见到 counter.status.404.** 这样的路径,它记录了返回HTTP 404状态码(未找到)的请求次数。

除了上述的数据度量之外,你还可以注册自己的度量信息。

获取指定的metrics的指标度量值

/metrics端点会返回所有的可用度量值,但你也可能只对某个值感兴趣。要获取单个值,请求时可以在URL后加上对应的键名。例如,要查看空闲内存大小,可以向/metrics/mem.free发一个GET请求:

$ curl localhost:8080/metrics/mem.free 
1444231
追踪Web请求(/trace)

尽管/metrics端点为Web请求提供了一些基础的计数和计时信息,但这些数据往往不够详尽。在进行故障排查时,能够获得关于处理请求的更细节信息显得尤为重要。因此,/trace端点的作用就凸显出来了。它不仅记录了每个Web请求的详细信息,如请求方法、请求路径、时间戳,还包括了请求与响应的头部信息。代码清单7-7展示了/trace端点输出的样例,其中包含了对请求跟踪项的完整描述。

/trace端点会记录下Web请求的细节
[ 
 ... 
 {
        "timestamp": 1426378239775,
        "info": {
            "method": "GET",
            "path": "/metrics",
            "headers": {
                "request": {
                    "accept": "*/*",
                    "host": "localhost:8080",
                    "user-agent": "curl/7.37.1"
                },
                "response": {
                    "X-Content-Type-Options": "nosniff",
                    "X-XSS-Protection": "1; mode=block",
                    "Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
                    "Pragma": "no-cache",
                    "Expires": "0",
                    "X-Frame-Options": "DENY",
                    "X-Application-Context": "application",
                    "Content-Type": "application/json;charset=UTF-8",
                    "Transfer-Encoding": "chunked",
                    "Date": "Sun, 15 Mar 2015 00:10:39 GMT",
                    "status": "200"
                }
            }
        }
    }
]

正如method和path属性所示,你可以看到这个跟踪项是一个针对/metrics的请求。timestamp属性(以及响应中的Date头)告诉了你请求的处理时间。headers属性的内容是请求和响应中所携带的头信息。

关闭应用程序(/shutdown)

在处理微服务架构下运行在云平台上的应用程序时,我们有时会遇到某个服务实例出现问题,需要进行重启以确保服务的正常运行和稳定性。在这种情况下,使用Actuator的/shutdown端点可以是一个高效的方法。具体而言,当我们确定一个服务实例需要关闭时,可以向该实例的/shutdown端点发送一个HTTP POST请求。这个操作会安全地关闭服务实例,之后云服务提供商可以根据配置的策略来自动重启该服务。这样做的好处是可以最小化服务中断的时间,并确保服务的弹性和可靠性。

注意,这一做法应该谨慎使用,并确保你拥有适当的权限,并且这一策略符合你的应用程序部署和运维策略。此外,开启Actuator的/shutdown端点可能带来安全风险,因此请确保适当保护该端点,避免未授权的访问。

可以用命令行工具curl来关闭应用程序:

$ curl -X POST http://ip:port/shutdown

很显然,关闭运行中的应用程序是件危险的事情,因此这个端点默认是关闭的。如果没有显式地开启这个功能,那么POST请求的结果是这样的:

{"message":"This endpoint is disabled"} 

要开启该端点,可以将endpoints.shutdown.enabled设置为true。举例来说,可以把如下内容加入application.yml,借此开启/shutdown端点:

endpoints: 
  shutdown: 
    enabled: true 

打开/shutdown端点后,你要确保并非任何人都能关闭应用程序。这时应该保护/shutdown端点,只有经过授权的用户能关闭应用程序。

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

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

相关文章

代码随想录算法训练营第一天|数组理论基础、704二分查找、27移除元素

数组理论基础 一维数组 数组中的元素在内存空间中是连续的数组名与数组中第一个元素的地址相同&#xff08;一维数组&#xff09;数组的下标从0开始删除数组的元素其实是用后面的元素覆盖掉要删除的元素数组的长度不能改变 二维数组 二维数组是按照行存储的&#xff0c;也是…

宠物空气净化器品牌推荐哪个牌子好?五款猫用空气净化器高质量推荐品牌

养宠人家里除了猫粮、猫砂和罐头等必备的日常用品外&#xff0c;宠物空气净化器也是必需的。它可以在我们不方便开窗通风的日子里&#xff0c;有效净化室内空气&#xff0c;并且能够有效减少动物皮屑引起的过敏反应。然而&#xff0c;面对市场上琳琅满目的新款空气净化器、功能…

Python--循环语句

在 Python 中&#xff0c;循环语句用于重复执行一段代码多次。Python 主要提供了两种类型的循环&#xff1a;for 循环和 while 循环。 1. for 循环 for 循环用于遍历可迭代对象&#xff08;如列表、元组、字典、字符串等&#xff09;中的每个元素&#xff0c;并对每个元素执行…

【牛客周赛Round 27】题目讲解

题目一 小红的二进制删数字&#xff1a; 小红拿到了一个二进制字符串 s&#xff0c;她可以删掉其中的一些字符&#xff0c;使得最终该字符串为一个2的幂&#xff08;即可以表示为 2^k 形式的数&#xff09;。小红想知道&#xff0c;自己最少删几个字符可以达成&#xff1f;请你…

哈希表的实现(2):拉链法实现哈希表

一&#xff0c;拉链法 在使用线性探测法实现哈希表时&#xff0c;会发生哈希冲突。这个时候就得向后找位置给新插入的值。这个过程无疑会对哈希表的效率有很大的影响。那我们能不能通过另一种方式来实现哈希表&#xff0c;让哈希表不会发生哈希冲突呢&#xff1f;答案当然是可以…

海外媒体宣发:新闻媒体发稿引爆社交媒体的7个诀窍-华媒舍

社交媒体的崛起已经改变了新闻媒体的传播方式。从Facebook到Twitter&#xff0c;从Instagram到LinkedIn&#xff0c;社交媒体平台为新闻媒体提供了一个巨大且潜力无限的受众群体。要在这个竞争激烈的环境中引爆社交媒体&#xff0c;需要一些技巧和诀窍。在本篇文章中&#xff0…

代码随想录算法训练营day8|344.反转字符串、541.反转字符串II、54.替换数字、151.翻转字符串里的单词、55.右旋转字符串

344.反转字符串 541. 反转字符串II 卡码网&#xff1a;54.替换数字 151.翻转字符串里的单词 卡码网&#xff1a;55.右旋转字符串 344.反转字符串 建议&#xff1a; 本题是字符串基础题目&#xff0c;就是考察 reverse 函数的实现&#xff0c;同时也明确一下 平时刷题什么时候用…

2624. 蜗牛排序

说在前面 &#x1f388;不知道大家对于算法的学习是一个怎样的心态呢&#xff1f;为了面试还是因为兴趣&#xff1f;不管是出于什么原因&#xff0c;算法学习需要持续保持。 题目描述 请你编写一段代码为所有数组实现 snail(rowsCount&#xff0c;colsCount) 方法&#xff0c;…

第 4 章 链表

文章目录 4.1 链表(Linked List)介绍4.2 单链表的应用实例4.3 单链表面试题(新浪、百度、腾讯)4.4 双向链表应用实例4.4.1 双向链表的操作分析和实现4.4.2 课堂作业和思路提示 4.5 单向环形链表应用场景4.6 单向环形链表介绍4.7 Josephu 问题4.8 Josephu 问题的代码实现 4.1 链…

Fiddler工具 — 14.Composer界面

1、Composer介绍 Fiddler的Composer的功能就是用来创建HTTP Request然后发送请求。 允许自定义请求发送到服务器&#xff0c;即可以手动创建一个新的请求&#xff0c;也可在会话表中拖拽一个现有的请求。 Fiddler创建Request有两种方式&#xff1a; 可以手写一个Request。 在…

如何在 openKylin 上安装 ONLYOFFICE 文档?

文章作者&#xff1a;ajun ONLYOFFICE 文档是一款全面的在线办公工具&#xff0c;提供了文本文档、电子表格和演示文稿的查看和编辑功能。它高度兼容微软 Office 格式&#xff0c;包括 .docx、.xlsx 和 .pptx 等文件格式&#xff0c;并支持实时协作编辑&#xff0c;使团队成员能…

DHCP自动获取实验和DNS正向解析实验

一、服务程序 1.1DHCP定义 DHCP&#xff08;动态主机配置协议&#xff09;是一个局域网的网络协议。指的是由服务器控制一段IP地址范围&#xff0c;客户机登录服务器时就可以自动获得服务器分配的IP地址和子网掩码。默认情况下&#xff0c;DHCP作为Windows Server的一个服务组…

嵌入式软件开发对硬件知识的掌握要求要多高?

嵌入式软件开发对硬件知识的掌握要求要多高&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff0…

QT+jenkins window环境实现一键自动化构建打包签名发布

jenkins + QT 自动化构建打包 1.官网下载地址: Jenkins download and deployment,下载最新版本的安装包并安装。安装过程中,会要求你输入端口号并记住。 2.java下载地址:Java Downloads | Oracle,下载最新版本的安装包并安装。 3.浏览器输入网址:127.0.0.1: port, port为…

【Docker】镜像的构建与上传下载阿里云

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Docker实战》。&#x1f3af;&#x1f3af; &…

STEGNN

STEGNN 摘要 随着智能交通系统(ITS)逐渐融入我们的日常生活,人们普遍认为路网预测是智能交通系统的杀手锏,具有很高的社会和经济效益。然而,目前的解决方案忽视了时空交通数据的异质性,无法捕捉隐藏的时空相关性。本文介绍了 STEGNN:一种用于路网预测的新型时空嵌入图神…

linux主机的免密登录

实现linux主机之间的相互免密登录 在进行远程登录的时&#xff0c;服务器和主机间进行认证阶段分为&#xff1a; 基于口令认证&#xff08;不安全&#xff0c;易被抓包拦截获取&#xff09; 客户机连接服务器时&#xff0c;服务器将自己的公钥返回给客户机 客户机会将服务器的…

vue知识-04

计算属性computed 注意&#xff1a; 1、计算属性是基于它们的依赖进行缓存的 2、计算属性只有在它的相关依赖发生改变时才会重新求值 3、计算属性就像Python中的property&#xff0c;可以把方法/函数伪装成属性 4、computed: { ... } 5、计算属性必须要有…

视频号小店发展前景怎样?适合新手入驻吗?

我是电商珠珠 视频号于22年7月发展了属于自己的平台-视频号小店。作为一个发展了才一年的平台来说&#xff0c;很多人都不敢入驻&#xff0c;害怕它很快就会垮掉。 我们团队在22年10月的时候&#xff0c;开始入驻其中。发现它的玩法和抖音小店相比并没有什么两样。 在刚开始…

深度学习工具-如何选择服务器和GPU

深度学习训练通常需要大量的计算。目前&#xff0c;GPU是深度学习最具成本效益的硬件加速器。与CPU相比&#xff0c;GPU更便宜&#xff0c;性能更高&#xff0c;通常超过一个数量级。此外&#xff0c;一台服务器可以支持多个GPU&#xff0c;高端服务器最多支持8个GPU。更典型的…