从零到Offer:Java Socket面试通关秘籍-Socket面试为何总让人“心跳加速”? - 实践

news/2025/9/22 13:49:16/文章来源:https://www.cnblogs.com/yxysuanfa/p/19105102

一、为什么面试官总爱问Socket?

        在Java后端开发岗位中,Socket编程是考察网络通信能力的核心知识点。大厂常通过此类题目验证候选人:

  • 对TCP/IP协议栈的理解深度
  • 多线程与IO模型的实战能力
  • 高并发场景下的问题解决思路

真实案例‌:某候选人因无法解释三次握手与Socket连接的关系,被面试官追问至卡壳

二、高频面试题解剖

核心知识地图(附面试权重)

2.1 基础概念(权重30%)

  • 面试高频题
    UDP vs TCP的区别?(阿里必问)
    满分答案

// 用类对比记忆
class TransportProtocol {
static class TCP {
// 有连接、可靠、复杂
void handshake() {...}
void retransmit() {...}
}
static class UDP {
// 无连接、高效、简单
void send() {...}
}
}

基础三连击

题目‌:

  • BIO/NIO/AIO的区别是什么?

        BIO、NIO和AIO是Java中三种不同的I/O模型,主要区别在于阻塞方式、并发处理机制和适用场景‌。以下是详细对比:

1. BIO(同步阻塞I/O)

  • 特点‌:每个连接对应一个独立线程,数据未就绪时线程会阻塞等待‌。
  • 缺点‌:高并发时线程资源消耗大,易导致性能瓶颈‌。
  • 适用场景‌:低并发、短连接场景(如小型服务)‌。

2. NIO(同步非阻塞I/O)

  • 特点‌:基于事件驱动,通过Selector单线程轮询多通道状态‌。
  • 核心组件‌:Channel/Buffer/Selector,支持多路复用(如epoll)‌。
  • 优势‌:高并发下资源利用率高,适合长连接(如聊天服务器)‌。

3. AIO(异步非阻塞I/O)

  • 特点‌:操作系统完成I/O后回调通知,实现真正的异步‌。
  • 实现‌:基于Proactor模式,使用CompletionHandler处理结果‌。
  • 局限‌:JDK实现未充分适配各平台,多用于文件操作‌。

总结对比

模型阻塞方式并发能力典型场景
BIO同步阻塞低(线程数限制)简单应用、短连接
NIO同步非阻塞高(多路复用)高并发网络服务
AIO异步非阻塞最高(内核异步)文件操作、长连接

性能建议:短连接可选BIO,长连接高并发优先NIO/AIO‌。

  • 如果客户端连接数暴增,如何优化?

        当面临客户端连接数暴增的情况时,需要从多个层面进行优化,包括服务器配置、数据库连接管理、负载均衡策略以及连接管理机制等。以下是详细的优化方案:

一、连接数暴增原因分析

  1. 数据库连接泄漏‌:应用程序未正确关闭连接,导致连接池中连接耗尽
  2. 高并发访问‌:短时间内大量并发请求导致连接数激增
  3. 长时间占用连接‌:查询或事务操作时间过长,占用连接资源
  4. TCP连接TIME_WAIT状态过多‌:导致端口耗尽,无法建立新连接

二、服务器软件优化

Nginx优化

  • 调整worker_processes为CPU核数或倍数
  • 设置worker_rlimit_nofile与系统最大打开文件数一致
  • 使用epoll I/O模型处理异步事件
  • 合理设置worker_connections(建议65535)
  • 调整keepalive_timeout(建议60秒)

Apache优化

  • 根据MPM模块调整参数:
    • prefork模式:调整StartServers、MinSpareServers、MaxRequestWorkers
    • worker/event模式:调整ThreadsPerChild、MaxRequestWorkers
  • 启用keepalive并合理配置keepalivetimeout(1-3秒)
  • 使用event MPM提升并发性能

Tomcat优化

  • 设置maxThreads(建议300)和minSpareThreads(建议50)
  • 调整acceptCount(建议100)等待队列大小
  • 设置maxConnections(建议10000)最大连接数
  • 配置JVM内存参数(-Xms1024m -Xmx4096m)

三、数据库连接池优化

  1. 连接池参数调优‌:

    • 初始连接数(initialSize):建议CPU核心数的一半
    • 最小空闲连接数(minIdle):建议CPU核心数×1.5
    • 最大连接数(maxActive):根据业务并发量设置
  2. 连接泄漏检测‌:

    • 设置removeAbandonedTimeout检测未关闭连接
    • 启用testOnBorrow验证连接有效性
  3. 连接超时设置‌:

    • 合理设置maxWait(获取连接最大等待时间)
    • 设置validationQuery验证SQL

四、负载均衡与水平扩展

  1. 负载均衡策略‌:

    • 使用Nginx/Haproxy等负载均衡器分发请求
    • 采用轮询、最少连接或IP哈希等算法
  2. 水平扩展方案‌:

    • 增加服务器节点分担连接压力
    • 数据库读写分离或分库分表
    • 使用缓存(Redis/Memcached)减轻数据库压力

五、连接管理优化

  1. 连接超时设置‌:

    • 合理设置连接超时时间(5-10秒)
    • 调整socketTimeout避免长时间占用
  2. 心跳机制‌:

    • 设置心跳间隔(30-60秒)检测连接状态
    • 超时阈值设为心跳间隔的3倍
    • 实现断线重连机制
  3. TCP参数优化‌:

    • 调整tcp_tw_reuse重用TIME_WAIT连接
    • 增加系统文件描述符限制
    • 优化内核TCP参数(如tcp_max_syn_backlog)

2.2 实战代码(权重50%)

真题1:

实现心跳包检测(含异常处理)

// 面试加分写法
public class Heartbeat {
private static final long TIMEOUT = 5000;
public void monitor(Socket socket) {
try { socket.setSoTimeout((int)TIMEOUT);
while(!socket.isClosed()) {
if(!socket.isConnected()) {
throw new SocketException("Heartbeat timeout");
}
Thread.sleep(TIMEOUT);
}
} catch (IOException | InterruptedException e) {
// 面试重点:要区分异常类型
System.err.println("Monitor error: " + e.getClass().getSimpleName());
}
}
}

真题2:

用NIO实现万人聊天室

// 面试官最看重的设计
public class ChatRoom {
private Selector selector;
public void start(int port) throws IOException {
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress(port));
server.configureBlocking(false);
selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
// 核心事件循环(面试要能画流程图)
while(running) {
int ready = selector.select();
for(SelectionKey key : selector.selectedKeys()) {
if(key.isAcceptable()) handleAccept(key);
else if(key.isReadable()) handleRead(key);
}
}
}
}

    2. ‌进阶陷阱题

    题目‌:

    • 如何防止Socket连接中的粘包问题?

    在Java中防止Socket连接中的粘包问题,主要通过以下几种核心方案实现:

    消息头+消息体方案

            最推荐的方式是在消息前添加固定长度的消息头,其中包含消息体的长度信息。接收方先读取消息头获取长度,再按长度读取完整消息体。这种方式既灵活又高效,能准确界定数据边界。示例实现包含:

    1. 发送方将消息长度转换为4字节头部前缀
    2. 接收方先读取4字节头部,再按长度读取后续数据
    3. 使用ByteBuffer处理二进制数据转换

    分隔符方案

            通过特殊字符(如换行符\n)标记消息边界,适用于文本协议。需确保分隔符不会出现在正常消息内容中,否则需进行转义处理。典型实现包括:

    1. 使用BufferedReader的readLine()方法按行读取
    2. 自定义分隔符如##END##等特殊标记
    3. 需处理字符编码转换问题

    定长消息方案

            固定每条消息的字节长度,不足部分用填充字符补全。虽然实现简单,但会浪费带宽且灵活性较差。适用于对实时性要求高但数据格式固定的场景。

    协议层优化

            在应用层协议设计时需明确数据边界规则,常见组合方案包括:

    1. 消息头包含长度字段+消息体内容
    2. 采用TLV(Type-Length-Value)格式编码
    3. 使用序列化框架自动处理边界(如Protobuf)

    以下是一个采用消息头方案的完整示例实现:

    import java.io.*;
    import java.net.Socket;
    public class MessageProtocol {
    // 将int转为4字节数组
    private static byte[] intToBytes(int value) {
    return new byte[] {
    (byte)(value >>> 24),
    (byte)(value >>> 16),
    (byte)(value >>> 8),
    (byte)value};
    }
    // 将4字节数组转为int
    private static int bytesToInt(byte[] bytes) {
    return ((bytes[0] & 0xFF) << 24) |
    ((bytes[1] & 0xFF) << 16) |
    ((bytes[2] & 0xFF) << 8)  |
    (bytes[3] & 0xFF);
    }
    // 发送带长度头的消息
    public static void sendMessage(Socket socket, String message) throws IOException {
    byte[] content = message.getBytes("UTF-8");
    byte[] lengthHeader = intToBytes(content.length);
    OutputStream out = socket.getOutputStream();
    out.write(lengthHeader);
    out.write(content);
    out.flush();
    }
    // 接收带长度头的消息
    public static String receiveMessage(Socket socket) throws IOException {
    InputStream in = socket.getInputStream();
    byte[] lengthBytes = new byte[4];
    in.read(lengthBytes);
    int length = bytesToInt(lengthBytes);
    byte[] content = new byte[length];
    int read = 0;
    while (read < length) {
    read += in.read(content, read, length - read);
    }
    return new String(content, "UTF-8");
    }
    }

    该代码实现了基于长度头部的消息协议,包含:

    1. int与字节数组的转换方法
    2. 发送时自动添加4字节长度头
    3. 接收时先读长度头再读取完整消息体
    4. 支持UTF-8编码的文本消息传输

    实际应用中还需考虑网络异常处理、缓冲区大小限制以及心跳机制等增强措施。对于高性能场景,建议使用Netty等框架内置的编解码器处理粘包问题。

    • 半包处理有哪些解决方案?

    在Java中处理Socket通信时的半包问题,主要有以下几种解决方案:

    定长协议方案

    通过固定每个数据包的长度来处理半包问题,不足部分用填充字符补全。这种方式实现简单,但灵活性较差且可能浪费带宽。典型实现包括:

    1. 发送方固定每个消息为1024字节
    2. 接收方按固定长度读取数据
    3. 需处理填充字符的去除逻辑

    分隔符方案

    使用特殊字符(如换行符\n)作为消息边界标记。接收方通过识别分隔符来拆分数据流,适用于文本协议场景。关键实现要点:

    1. 选择不会出现在正常数据中的分隔符
    2. 使用BufferedReader.readLine()处理文本流
    3. 需考虑字符编码转换问题

    消息头+消息体方案

    最推荐的方案是在数据前添加包含长度信息的消息头。接收方先读取固定长度的头部获取消息体大小,再读取完整数据包。核心优势包括:

    1. 灵活适应不同长度的消息
    2. 准确界定数据边界
    3. 支持二进制协议
      典型实现采用4字节头部存储消息长度,如:
    // 发送方写入长度头和数据体
    byte[] data = message.getBytes();
    out.writeInt(data.length);
    out.write(data);

    高级编解码器方案

    使用Netty等框架内置的处理器自动处理半包问题,主要包括:

    1. LineBasedFrameDecoder:基于换行符的解码器
    2. LengthFieldBasedFrameDecoder:基于长度字段的解码器
    3. DelimiterBasedFrameDecoder:支持自定义分隔符
      这些解码器能自动处理TCP流的分帧问题,大幅降低开发复杂度。

    二进制协议方案

    采用Protobuf等序列化框架时,其内置的Varint32编码能自动处理消息边界,通过前缀长度标识实现数据包分割。特点包括:

    1. 自动化的长度编码
    2. 跨语言支持
    3. 高效的空间利用率

    实际选择方案时需考虑协议复杂度、性能要求和开发成本。对于高性能场景,推荐结合Netty和LengthFieldBasedFrameDecoder实现;而对简单文本协议,分隔符方案更为轻量。

    实战技巧‌:

    • 定长协议‌:每个消息固定长度(如1024字节)
    • 分隔符协议‌:用特殊字符(如\n)分割消息
    • 长度头协议‌:消息前4字节存储数据长度

    面试官最爱的“陷阱题”

    3.1 经典陷阱

    TCP四次挥手时,为什么TIME_WAIT要等2MSL?
    反向回答技巧
    “这个问题其实考察网络可靠性设计。2MSL的等待时间主要解决两个问题:一是确保最后一个ACK到达,二是防止旧报文干扰新连接。不过实际开发中,我们可以通过SO_REUSEADDR优化端口占用问题...”

    3.2 压力测试

    某面试官反馈:“要求现场用Socket实现HTTP请求的候选人,80%卡在Content-Length处理”。建议提前练习:

    // 易错点:多线程安全
    public String fetch(String url) {
    try(Socket socket = new Socket(url, 80)) {
    OutputStream os = socket.getOutputStream();
    os.write(("GET / HTTP/1.1\r\nHost: " + url + "\r\n\r\n").getBytes());
    // 面试加分:用Buffer处理二进制数据
    ByteArrayBuffer buf = new ByteArrayBuffer(1024);
    InputStream is = socket.getInputStream();
    while(is.read(buf) != -1) {}
    return buf.toString(StandardCharsets.UTF_8);
    }
    }

    三、避坑指南

    1. 资源泄漏‌:忘记关闭Socket或流会导致端口耗尽
    2. 线程滥用‌:每连接一线程的BIO模型在万人并发时直接崩溃
    3. 测试顺序‌:务必先启动服务端再启动客户端

    通关装备清单

    1. 必刷题库

      • 美团《Socket性能调优手册》

      • 阿里《网络协议白皮书》

    2. 模拟面试
      建议用mvn dependency:tree分析项目依赖时,同步练习Socket相关命令:

      netstat -anp | grep 8080 # 检查端口占用

      tcpdump -i eth0 port 443 # 抓包分析

    四、终极武器:Netty降维打击

    当面试官要求实现高性能Socket时,抛出Netty框架可大幅加分:

    • 基于NIO的异步非阻塞模型
    • 内置编解码器解决粘包问题
    • 事件驱动架构轻松应对10万级连接

    面试话术‌:虽然原生Socket能实现基础功能,但在实际项目中,Netty的ChannelHandler设计让我们能更优雅地处理网络异常和业务逻辑

            Netty是一个基于Java NIO的高性能异步事件驱动网络应用框架,主要用于快速开发可维护的高负载网络服务器和客户端程序。其核心设计目标包括高性能、模块化和安全性,通过零拷贝、内存池等技术减少资源消耗,并内置SSL/TLS支持。

    核心特性

    1. 异步非阻塞架构‌:采用事件驱动模型处理I/O操作,避免线程阻塞,支持高并发连接。
    2. 统一API‌:支持多种传输类型(如OIO、NIO)和协议(HTTP、TCP/UDP),简化多协议开发。
    3. 高性能优化‌:通过内存池、零拷贝技术降低延迟,提升吞吐量,资源消耗少于原生Java NIO。
    4. 健壮性‌:自动处理TCP粘包/分包,提供心跳检测和重连机制,避免NIO的常见陷阱(如epoll空轮询)。

    核心组件

    • Channel‌:封装Socket连接,支持读写操作。
    • EventLoop‌:事件循环线程,处理I/O事件和任务调度。
    • Bootstrap‌:配置服务端/客户端的启动参数。
    • ChannelHandler‌:业务逻辑处理链,通过Pipeline组织编解码器和业务处理器。

    与传统Socket对比

    • 开发效率‌:Netty简化了NIO的复杂API(如Selector、ByteBuffer),减少样板代码。
    • 可靠性‌:内置连接管理、异常处理等机制,而传统Socket需手动实现。
    • 性能‌:Netty的Reactor线程模型和内存优化显著优于同步阻塞IO。

    典型应用场景

    • 分布式系统通信(如Dubbo、Kafka)。
    • 游戏服务器、实时消息推送。
    • HTTP/WebSocket服务。

    五、模拟面试现场

    Socket面试终极挑战:断点续传协议设计

    题目背景
    设计一个支持断点续传的文件传输协议,要求:

    • 用Socket实现分块传输
    • 客户端崩溃后能自动续传
    • 包含CRC校验

    核心考点解析

    1. 分块传输机制

      // 文件分块处理示例
      public class FileChunk {
      private static final int CHUNK_SIZE = 1024 * 8; // 8KB/块
      private byte[] data;
      private int offset;
      private int sequenceId;
      public void send(OutputStream os) throws IOException {
      os.write(sequenceId); // 发送块序号
      os.write(data, offset, CHUNK_SIZE); // 发送数据
      }
      }

    2. 断点续传实现

      // 服务器端记录已接收块
      public class ResumeManager {
      private Map receivedChunks = new ConcurrentHashMap<>();
      public boolean isReceived(int chunkId) {
      return receivedChunks.getOrDefault(chunkId, false);
      }
      }
    3. CRC校验保障

      // 校验算法实现
      public class CRC32 {
      public static int calculate(byte[] data) {
      return (int) java.util.zip.CRC32.crc32(data);
      }
      }

    完整解决方案框架

    // 客户端伪代码
    public class FileTransferClient {
    public void upload(String filePath) {
    File file = new File(filePath);
    try (Socket socket = new Socket("server", 8080)) {
    OutputStream os = socket.getOutputStream();
    ResumeManager manager = new ResumeManager();
    for (int i = 0; i < file.length(); i += CHUNK_SIZE) {
    if (!manager.isReceived(i / CHUNK_SIZE)) {
    FileChunk chunk = new FileChunk(file, i);
    os.write(chunk.getData());
    os.write(CRC32.calculate(chunk.getData()));
    }
    }
    }
    }
    }

    面试加分点

    1. 异常处理‌:需处理网络中断、校验失败等场景

    2. 性能优化‌:建议使用NIO实现非阻塞传输

    3. 协议设计‌:可扩展支持多线程并发传输


    多线程并发聊天服务器设计

    Socket面试题:多客户端聊天服务器实现

    题目要求‌:
    设计一个基于Socket的多客户端聊天服务器,要求:

    • 支持多客户端同时连接
    • 实现消息广播功能(一个客户端发送的消息传递给所有其他客户端)
    • 客户端可以设置用户名
    • 服务器记录连接日志
    • 包含异常处理和资源清理

    核心考点解析

    1. 多线程服务器架构

    // 主服务器线程处理新连接的客户端
    public class ChatServer {
    private static final int PORT = 8080;
    private static final Set clients = new HashSet<>();
    private static final ExecutorService pool = Executors.newCachedThreadPool();
    public static void main(String[] args) throws IOException {
    ServerSocket serverSocket = new ServerSocket(PORT);
    System.out.println("聊天服务器已启动,端口:" + PORT);
    while (true) {
    Socket clientSocket = serverSocket.accept();
    ClientHandler clientThread = new ClientHandler(clientSocket, clients);
    clients.add(clientThread);
    pool.execute(clientThread);
    }
    }
    }

    2. 客户端处理器设计

    public class ClientHandler implements Runnable {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;
    private String username;
    private Set clients;
    public ClientHandler(Socket socket, Set clients) {
    this.socket = socket;
    this.clients = clients;
    }
    @Override
    public void run() {
    try {
    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    out = new PrintWriter(socket.getOutputStream(), true);
    // 获取用户名
    out.println("请输入用户名:");
    username = in.readLine();
    broadcast(username + " 加入了聊天室");
    String message;
    while ((message = in.readLine()) != null) {
    if (message.equalsIgnoreCase("/exit")) {
    break;
    }
    broadcast(username + ": " + message);
    }
    } catch (IOException e) {
    System.err.println("客户端连接错误: " + e.getMessage());
    } finally {
    cleanup();
    }
    }
    private void broadcast(String message) {
    for (ClientHandler client : clients) {
    if (client != this) {
    client.sendMessage(message);
    }
    }
    }
    public void sendMessage(String message) {
    out.println(message);
    }
    private void cleanup() {
    try {
    clients.remove(this);
    broadcast(username + " 离开了聊天室");
    if (in != null) in.close();
    if (out != null) out.close();
    if (socket != null) socket.close();
    } catch (IOException e) {
    System.err.println("清理资源错误: " + e.getMessage());
    }
    }
    }

    3. 客户端实现

    public class ChatClient {
    public static void main(String[] args) {
    try (Socket socket = new Socket("localhost", 8080);
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    Scanner scanner = new Scanner(System.in)) {
    // 启动消息接收线程
    new Thread(() -> {
    try {
    String serverMessage;
    while ((serverMessage = in.readLine()) != null) {
    System.out.println(serverMessage);
    }
    } catch (IOException e) {
    System.out.println("与服务器断开连接");
    }
    }).start();
    // 处理用户输入
    String userInput;
    while (true) {
    userInput = scanner.nextLine();
    if (userInput.equalsIgnoreCase("/exit")) {
    out.println("/exit");
    break;
    }
    out.println(userInput);
    }
    } catch (IOException e) {
    System.err.println("客户端错误: " + e.getMessage());
    }
    }
    }

    解决方案框架

    A[聊天服务器] --> B[监听端口 8080]
    B --> C[接受新连接]
    C --> D[创建ClientHandler线程]
    D --> E{是否有消息}
    E --> |是| F[广播消息给所有客户端]
    E --> |否| G[等待消息]
    F --> E
    G --> E

    面试加分点

    1. 线程安全处理‌:

      // 使用Collections.synchronizedSet包装客户端集合
      private static final Set clients =
      Collections.synchronizedSet(new HashSet<>());
    2. 心跳检测机制‌:

      // 定时发送心跳包验证连接
      private void startHeartbeat() {
      new Timer().scheduleAtFixedRate(new TimerTask() {
      @Override
      public void run() {
      try {
      out.println("HEARTBEAT");
      } catch (Exception e) {
      cleanup();
      this.cancel();
      }
      }
      }, 0, 30000); // 每30秒发送一次心跳
      }
    3. 消息格式扩展‌:

      {
      "username": "Alice",
      "timestamp": "2025-09-19T10:00:00Z",
      "content": "Hello everyone!",
      "type": "MESSAGE" // HEARTBEAT, JOIN, LEAVE, COMMAND
      }
    4. 非阻塞NIO实现‌:

      // 使用Java NIO实现高性能服务器
      Selector selector = Selector.open();
      ServerSocketChannel serverSocket = ServerSocketChannel.open();
      serverSocket.bind(new InetSocketAddress(PORT));
      serverSocket.configureBlocking(false);
      serverSocket.register(selector, SelectionKey.OP_ACCEPT);

    测试方法

    1. 启动服务器:

      java ChatServer

    2. 启动多个客户端:

      java ChatClient

    3. 测试功能:

      • 用户加入/离开通知
      • 消息广播功能
      • 异常断开处理
      • 用户名设置
      • /exit退出命令

    这个题目全面考察Socket编程、多线程处理、异常管理和协议设计能力,非常适合中级Java开发岗位的面试。


    六、彩蛋——壁纸特辑:让热血永驻屏幕

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

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

    相关文章

    C# 第 17天 028 029接口,依赖反转,单元测试

    胖接口:多要显示接口实现(C#语言独有的功能)

    详细介绍:Linux驱动开发笔记(七)——并发与竞争(下)——自旋锁信号量互斥体

    pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

    2025年项目管理软件革命:AI与空间计算如何重塑企业协作范式

    2025年项目管理软件革命:AI与空间计算如何重塑企业协作范式 全球项目管理软件市场正在经历一场由多重技术叠加驱动的深度变革。根据Gartner最新预测,到2025年,75%的企业将采用至少一种具备AI决策能力的项目管理工具…

    Threading 串行VS并发

    Threading 串行VS并发 IO 密集型 结果 >>> 串行开始... 下载https://www.baidu.com/成功,状态码为200 下载https://www.sina.com.cn/成功,状态码为200 下载https://www.bilibili.com/成功,状态码为412 耗时…

    parallel index

    select * from tablename tb为提高查询效率,可使用一下方法:(1)并行查询:/*+ parallel(tb,32) * / select /*+ parallel(tb,32) */ count(*) from leo1 tb; (2)强制走索引:/*+ index(tb, indexname) */ …

    C语言 第三讲:分支和循环(上) - 教程

    C语言 第三讲:分支和循环(上) - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mo…

    群晖安装套件,套件版本与群晖版本不兼容;

    群晖安装套件,套件版本与群晖版本不兼容;以SurveillanceStation9.1.2为例 若遇到最新版群晖系统提示“与您的Synology NAS不兼容,请上传9.2.1-11320或以上版本”导致无法安装,请执行以下代码,通过SSH或者计划任务…

    中间件专题:Redis

    1. Redis 数据结构 # String set `key` `value` setnx `key` `value` # 不存在才set setex `key` `value` `ttl` incrby `key` `increment` # 自增# Hash 哈希表 hset `key` `field` `value` `field` `value` hget `ke…

    Vue3 新趋势:弃用 ECharts!最强图表库诞生!

    Vue3 新趋势:弃用 ECharts!最强图表库诞生!原文链接:https://mp.weixin.qq.com/s/hE7XmPjSOGpD6EYQCKSpkw在前端开发领域,数据可视化已然成为不可或缺的一环。 目前市面上主流的图表库诸如 ECharts、AntV 等,虽然…

    群晖安装套件跳过版本检查

    群晖安装套件跳过版本检查若遇到最新版群晖系统提示“10854与您的Synology NAS不兼容,请上传9.2.1-11320或以上版本”导致无法安装,请执行以下代码,通过SSH或者计划任务执行均可: cp /etc.defaults/synopackagesli…

    负载排查和分析四

    负载排查和分析四明白,我给你提供完整整合后的最终文档版本,把软/硬中断触发机制、背景、流程、表格全部补充进去,保持原有网络优化、Perf 分析、脚本和流程图不变。Linux 网络优化与性能分析完全指南(最终完整版)…

    微信个人号开发API/文档/教程

    微信个人号开发API/文档/教程 大家一般需求点无非是以下几个需求: 1.开发个人微信营销系统 2.开发自定义的微信机器人, 3.开发微信智能聊天客服系统 4.定制行业内的群数据分析 功能需求很简单,业务代码贼好撸,但是如…

    微指令控制器基本原理

    微指令控制器的基本原理 微命令和微操作一一对应。一个微命令对于一根输出控制线 相容性微命令:可以并行完成的微命令 互斥型微命令:不可以并行完成的微命令 微命令格式 水平型微命令 一条微命令可定义多个可并行的微…

    一个拒绝过度设计的 .NET 快速开发框架:开箱即用,专注干活

    前言 .NET 生态快速发展的背景下,越来越多开发希望找到一个既能快速上手,又不过度设计的后端框架。尤其是在中小型项目中,复杂的架构、层层封装的服务逻辑往往让开发效率大打折扣。 今天推荐一个轻量级、高效实用的…

    lookup-mehtod和replace-method标签的作用

    lookup-mehtod和replace-method标签的作用下面通过一个基于Spring框架的简单示例来解释 lookup - method和 replace - method的作用。 1. 项目准备 首先创建一个Maven项目,添加Spring相关的依赖: <dependencies&g…

    个人微信号二次开发API调用、微信API接口

    个人微信号二次开发API调用、微信API接口微信API接口、微信二次开发API调用微信协议接口调用-加微信好友及通过好友请求发送小程序 请求URL: http://域名地址/sendApplets 请求方式: POST 请求头Headers: Content-T…

    React 学习笔记4 Diffing/脚手架 - 详解

    pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

    2025.9.21+7 [未完]

    2025.9.21 Week 笔记2025.9.22

    VisualStudio-Python-工具指南-全-

    VisualStudio Python 工具指南(全)原文:zh.annas-archive.org/md5/396df14cf233d147d6dfcb4a589a8b75 译者:飞龙 协议:CC BY-NC-SA 4.0前言 和许多其他开发者一样,Python 开发者总是需要找到方法来管理不同工具之…

    深入解析:Spring Boot注解

    深入解析:Spring Boot注解2025-09-22 13:14 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; …