后端开发面经系列 -- 小鹏汽车一面面经

小鹏汽车一面面经

公众号:阿Q技术站

来源:职言详情页 (maimai.cn)

文章目录

  • 小鹏汽车一面面经
      • 1、String类型为什么不可变?
        • 1. 安全性
        • 2. 缓存和性能优化
        • 3. 哈希码缓存
        • 4. 类设计和接口
        • 5. 简单性和可读性
      • 2、在浏览器中输入url地址到显示主页的过程?
        • 1. 输入 URL 并解析
        • 2. DNS 解析
        • 3. 建立 TCP 连接
        • 4. 发送 HTTP 请求
        • 5. 服务器处理请求并返回响应
        • 6. 浏览器接收响应并开始渲染
        • 7. 显示主页
      • 3、为什么要三次握手?二次握手或者四次握手会怎么样?
          • 三次握手
        • 为什么需要三次握手?
        • 二次握手的问题
        • 四次握手的问题
      • 4、日常开发中用过哪些设计模式,具体的应用场景是什么?
      • 5、 redis 的并发竞争 Key 问题?
        • 1. 使用 Redis 事务
        • 2. 使用 Lua 脚本
        • 3. 使用分布式锁
        • 4. 使用 Redis 乐观锁
      • 6、redis 常见数据结构以及使用场景分析?
        • 1. 字符串(String)
        • 2. 列表(List)
        • 3. 集合(Set)
        • 4. 有序集合(Sorted Set)
        • 5. 哈希表(Hash)
        • 使用场景分析
      • 7、redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)?
        • RDB 持久化
          • RDB 的优点:
          • RDB 的缺点:
        • AOF 持久化
          • AOF 的优点:
          • AOF 的缺点:
        • 选择持久化机制
      • 8、如何理解事务?如何理解事务的隔离等级?
        • 事务的特性(ACID)
        • 事务的隔离级别
      • 9、binlog、undelog、redolog的区别是什么?为什么不推荐使用长事务?
        • 1. binlog(二进制日志)
        • 2. undolog(回滚日志)
        • 3. redo log(重做日志)
        • 不推荐使用长事务的原因
      • 10、算法题:如何判断链表中存在环?
        • 思路
        • 参考代码
          • Java

小鹏汽车面经

1、String类型为什么不可变?

1. 安全性

不可变对象是线程安全的,因为它们的状态在创建之后无法更改。多线程环境中,不需要对不可变对象进行同步处理,可以避免线程安全问题。例如,多个线程可以安全地共享和使用同一个 String 对象而不需要同步。

2. 缓存和性能优化

由于 String 对象不可变,它们可以被安全地缓存。例如,字符串常量池(String Pool)利用了不可变性的特性,通过缓存相同的字符串对象来减少内存开销和提高性能。在 Java 中,当创建一个字符串字面量时,JVM 会先检查字符串池中是否已经存在相同的字符串,如果存在则直接返回该对象的引用,否则创建新的字符串对象并放入池中。

3. 哈希码缓存

不可变对象的哈希码在对象创建时计算,并且在整个生命周期中不变。因此,不可变对象可以安全地缓存哈希码,提高哈希表(如 HashMap)的性能。对于可变对象,每次哈希码计算都可能不同,不能进行这种优化。

4. 类设计和接口

不可变对象可以被安全地传递、共享和缓存,而无需担心对象的状态会被外部修改。这使得不可变对象在设计类和接口时更容易使用。例如,String 类型可以作为安全的键(key)用于哈希表(如 HashMap)中。

5. 简单性和可读性

不可变对象的行为是确定的、可预测的。这简化了代码的理解和维护,因为开发人员可以放心对象的状态不会在不可预见的地方被修改。

2、在浏览器中输入url地址到显示主页的过程?

1. 输入 URL 并解析

当用户在浏览器的地址栏中输入 URL(如 http://www.xxx.com)并按下回车键时,浏览器开始处理该请求。

2. DNS 解析

浏览器首先需要将域名(如 www.example.com)解析为 IP 地址。这个过程包括以下步骤:

  • 浏览器查找 DNS 缓存,看看是否已经缓存了该域名的 IP 地址。
  • 如果浏览器缓存中没有找到,操作系统会查找其本地 DNS 缓存。
  • 如果操作系统缓存中也没有找到,操作系统会向配置的 DNS 服务器发送查询请求。
  • DNS 服务器查询解析链路,最终将域名解析为 IP 地址,并返回给操作系统。
  • 操作系统将 IP 地址返回给浏览器。
3. 建立 TCP 连接

有了 IP 地址后,浏览器与服务器建立 TCP 连接。这个过程包括三次握手(Three-way handshake):

  1. 浏览器发送一个 SYN 包(同步序列编号)到服务器。
  2. 服务器响应一个 SYN-ACK 包(同步确认)。
  3. 浏览器发送一个 ACK 包(确认),TCP 连接建立。
4. 发送 HTTP 请求

TCP 连接建立后,浏览器会向服务器发送一个 HTTP 请求。

5. 服务器处理请求并返回响应

服务器接收到请求后,处理请求,生成响应内容,并返回给浏览器。响应内容包括 HTTP 状态码、响应头和响应主体。

6. 浏览器接收响应并开始渲染

浏览器接收 HTTP 响应后,开始渲染页面。这个过程包括以下步骤:

  1. 解析 HTML:浏览器解析 HTML 内容,构建 DOM 树。
  2. 解析 CSS:如果 HTML 中包含 CSS 文件或内嵌样式,浏览器会解析 CSS 内容,构建 CSSOM 树(CSS 对象模型)。
  3. 解析 JavaScript:如果 HTML 中包含 JavaScript 文件或内嵌脚本,浏览器会解析并执行 JavaScript 代码,可能会修改 DOM 树或 CSSOM 树。
  4. 构建渲染树:根据 DOM 树和 CSSOM 树,浏览器构建渲染树(Render Tree),这是一种表示页面布局和样式的内部表示。
  5. 布局(Layout):根据渲染树计算每个节点在屏幕上的位置和大小。这一步称为布局或回流(Reflow)。
  6. 绘制(Painting):将渲染树的每个节点绘制到屏幕上,这一步称为绘制或重绘(Repaint)。
7. 显示主页

经过上述步骤后,浏览器将渲染的页面内容显示给用户,用户可以看到主页。

3、为什么要三次握手?二次握手或者四次握手会怎么样?

三次握手

三次握手

在建立连接之前,Client处于CLOSED状态,而Server处于LISTEN的状态。

  1. 第一次握手(SYN-1):
    • 客户端发送一个带有 SYN 标志的 TCP 报文段给服务器,表示客户端请求建立连接。
    • 客户端选择一个初始序列号(ISN)并将其放入报文段中,进入 SYN_SENT 状态。
  2. 第二次握手(SYN + ACK):
    • 服务器收到客户端发送的 SYN 报文段后,如果同意建立连接,会发送一个带有 SYN 和 ACK 标志的报文段给客户端,表示服务器接受了客户端的请求,并带上自己的 ISN。
    • 服务器进入 SYN_RCVD 状态。
  3. 第三次握手(ACK):
    • 客户端收到服务器发送的 SYN+ACK 报文段后,会发送一个带有 ACK 标志的报文段给服务器,表示客户端确认了服务器的响应。
    • 客户端和服务器都进入 ESTABLISHED 状态,连接建立成功,可以开始进行数据传输。
为什么需要三次握手?
  1. 确保双方都能发送和接收数据
    • 第一次握手确认客户端的发送能力和服务器的接收能力。
    • 第二次握手确认服务器的发送能力和客户端的接收能力。
    • 第三次握手确认客户端的发送能力和服务器的接收能力。
  2. 防止旧的连接请求误导双方
    • 通过三次握手,双方都能确认对方的状态是最新的,有效避免了网络中的旧的、延迟的SYN包造成的错误连接。
  3. 防止重复数据包干扰
    • 三次握手确保双方都能有效处理重复的数据包,并建立一个唯一的连接。
二次握手的问题

如果采用二次握手(即省略第三次握手),可能会导致以下问题:

  1. 旧的重复连接请求:旧的 SYN 包在网络中延迟传输,服务器可能误认为是新的连接请求,发送 SYN-ACK 包,但客户端不知道这个连接,可能导致连接建立异常。
  2. 无法确认客户端的接收能力:服务器在发送 SYN-ACK 包后,不知道客户端是否已成功收到,如果客户端未收到,服务器会一直等待 ACK 包,导致资源浪费。
四次握手的问题

如果采用四次握手(即增加额外的确认步骤),虽然能增加连接建立的可靠性,但也会带来额外的开销和复杂性,增加连接建立的延迟。TCP 设计中,三次握手已经足够确保连接的可靠性和双方通信的能力,再增加步骤则显得不必要且低效。

4、日常开发中用过哪些设计模式,具体的应用场景是什么?

5、 redis 的并发竞争 Key 问题?

Redis 在高并发场景下并发竞争 Key 通常发生在多个客户端同时对同一个 Key 进行读写操作时,可能会导致数据不一致或竞争条件。

1. 使用 Redis 事务

Redis 事务可以确保一系列命令按顺序执行,避免并发插入。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class RedisTransactionExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        try {
            // 开启事务
            Transaction transaction = jedis.multi();
            transaction.set("key1", "value1");
            transaction.incr("key2");

            // 提交事务
            transaction.exec();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }
    }
}
2. 使用 Lua 脚本

Lua 脚本可以确保在服务器端原子性地执行一系列操作。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;

public class RedisLuaScriptExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        String luaScript = 
            "local current = redis.call('GET', KEYS[1]) " +
            "if current == ARGV[1] then " +
            "    return redis.call('SET', KEYS[1], ARGV[2]) " +
            "else " +
            "    return nil " +
            "end";

        String result = (String) jedis.eval(luaScript, 1, "key1", "old_value", "new_value");
        if (result == null) {
            System.out.println("Key value mismatch or key does not exist.");
        } else {
            System.out.println("Script executed successfully.");
        }
        jedis.close();
    }
}
3. 使用分布式锁

可以使用分布式锁来避免并发竞争。Redisson 是一个 Redis 客户端,可以用于实现分布式锁。

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

import java.util.concurrent.TimeUnit;

public class RedisDistributedLockExample {
    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379");
        RedissonClient redisson = Redisson.create(config);

        RLock lock = redisson.getLock("myLock");

        try {
            // 尝试获取锁,等待时间为 10 秒,锁超时时间为 10 秒
            if (lock.tryLock(10, 10, TimeUnit.SECONDS)) {
                try {
                    // 加锁成功,执行相关业务逻辑
                    System.out.println("Lock acquired.");
                } finally {
                    // 释放锁
                    lock.unlock();
                }
            } else {
                System.out.println("Failed to acquire lock.");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            redisson.shutdown();
        }
    }
}
4. 使用 Redis 乐观锁

Redis 的 WATCH 命令可以用来实现乐观锁,监视一个或多个 Key,在事务执行前检查这些 Key 是否被修改。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class RedisOptimisticLockExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        while (true) {
            jedis.watch("key1");
            int value = Integer.parseInt(jedis.get("key1"));

            Transaction transaction = jedis.multi();
            transaction.set("key1", String.valueOf(value + 1));

            if (transaction.exec() != null) {
                break;
            }
        }
        jedis.close();
    }
}

6、redis 常见数据结构以及使用场景分析?

1. 字符串(String)
  • 使用场景:存储单个值,如用户信息、计数器等。
  • 示例命令:SET、GET、INCR、DECR。
SET user:1 "{name: 'Alice', age: 30}"
GET user:1
INCR counter
2. 列表(List)
  • 使用场景:存储有序的字符串列表,如消息队列、最新消息列表等。
  • 示例命令:LPUSH、RPUSH、LPOP、RPOP、LRANGE。
LPUSH messages "Hello"
RPUSH messages "World"
LPOP messages
LRANGE messages 0 -1
3. 集合(Set)
  • 使用场景:存储无序的唯一元素,如标签、好友列表等。
  • 示例命令:SADD、SREM、SMEMBERS、SISMEMBER。
SADD tags "redis"
SADD tags "database"
SMEMBERS tags
SISMEMBER tags "redis"
4. 有序集合(Sorted Set)
  • 使用场景:存储有序的唯一元素,每个元素都关联一个分数,常用于排行榜、计分系统等。
  • 示例命令:ZADD、ZRANGE、ZREVRANGE、ZSCORE。
ZADD leaderboard 100 "Alice"
ZADD leaderboard 200 "Bob"
ZRANGE leaderboard 0 -1 WITHSCORES
ZREVRANGE leaderboard 0 -1 WITHSCORES
5. 哈希表(Hash)
  • 使用场景:存储对象的字段和值,如存储用户对象、文章对象等。
  • 示例命令:HSET、HGET、HMSET、HGETALL。
HSET user:1 name "Alice"
HSET user:1 age 30
HMSET user:2 name "Bob" age 25
HGET user:1 name
HGETALL user:1
使用场景分析
  • 缓存:使用字符串存储缓存数据,列表存储消息队列,集合存储用户标签等。
  • 计数器:使用字符串的 INCR 命令实现计数器功能。
  • 会话管理:使用哈希表存储用户会话信息,如用户登录状态、权限等。
  • 发布订阅:使用发布订阅功能实现消息广播。
  • 排行榜:使用有序集合存储用户分数,实现排行榜功能。
  • 实时统计:使用计数器、有序集合等数据结构实现实时统计功能。

7、redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)?

RDB 持久化

RDB 持久化是通过将 Redis 在内存中的数据以快照的形式写入到硬盘的一个文件中。RDB 持久化可以手动执行,也可以通过配置自动执行。当 Redis 需要持久化数据时,它会 fork 出一个子进程来处理持久化工作,父进程继续处理客户端请求。

RDB 的优点:
  • RDB 文件是一个紧凑的二进制文件,适合用于备份和恢复数据。
  • RDB 持久化对 Redis 的性能影响较小,因为持久化过程由子进程完成,不会阻塞主进程处理客户端请求。
RDB 的缺点:
  • 如果 Redis 挂掉时还没有执行 RDB 持久化,会丢失最后一次持久化后的数据。
  • 执行 RDB 持久化时,会阻塞 Redis 主进程,可能会影响服务的响应速度。
AOF 持久化

AOF 持久化是通过将 Redis 的写操作以追加的方式记录到一个文件中。当 Redis 重启时,会重新执行 AOF 文件中的写操作来恢复数据。AOF 文件中的写操作以 Redis 协议格式保存,方便阅读和恢复。

AOF 的优点:
  • AOF 文件是一个文本文件,可以直接查看和修改,方便调试和恢复。
  • AOF 持久化记录了每次写操作,因此可以尽可能地减少数据丢失的风险。
AOF 的缺点:
  • AOF 文件比 RDB 文件大,恢复速度比 RDB 慢。
  • AOF 持久化对于写密集型工作负载可能会有一定的性能影响。
选择持久化机制
  • 如果对数据的完整性要求很高,可以选择使用 AOF 持久化。
  • 如果对数据的实时性要求较高,可以选择使用 RDB 持久化。
  • 也可以同时开启两种持久化机制,这样可以在 Redis 重启时先使用 AOF 文件恢复数据,然后再使用 RDB 文件进一步恢复数据,以提高数据的完整性和实时性。

8、如何理解事务?如何理解事务的隔离等级?

事务是指一组操作被视为一个不可分割的工作单元,要么全部执行成功,要么全部执行失败。在数据库中,事务是指一系列数据库操作组成的逻辑工作单元,这些操作要么全部执行成功,要么全部不执行,不会出现部分执行成功的情况。

事务的特性(ACID)
  1. 原子性(Atomicity):事务是一个原子操作,要么全部成功,要么全部失败回滚,不会出现部分执行的情况。
  2. 一致性(Consistency):事务执行前后,数据库的状态必须保持一致性,即数据库从一个一致性状态转变到另一个一致性状态。
  3. 隔离性(Isolation):事务的执行不受其他事务的影响,每个事务都感觉不到其他事务同时在执行。
  4. 持久性(Durability):事务一旦提交,其结果就是永久性的,即使系统崩溃,数据库也能够恢复到提交事务后的状态。
事务的隔离级别

事务的隔离级别定义了一个事务内部的操作对其他事务的可见性,以及其他事务对该事务的影响程度。常见的隔离级别有:

  1. 读未提交(Read Uncommitted):事务中的修改,即使没有提交,对其他事务也是可见的。这种隔离级别会导致脏读、不可重复读和幻读的问题。
  2. 读已提交(Read Committed):事务只能看到已经提交的事务所做的修改。这种隔离级别解决了脏读问题,但仍可能出现不可重复读和幻读的问题。
  3. 可重复读(Repeatable Read):事务执行期间看到的数据保持一致,即使其他事务对数据进行了修改,事务也只能看到自己开始前的数据状态。这种隔离级别解决了不可重复读问题,但仍可能出现幻读问题。
  4. 串行化(Serializable):事务顺序执行,事务之间完全隔离,可以避免脏读、不可重复读和幻读的问题,但会降低并发性能。

9、binlog、undelog、redolog的区别是什么?为什么不推荐使用长事务?

1. binlog(二进制日志)
  • 作用:记录对数据库执行的所有更改操作,包括增删改操作,但不包括查询操作。
  • 使用场景:用于数据库的备份、恢复和复制。
  • 优点:可以通过 replay binlog 的方式将主库的操作同步到从库,实现数据的复制和主从架构。
  • 缺点:对于每次操作都会记录一条日志,可能会导致 binlog 文件较大。
2. undolog(回滚日志)
  • 作用:记录事务执行过程中对数据页所做的所有修改,用于事务的回滚操作。
  • 使用场景:用于保证事务的原子性。
  • 优点:可以确保事务执行过程中出现问题时,可以回滚到事务开始前的状态。
  • 缺点:增加了数据库的存储开销。
3. redo log(重做日志)
  • 作用:记录事务对数据库所做的修改,但与 undolog 不同的是,redo log 是物理日志,记录的是数据页的修改操作,而不是逻辑修改。
  • 使用场景:用于保证事务的持久性,即事务提交后,数据的修改是永久性的。
  • 优点:可以确保数据库在崩溃后可以通过重做日志来恢复到事务提交后的状态。
  • 缺点:增加了数据库的 I/O 开销。
不推荐使用长事务的原因
  1. 锁资源:长事务持有的锁资源会导致其他事务无法访问需要的资源,影响数据库的并发性能。
  2. 内存占用:长事务可能导致数据库需要维护的 undo 日志和 redo 日志过大,占用大量内存空间。
  3. 数据一致性:长事务会增加系统发生故障的风险,一旦系统崩溃,长事务可能无法正常提交或回滚,导致数据不一致。

10、算法题:如何判断链表中存在环?

思路
  1. 定义两个指针 slowfast,初始时都指向链表的头节点 head
  2. slow 每次向后移动一个节点,fast 每次向后移动两个节点。这样,如果链表中有环,fast 最终会追上 slow
  3. 如果 fastnullptr 或者 fast->nextnullptr,则说明链表中不存在环,返回 false
  4. 如果 fastslow 相遇,则说明链表中存在环,返回 true
参考代码
Java
class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
        next = null;
    }
}

public class Solution {
    public boolean hasCycle(ListNode head) {
        // 定义快慢指针,并初始化为链表头节点
        ListNode slow = head;
        ListNode fast = head;

        // 使用快慢指针判断链表中是否存在环
        while (fast != null && fast.next != null) {
            slow = slow.next;       // 慢指针每次移动一步
            fast = fast.next.next;  // 快指针每次移动两步
            if (slow == fast) {     // 如果快慢指针相遇,说明存在环
                return true;
            }
        }

        // 如果快指针到达链表尾部,说明不存在环
        return false;
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建一个有环的链表
        ListNode head = new ListNode(3);
        head.next = new ListNode(2);
        head.next.next = new ListNode(0);
        head.next.next.next = new ListNode(-4);
        head.next.next.next.next = head.next; // 尾节点连接到第二个节点,形成环

        Solution sol = new Solution();
        System.out.println(sol.hasCycle(head)); // 输出 true,表示链表中存在环
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文搞懂flex布局

上学读书的时候,学习flex布局,更多停留在理论知识层面。近来,经过工作实践,发现自己对flex布局的理解更加深入,运用起来更加熟练,也越发能感受到flex布局的强大灵活性,特来总结一波。若有错误之…

Linux部署mysql8.0.28数据库

目录 1.基础准备 (1)首先去官网下载二进制安装包 (2)下载好之后上传至服务器 (3)禁用关闭selinux和防火墙 (4)挂载光盘搭建本地yum仓库 2.解压到指定目录 3.检查系统是否安装mariadb 4.安装MySQL数据库 (1)进入MySQL目录 看到‘完毕’就说面mysql已经安装成功了 4.初…

2024-6-12-IXI(mat)应用到SR的代码解读

数据集 Download and decompress data from the link 百度网盘 请输入提取码 Password: qrlt Transform .h5 format to .mat format "python convertH5tomat.py --data_dir XXX/T2Net/h5 论文:Task Transformer Network for Joint MRI Reconstruction and Super-Resoluti…

大数据概论总结

三次信息化浪潮 : 信息技术的支撑 : 存储设备容量不断增加 CPU的处理能力不断提高 网络带宽不断增加 数据产生方式的变革促成大数据时代的来临 运营式系统阶段用户原创内容感知式系统阶段 大数据发展历程 : 分为三个阶段 : 大数据的概念 : 1 . 数据量大 : 根据IDC作出…

量产导入 | Tessent Scan 和 ATPG

目标 Upon completion of this module, you should be able to: Use Tessent Scan to insert full scan. Write a scan-inserted netlist file. Write ATPG setup files. lnsert test logic. Create, configure, and balance scan chains. Edit a scan chain order file and …

PyCharm2018图文安装教程、附录软件下载

软件简介 PyCharm 2018是一款IDE集成开发环境,主要功能包括代码调试、语法高亮、智能提示、单元测试、版本控制等,支持Python 3.7,改进search everywhere功能等,可以让用户快速的开发程序。 软件下载 复制链接浏览器打开 https…

Java基础面试重点-1

0. 符号: *:记忆模糊,验证后特别标注的知识点。 &:容易忘记知识点。 *:重要的知识点。 1. 简述一下Java面向对象的基本特征(四个),以及你自己的应用? 抽象&#…

GStreamer安装——Android

Android安装 支持所有从2.3.1Gingerbread开始的版本 先决条件 开发机器是您开发Android应用程序的地方,然后您将其部署在目标机器上,目标机器显然应该是Android设备。 开发机器可以是Linux、Mac OS X或Windows,并且需要安装: 最…

私有云数据库特征

私有云数据库具有以下几个主要特征: 控制和安全: 数据控制:组织对数据有完全的控制权,可以根据需要设置访问权限和安全策略。安全性:私有云数据库通常部署在组织内部的数据中心,利用内部网络&#xff0c…

爆款AI工具大盘点:最强文本、视频、音乐生成AI,适用岗位全解析!

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

Linux部署项目

手动部署 1.在IDEA写一个有关springboot项目 在windows客户端可以通过localhost:8080/hello 访问 2.用packge 命令将该springboot项目打包 并在target目录下找到打包的jar包 3.上传到linux上 个人习惯在usr/local/app 下上传该项目 创建切换到app目录下 mkdir /usr/local/ap…

互联网医院系统源码的创新应用:预约挂号小程序开发实战

预约挂号小程序作为互联网医院系统的创新应用,更加贴近用户需求,实现了预约挂号的便捷化和智能化。本篇文章,笔者将带领读者进入预约挂号小程序开发的实战过程,探索互联网医院系统源码在小程序开发中的创新应用。 一、互联网医院系…

UML相关1

汽车租赁系统中的用例图简述(10分) 本系统根据功能可以分为三个用例图: 客户用例图:主要描述客户注册、登录、找回密码、查询车辆信息(包括所有车辆信息、已借车辆信息、租赁历史信息)、修改个人信息、网上预订车辆、电话预定车…

java多线程临界区介绍

在Java多线程编程中,"临界区"是指一段必须互斥执行的代码区域。当多个线程访问共享资源时,为了防止数据不一致或逻辑错误,需要确保同一时刻只有一个线程可以进入临界区。Java提供了多种机制来实现这一点,例如synchroniz…

Excel 多列组合内容循环展开

某表格 A 列是编号,其他列是用逗号分隔的意义不同的分类列 ABCDEFG1Assembly#ProductTypeUnit ConfigNominal CapacitySupply VoltageGenerationCase Construction23H1012290001CMD,P24,36FAA,B33H1012290002CMD,P48,60FA,BA,B43H1012290003CMD,P24,36B,C,D,EAA,B …

注册讲堂 | 医疗器械监管的可追溯性与UDI

医疗器械监管的关键-可追溯性 在医疗领域,每一个环节的精准和透明都是至关重要的。医疗器械的可追溯性正是这一需求的核心,它确保了产品从生产到患者使用的整个路径可以被追踪和记录。这不仅关乎患者的安全,也是医疗质量保证的关键。 可追溯…

Python强化学习(Reinforcement Learning, RL)库之gymnasium使用详解

概要 在强化学习(Reinforcement Learning, RL)领域中,环境(Environment)是进行算法训练和测试的关键部分。gymnasium 库是一个广泛使用的工具库,提供了多种标准化的 RL 环境,供研究人员和开发者使用。通过 gymnasium,用户可以方便地创建、管理和使用各种 RL 环境,帮助…

Android native层的线程分析(C++),以及堆栈打印调试

文章目录 Android native层的线程分析(C),多线程实现1.native线程的创建第一部分:android_thread模块第二部分:linux_thread模块 2.测试linux_thread模块3.Android native的Thread类3.1源码分析 4.native层堆栈调试方法 Android native层的线…

postman教程-21-Newman运行集合生成测试报告

上一小节我们Postman Newman的安装方法,本小节我们讲解一下Postman Newman的具体使用方法。 使用Newman运行集合 1、导出Postman集合: 在Postman中,选择你想要运行的集合,然后点击“导出”按钮,选择导出为“Collect…

推荐使用三丰云免费云服务器、免费虚拟主机

官网地址:www.sanfengyun.com 三丰云服务器: 配置高:能够轻松运行应用程序和网站,在处理大量请求和保持高可靠性方面表现出色。 易用性好:界面直观、简单,能够轻松管理服务器和资源,快速创建和…