第四章-Tomcat线程模型与运行方式 - 指南

news/2025/11/23 21:23:56/文章来源:https://www.cnblogs.com/yangykaifa/p/19261555

第四章:Tomcat 线程模型与运行方式

目录


4.1 线程模型概述

4.1.1 线程模型架构

整体架构图
业务处理
Worker 线程池
Poller 线程
Acceptor 线程
Servlet 处理
业务逻辑
数据库操作
Worker 1
Worker 2
Worker 3
Worker N
Poller 1
Poller 2
Poller N
Acceptor
线程职责分工
线程类型职责数量生命周期
Acceptor接受新连接1个长期运行
Poller处理 I/O 事件1-2个长期运行
Worker处理业务逻辑可配置按需创建

4.1.2 线程池配置

标准线程池
// 标准线程池实现
public class StandardThreadExecutor implements Executor {
private final ThreadPoolExecutor executor;
private final String name;
private final int maxThreads;
private final int minSpareThreads;
private final int maxSpareThreads;
private final long keepAliveTime;
public StandardThreadExecutor() {
this.maxThreads = 200;
this.minSpareThreads = 10;
this.maxSpareThreads = 50;
this.keepAliveTime = 60L;
// 创建线程池
this.executor = new ThreadPoolExecutor(
minSpareThreads,           // 核心线程数
maxThreads,                // 最大线程数
keepAliveTime,             // 空闲时间
TimeUnit.SECONDS,          // 时间单位
new LinkedBlockingQueue<>(), // 工作队列new ThreadFactory() {      // 线程工厂private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix = "http-nio-8080-exec-";@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());t.setDaemon(false);t.setPriority(Thread.NORM_PRIORITY);return t;}});}@Overridepublic void execute(Runnable command) {executor.execute(command);}}
自定义线程池
// 自定义线程池配置
public class CustomThreadExecutor implements Executor {
private final ThreadPoolExecutor executor;
public CustomThreadExecutor() {
// 核心线程数
int corePoolSize = 10;
// 最大线程数
int maximumPoolSize = 200;
// 空闲时间
long keepAliveTime = 60L;
// 时间单位
TimeUnit unit = TimeUnit.SECONDS;
// 工作队列
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);// 线程工厂ThreadFactory threadFactory = new ThreadFactory() {private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix = "custom-exec-";@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());t.setDaemon(false);t.setPriority(Thread.NORM_PRIORITY);return t;}};// 拒绝策略RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,workQueue, threadFactory, handler);}}

4.2 支持的 I/O 模式

4.2.1 BIO(阻塞 I/O)

特点
  • 阻塞模式:每个连接占用一个线程
  • 简单实现:代码逻辑简单,易于理解
  • 资源消耗:线程数量与连接数成正比
  • 适用场景:连接数较少,并发量不高的应用
实现原理
// BIO 连接器实现
public class Http11Protocol extends AbstractHttp11Protocol<Socket> {@Overrideprotected AbstractEndpoint.Handler<Socket> getHandler() {return new Http11ConnectionHandler(this);}}// BIO 连接处理器public class Http11ConnectionHandler extends AbstractConnectionHandler<Socket, Http11Processor> {@Overrideprotected Http11Processor createProcessor() {Http11Processor processor = new Http11Processor(this);processor.setAdapter(getAdapter());return processor;}}
配置示例
<!-- BIO 连接器配置 --><Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100" />

4.2.2 NIO(非阻塞 I/O)

特点
实现原理
// NIO 连接器实现
public class Http11NioProtocol extends AbstractHttp11Protocol<NioChannel> {@Overrideprotected AbstractEndpoint.Handler<NioChannel> getHandler() {return new Http11ConnectionHandler(this);}}// NIO 连接处理器public class Http11ConnectionHandler extends AbstractConnectionHandler<NioChannel, Http11NioProcessor> {@Overrideprotected Http11NioProcessor createProcessor() {Http11NioProcessor processor = new Http11NioProcessor(this);processor.setAdapter(getAdapter());return processor;}}
事件循环
// NIO 事件循环
public class Poller implements Runnable {
private final Selector selector;
private final AtomicBoolean running = new AtomicBoolean(true);
@Override
public void run() {
while (running.get()) {
try {
// 等待事件
int keyCount = selector.select(selectorTimeout);
if (keyCount > 0) {
// 处理就绪的通道
Iterator<SelectionKey> iterator =selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();// 处理 I/O 事件processKey(key);}}} catch (Exception e) {// 处理异常}}}private void processKey(SelectionKey key) {if (key.isReadable()) {// 处理读事件processRead(key);} else if (key.isWritable()) {// 处理写事件processWrite(key);}}}
配置示例
<!-- NIO 连接器配置 --><Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100"maxConnections="8192" />

4.2.3 NIO2(AIO - 异步 I/O)

特点
实现原理
// NIO2 连接器实现
public class Http11Nio2Protocol extends AbstractHttp11Protocol<Nio2Channel> {@Overrideprotected AbstractEndpoint.Handler<Nio2Channel> getHandler() {return new Http11ConnectionHandler(this);}}// NIO2 连接处理器public class Http11ConnectionHandler extends AbstractConnectionHandler<Nio2Channel, Http11Nio2Processor> {@Overrideprotected Http11Nio2Processor createProcessor() {Http11Nio2Processor processor = new Http11Nio2Processor(this);processor.setAdapter(getAdapter());return processor;}}
异步处理
// 异步 I/O 处理
public class Http11Nio2Processor extends AbstractProcessorLight {
@Override
public SocketState service(SocketWrapperBase<Nio2Channel> socketWrapper)throws IOException {// 异步读取socketWrapper.getSocket().read(inputBuffer,inputBuffer.position(),inputBuffer.remaining(),new CompletionHandler<Integer, Void>() {@Overridepublic void completed(Integer result, Void attachment) {// 处理读取结果processRead(result);}@Overridepublic void failed(Throwable exc, Void attachment) {// 处理读取失败processError(exc);}});return SocketState.OPEN;}}
配置示例
<!-- NIO2 连接器配置 --><Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100" />

4.2.4 APR(Apache Portable Runtime)

特点
实现原理
// APR 连接器实现
public class Http11AprProtocol extends AbstractHttp11Protocol<Long> {@Overrideprotected AbstractEndpoint.Handler<Long> getHandler() {return new Http11ConnectionHandler(this);}}// APR 连接处理器public class Http11ConnectionHandler extends AbstractConnectionHandler<Long, Http11AprProcessor> {@Overrideprotected Http11AprProcessor createProcessor() {Http11AprProcessor processor = new Http11AprProcessor(this);processor.setAdapter(getAdapter());return processor;}}
配置示例
<!-- APR 连接器配置 --><Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100" />

4.3 线程生命周期管理

4.3.1 线程创建

线程工厂
// 自定义线程工厂
public class TomcatThreadFactory implements ThreadFactory {
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
private final ThreadGroup group;
private final boolean daemon;
private final int priority;
public TomcatThreadFactory(String namePrefix) {
this(namePrefix, false, Thread.NORM_PRIORITY);
}
public TomcatThreadFactory(String namePrefix, boolean daemon, int priority) {
this.namePrefix = namePrefix;
this.daemon = daemon;
this.priority = priority;
this.group = Thread.currentThread().getThreadGroup();
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement());
t.setDaemon(daemon);
t.setPriority(priority);
return t;
}
}
线程创建流程
// 线程创建流程
public class StandardThreadExecutor implements Executor {
@Override
public void execute(Runnable command) {
// 1. 检查线程池状态
if (executor.isShutdown()) {
return;
}
// 2. 提交任务
executor.execute(command);
}
private void createWorkerThread(Runnable command) {
// 1. 创建线程
Thread worker = threadFactory.newThread(command);
// 2. 设置线程属性
worker.setDaemon(false);
worker.setPriority(Thread.NORM_PRIORITY);
// 3. 启动线程
worker.start();
}
}

4.3.2 线程调度

任务调度
// 任务调度器
public class TaskScheduler {
private final ScheduledExecutorService scheduler;
private final Map<String, ScheduledFuture<?>> tasks;public TaskScheduler() {this.scheduler = Executors.newScheduledThreadPool(1);this.tasks = new ConcurrentHashMap<>();}public void scheduleTask(String name, Runnable task, long delay, TimeUnit unit) {ScheduledFuture<?> future = scheduler.schedule(task, delay, unit);tasks.put(name, future);}public void scheduleAtFixedRate(String name, Runnable task,long initialDelay, long period, TimeUnit unit) {ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(task, initialDelay, period, unit);tasks.put(name, future);}public void cancelTask(String name) {ScheduledFuture<?> future = tasks.remove(name);if (future != null) {future.cancel(false);}}}
线程池监控
// 线程池监控
public class ThreadPoolMonitor {
private final ThreadPoolExecutor executor;
private final ScheduledExecutorService monitor;
public ThreadPoolMonitor(ThreadPoolExecutor executor) {
this.executor = executor;
this.monitor = Executors.newScheduledThreadPool(1);
// 启动监控
startMonitoring();
}
private void startMonitoring() {
monitor.scheduleAtFixedRate(() -> {
// 监控线程池状态
int activeCount = executor.getActiveCount();
int poolSize = executor.getPoolSize();
int corePoolSize = executor.getCorePoolSize();
int maximumPoolSize = executor.getMaximumPoolSize();
long completedTaskCount = executor.getCompletedTaskCount();
long taskCount = executor.getTaskCount();
// 记录监控信息
log.info("ThreadPool Status: active={}, pool={}, core={}, max={}, completed={}, total={}",
activeCount, poolSize, corePoolSize, maximumPoolSize, completedTaskCount, taskCount);
}, 0, 30, TimeUnit.SECONDS);
}
}

4.3.3 线程销毁

优雅关闭
// 优雅关闭
public class GracefulShutdown {
private final ThreadPoolExecutor executor;
private final long timeout;
private final TimeUnit unit;
public GracefulShutdown(ThreadPoolExecutor executor, long timeout, TimeUnit unit) {
this.executor = executor;
this.timeout = timeout;
this.unit = unit;
}
public void shutdown() {
// 1. 停止接受新任务
executor.shutdown();
try {
// 2. 等待现有任务完成
if (!executor.awaitTermination(timeout, unit)) {
// 3. 强制关闭
executor.shutdownNow();
// 4. 再次等待
if (!executor.awaitTermination(timeout, unit)) {
log.warn("Thread pool did not terminate gracefully");
}
}
} catch (InterruptedException e) {
// 5. 中断当前线程
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
资源清理
// 资源清理
public class ResourceCleanup {
private final List<AutoCloseable> resources;public ResourceCleanup() {this.resources = new ArrayList<>();}public void addResource(AutoCloseable resource) {resources.add(resource);}public void cleanup() {for (AutoCloseable resource : resources) {try {resource.close();} catch (Exception e) {log.error("Error closing resource", e);}}resources.clear();}}

4.4 运行模式详解

4.4.1 独立运行模式

启动脚本
#!/bin/bash
# startup.sh
# 设置环境变量
export CATALINA_HOME="/opt/tomcat"
export CATALINA_BASE="/opt/tomcat"
export JAVA_HOME="/opt/java"
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m"
# 启动 Tomcat
exec "$CATALINA_HOME/bin/catalina.sh" run
停止脚本
#!/bin/bash
# shutdown.sh
# 设置环境变量
export CATALINA_HOME="/opt/tomcat"
export CATALINA_BASE="/opt/tomcat"
# 停止 Tomcat
exec "$CATALINA_HOME/bin/catalina.sh" stop
配置管理
<!-- 独立运行配置 --><Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" /><Engine name="Catalina" defaultHost="localhost"><Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><Context path="/myapp" docBase="myapp" /></Host></Engine></Service>
</Server>

4.4.2 内嵌运行模式

Spring Boot 集成
// Spring Boot 应用
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// 自定义 Tomcat 配置
@Configuration
public class TomcatConfig {
@Bean
public TomcatServletWebServerFactory tomcatFactory() {
return new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
// 自定义配置
context.addParameter("app.config", "production");
}
};
}
}
内嵌配置
// 内嵌 Tomcat 配置
public class EmbeddedTomcatConfig {
public static void main(String[] args) throws Exception {
// 创建 Tomcat 实例
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
// 设置基础目录
tomcat.setBaseDir(".");
// 添加上下文
Context context = tomcat.addContext("/myapp", ".");
// 添加 Servlet
Tomcat.addServlet(context, "MyServlet", new MyServlet());
context.addServletMappingDecoded("/myservlet", "MyServlet");
// 启动 Tomcat
tomcat.start();
tomcat.getServer().await();
}
}

4.4.3 反向代理模式

Nginx 配置
# nginx.conf
upstream tomcat_backend {server 127.0.0.1:8080 weight=1;server 127.0.0.1:8081 weight=1;server 127.0.0.1:8082 weight=1;
}
server {listen 80;server_name example.com;location / {proxy_pass http://tomcat_backend;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}location /static/ {alias /var/www/static/;expires 1y;add_header Cache-Control "public, immutable";}
}
负载均衡配置
// 负载均衡配置
public class LoadBalancerConfig {
private final List<Server> servers;private final AtomicInteger currentIndex;public LoadBalancerConfig(List<Server> servers) {this.servers = servers;this.currentIndex = new AtomicInteger(0);}public Server getNextServer() {int index = currentIndex.getAndIncrement() % servers.size();return servers.get(index);}}

4.5 性能对比分析

4.5.1 I/O 模式性能对比

性能测试结果
I/O 模式并发连接数响应时间吞吐量内存使用CPU 使用
BIO100050ms1000 req/s
NIO1000030ms5000 req/s
NIO21000025ms6000 req/s
APR1000020ms8000 req/s
性能分析
// 性能测试代码
public class PerformanceTest {
public void testBIO() {
// BIO 性能测试
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
// 发送请求
sendRequest();
}
long endTime = System.currentTimeMillis();
System.out.println("BIO Time: " + (endTime - startTime) + "ms");
}
public void testNIO() {
// NIO 性能测试
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
// 发送请求
sendRequest();
}
long endTime = System.currentTimeMillis();
System.out.println("NIO Time: " + (endTime - startTime) + "ms");
}
}

4.5.2 线程模型性能对比

线程数量对比
// 线程数量统计
public class ThreadCountMonitor {
public void monitorThreads() {
// 获取线程信息
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
int threadCount = threadBean.getThreadCount();
int peakThreadCount = threadBean.getPeakThreadCount();
long totalStartedThreadCount = threadBean.getTotalStartedThreadCount();
System.out.println("Thread Count: " + threadCount);
System.out.println("Peak Thread Count: " + peakThreadCount);
System.out.println("Total Started Thread Count: " + totalStartedThreadCount);
}
}
内存使用对比
// 内存使用监控
public class MemoryMonitor {
public void monitorMemory() {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
System.out.println("Heap Used: " + heapUsage.getUsed() / 1024 / 1024 + "MB");
System.out.println("Heap Max: " + heapUsage.getMax() / 1024 / 1024 + "MB");
System.out.println("Non-Heap Used: " + nonHeapUsage.getUsed() / 1024 / 1024 + "MB");
}
}

4.6 配置优化建议

4.6.1 线程池优化

核心参数配置
<!-- 线程池优化配置 --><Connector port="8080" protocol="HTTP/1.1"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100"connectionTimeout="20000"keepAliveTimeout="60000"maxKeepAliveRequests="100" />
参数说明
参数说明推荐值调优建议
maxThreads最大线程数200-500根据 CPU 核心数调整
minSpareThreads最小空闲线程数10-50保证快速响应
maxSpareThreads最大空闲线程数50-100避免资源浪费
acceptCount等待队列长度100-200根据并发量调整
connectionTimeout连接超时时间20000ms根据网络环境调整
keepAliveTimeout保持连接时间60000ms根据应用特性调整

4.6.2 内存优化

JVM 参数配置
# JVM 参数优化
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
参数说明
参数说明推荐值调优建议
-Xms初始堆大小512m与 -Xmx 相同
-Xmx最大堆大小1024m-2048m根据应用需求调整
-XX:PermSize永久代初始大小128mJava 8 之前使用
-XX:MaxPermSize永久代最大大小256mJava 8 之前使用
-XX:MetaspaceSize元空间初始大小128mJava 8 及以后使用
-XX:MaxMetaspaceSize元空间最大大小256mJava 8 及以后使用

4.6.3 系统优化

系统参数配置
# 系统参数优化
# 文件句柄数
ulimit -n 65536
# 网络参数
echo 'net.core.somaxconn = 65536' >> /etc/sysctl.conf
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 65536' >> /etc/sysctl.conf
# 应用参数
sysctl -p
参数说明
参数说明推荐值调优建议
ulimit -n文件句柄数65536根据连接数调整
somaxconn监听队列长度65536提高并发处理能力
netdev_max_backlog网络设备队列长度5000提高网络处理能力
tcp_max_syn_backlogTCP 连接队列长度65536提高 TCP 处理能力

4.7 本章小结

关键要点

  1. 线程模型

    • Acceptor 线程:接受新连接
    • Poller 线程:处理 I/O 事件
    • Worker 线程:处理业务逻辑
  2. I/O 模式

    • BIO:阻塞 I/O,简单但性能较低
    • NIO:非阻塞 I/O,高并发处理
    • NIO2:异步 I/O,真正的异步处理
    • APR:原生实现,性能最高
  3. 运行模式

    • 独立运行:传统部署方式
    • 内嵌运行:Spring Boot 集成
    • 反向代理:Nginx + Tomcat 架构
  4. 性能优化

    • 合理配置线程池参数
    • 优化 JVM 参数
    • 调整系统参数

选择建议

  1. 开发环境:使用 NIO 模式,配置简单
  2. 测试环境:使用 NIO 模式,性能适中
  3. 生产环境:使用 APR 模式,性能最优
  4. 高并发场景:使用 NIO2 模式,异步处理

下一步学习

在下一章中,我们将深入探讨 Tomcat 的配置体系与部署机制,了解各种配置文件的用途和配置方法,以及如何实现自动化部署和运维管理。


相关资源

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

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

相关文章

11-21

今日学习了 Date 类的使用,掌握了 SimpleDateFormat 类的日期格式化(yyyy-MM-dd HH:mm:ss)与解析功能,完成了当前日期输出与生日计算案例。 明日计划学习异常处理机制,重点理解 try-catch-finally 语句,以及常见…

11-25

今日学习了字符流的适用场景(文本文件处理),掌握了 FileReader、FileWriter 的读写操作,以及缓冲流(BufferedReader/BufferedWriter)的效率优化。 明日计划学习集合框架,重点理解 List 接口的实现类(ArrayList…

11-24

今日掌握了字节流的核心类(FileInputStream、FileOutputStream),学会了使用字节流读取文件内容、写入数据到文件,完成了图片复制案例。 明日计划学习字符流(Reader/Writer),理解字节流与字符流的区别,重点掌握…

2023-10-15-R-如何阅读一本书

从五月份开始直至昨天,断断续续读完了这本书,但这个过程还是过于走马观花。因为是走马观花,所以大部分的内容根本没有深入理解,更谈不让将之运用于实践了。不过我知道这是一本好书,一本对于我的个人发展是一本好书…

2023-10-11-T-JAVA

1. 易忘知识点用于记录已遗忘的知识点1.1 基础语法一个JAVA文件中的不同类中均可以有public static 方法, 并且可用java 类名的方式运行public static方法javadoc 用于生成java文件的文档,使用方式javadoc xxx.java.…

通过SSH反向隧道让远程服务器走本地代理

通过建立 SSH 反向隧道,使无法直连外网的远程 Linux 服务器能借助本地 Windows 电脑的代理网络执行 git pull 等操作。1. 场景描述 先说一下笔者遇到的情况:本地 Windows 电脑 已经配置好代理或者加速工具,能正常访…

2023-09-19-R-金字塔原理

前言 简介 金字塔原理是美国作家芭芭拉明托在1966年所著,她是著名咨询公司麦肯锡聘用的第一位女性咨询顾问。金字塔原理是她在1966年被派往英国,担任负责麦肯锡欧洲员工写作能力的职位后总结得出的。金字塔原理介绍了…

2023-09-19-E-文章管理

文章管理2023年9月19日生效时间-文章类型-文章名称 文章类型:日记随想:D : Thoughts总结反思:S : Summary技术文章:T : Tech读书笔记:R : Reading效率管理:E : Efficiency日记: 记录一天经历的事件或所思所想 技…

11-6

今日深入学习了 for、while、do-while 三种循环的区别与适用场景,通过循环嵌套完成了九九乘法表、菱形图案打印。 明日计划学习数组的定义、初始化方式,以及数组的遍历、排序等基础操作。

11-18

今日深入学习了 String 类的不可变性,掌握了 charAt ()、substring ()、equals ()、indexOf () 等常用方法,完成了字符串反转、判断回文案例。 明日计划学习 StringBuffer 与 StringBuilder 类的使用,对比三者的效率…

11-12

今日深入学习了封装的意义,通过 private 修饰成员变量,编写 getter/setter 方法实现数据的安全访问,完成了学生类的封装案例。 明日计划学习继承的语法(extends 关键字),理解父类与子类的关系,以及方法的重写。…

11-11

今日理解了面向对象的核心思想(封装、继承、多态),掌握了类的定义(成员变量、成员方法)与对象的实例化(new 关键字)。 明日计划学习封装的实现方式,重点掌握 private 访问修饰符、getter/setter 方法的编写。

苹果app开发上架流程

苹果App开发上架流程主要包括注册账号、开发设置、打包上传、完善信息及提交审核等步骤,具体如下: 1. 注册Apple iOS开发者账号:访问Apple开发者网站,选择“Account”进行注册。填写真实信息,可能需人脸识别和上传…

11-10

今日学习了递归的原理与边界条件设置,通过递归完成了阶乘计算、斐波那契数列输出,理解了递归的优缺点。 明日计划正式进入面向对象编程,学习类与对象的概念,掌握类的定义与对象的创建。

P14566 【MX-S12-T1】取模

先将 \(a\) 排序。 显然,取 \(a_n + 1\) 是一种比较不错的方案,但此时如果最小值很大就会寄掉。 此时 \(p\) 只能够取 \(\le a_n\) 的数,无论取什么最大值都不会超过严格次大值(分类讨论即可),此时让 \(p = a_n\…

TCP 消息分段与粘包问题的完整解决方案 - 指南

TCP 消息分段与粘包问题的完整解决方案 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

语音技术助力非标准语音人群沟通

Voiceitt开发个性化语音识别技术,通过卷积神经网络模型帮助有语言障碍的人群使用语音助手和与他人交流,让非标准语音用户也能享受语音技术带来的便利。Voiceitt将语音革命延伸至非标准语音人群 根据某机构的数据,美…

洛谷 B4357:[GESP202506 二级] 幂和数 ← 嵌套循环

​【题目来源】https://www.luogu.com.cn/problem/B4357【题目描述】对于正整数 n,如果 n 可以表为两个 2 的次幂之和,即 n=2^x+2^y(x,y 均为非负整数),那么称 n 为幂和数。给定正整数 l,r,请你求出满足 l≤n≤…

20232303 2025-2026-1 《网络与系统攻防技术》实验六实验报告

20232303 2025-2026-1 《网络与系统攻防技术》实验六实验报告 1.实验内容

P14457 [ICPC 2025 Xian R] Killing Bits

网络流优化排列匹配先判掉 \(a=b\) 的情况,那么有充要条件(\(\otimes\) 表示按位与):\(\forall i,a_i\otimes b_i=b_i\) \(\exists p,p_i\otimes b_i=b_i\)对于 \(1\) 条件的必要性显然,如果一个位置为 \(0\) 那么…