当前位置: 首页 > news >正文

第2周-预习作业

Java 相关问题解答

1. 方法相关问题

1.1 changeStr与changeArr的功能各是什么?

  • changeStr功能:该方法接收一个String参数x,并尝试将x赋值为"xyz"。但由于String是不可变类,且Java采用值传递,所以该方法不会改变原始字符串的值。它只会修改方法内部局部变量x的引用,对调用方的变量无影响。

  • changeArr功能:该方法接收一个String数组参数strs,并遍历数组,将每个元素拼接上其索引值(例如,strs[i]变为strs[i] + "" + i)。由于数组是对象,传递的是引用值的副本,但副本和原始引用指向同一数组对象,因此该方法会实际修改数组的内容。

1.2 main方法的x有没有被改变?为什么?

  • 没有改变。原因如下:
    • Java中方法参数传递是值传递(pass-by-value)。当调用changeStr(x)时,传递的是变量x的值的副本(即指向字符串"abc"的引用的副本)。
    • changeStr方法内部,参数x被重新赋值为指向"xyz",但这只影响方法内的局部变量,不会改变main方法中x的引用。main方法中的x仍然指向原始的字符串"abc"。
    • String的不可变性也确保了字符串内容不会被修改。

1.3 main方法的args数组的内容有没有被改变?为什么?

  • 被改变了。原因如下:
    • 当调用changeArr(args)时,传递的是args数组的引用值的副本,但该副本和原始引用都指向同一个数组对象。
    • changeArr方法中,通过引用修改了数组元素的值(例如,将每个元素拼接索引值),这些修改会反映到原始数组上,因为操作的是同一对象。

1.4 args数组中的值是从哪里来的?要怎么才能给他赋值?

  • 来源:args数组中的值来自命令行参数(command-line arguments)。当运行Java程序时,可以通过命令行输入参数。

  • 赋值方法

    • 命令行方式:使用java Main arg1 arg2 arg3运行程序,其中arg1arg2arg3会被传入args数组(args[0]="arg1", args[1]="arg2", 等等)。
    • IDE方式:在IDE(如Eclipse、IntelliJ IDEA)中,可以通过运行配置(Run Configuration)设置程序参数(Program arguments)来赋值。
    • 示例:如果在命令行中运行java Main hello world,则args[0]="hello", args[1]="world"。

2. 数组相关问题

2.1 这段程序输出结果是什么?为什么?

int[] arr = new int[3];
arr[0] = 1; arr[1] = 1;
int[] arrX = arr;
arr[0] = 2;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arrX));
  • 输出结果

    [2, 1, 0]
    [2, 1, 0]
    
  • 原因

    • int[] arrX = arr; 将arrX指向了同一个数组对象作为arr。因此,arr和arrX是同一个数组的两个引用。
    • 当执行arr[0] = 2;时,修改了数组的第一个元素,由于arr和arrX共享同一数组,所以通过arrX访问时也能看到修改后的值。
    • 数组初始化为int[3]时,元素默认值为0,所以arr[2]为0。

2.2 字符串是不可变类,为什么可以对strArr[1]赋值"xx"?

String[] strArr = {"aa","bb","cc"};
strArr[1] = "xx";
System.out.println(Arrays.toString(strArr));
  • 原因
    • 字符串不可变是指String对象本身的内容不能被修改(例如,不能改变"bb"的内部字符数组)。
    • 但是,strArr是一个String数组,其元素是String类型的引用。执行strArr[1] = "xx";并不是修改已有的String对象"bb",而是将strArr[1]的引用从指向"bb"改为指向一个新的String对象"xx"。
    • 因此,这是改变数组元素的引用值,而不是修改String对象的内容,所以是允许的。

3. 二维数组问题

使用int[5][]定义一个二维数组,其第二维的长度最初未指定(即为null),需要单独初始化。第二维的长度可以各不相同。

补全代码示例:

// 定义二维数组,第一维长度为5,第二维未初始化
int[][] twoDArray = new int[5][];// 初始化第二维数组,这里假设第二维长度均为3(也可以设置不同长度)
for (int i = 0; i < twoDArray.length; i++) {twoDArray[i] = new int[3]; // 每个第二维数组长度为3
}// 使用foreach循环遍历二维数组
for (int[] innerArray : twoDArray) {for (int value : innerArray) {System.out.print(value + " ");}System.out.println();
}
  • 第二维的长度:在初始化之前,第二维的每个元素都是null。初始化后,第二维的长度由代码决定(如上例中均为3),但也可以设置不同长度,例如:
    twoDArray[0] = new int[2];
    twoDArray[1] = new int[4];
    // ...
    

4. 类与对象问题

类与对象的区别是什么?

  • :是对象的蓝图或模板,定义了对象的属性(字段)和方法(行为)。它是一个抽象概念,例如String类、Math类。
  • 对象:是类的实例,是具体的数据结构,占用内存空间。例如,通过new String("abc")创建的字符串对象。

Math类有对象吗?

  • Math类没有对象(实例)。因为Math类被设计为工具类,所有方法都是static的,并且构造函数是private的,防止实例化。直接通过类名调用方法,如Math.abs(-5)

String类有什么属性是private的,有什么方法是public的,为什么这样设计?

  • private属性:String类内部使用private final数组存储字符数据,例如在Java 8及之前是private final char[] value,在Java 9及之后是private final byte[] value。这些属性是private的,以防止外部直接访问和修改。

  • public方法:String类提供了许多public方法用于操作字符串,例如:

    • public int length():返回字符串长度。
    • public char charAt(int index):返回指定索引处的字符。
    • public String substring(int beginIndex):返回子字符串。
  • 为什么这样设计

    • 封装性:通过将属性设为private,控制对内部数据的访问,确保字符串的不可变性。外部代码不能直接修改内部数组,从而保证字符串内容一致性和线程安全。
    • 安全性:防止恶意修改字符串内容,例如在安全敏感的上下文中。
    • 灵活性:可以在内部改变实现而不影响外部代码(例如从char数组改为byte数组以节省空间)。
    • 示例:substring方法返回新字符串,而不是修改原字符串,这得益于不可变设计。

5. setter/getter模式与封装性

为什么Java中普遍使用setter/getter模式?

  • 原因
    • 封装性:setter/getter模式是封装的具体体现。通过将属性设为private,然后提供public的setter和getter方法,可以控制对属性的访问。
    • 优点
      • 数据验证:在setter方法中检查输入值的有效性(例如,年龄不能为负数)。
      • 延迟初始化或计算:在getter中可以实现延迟加载或计算属性值。
      • 修改内部实现:以后可以改变属性的存储方式而不影响外部代码(例如,将直接存储改为计算得出)。
      • 添加额外逻辑:可以在setter/getter中添加日志、通知或同步代码。
    • 与封装性的关系:封装隐藏了对象的内部状态,只暴露必要的操作接口(setter/getter),从而降低耦合度,提高代码的可维护性和安全性。如果属性直接public,外部代码可以随意修改,可能导致对象状态不一致。

6. 对象属性的初始化时机和方法

对象的属性可以在以下时机进行初始化:

  1. 声明时直接初始化:在定义属性时直接赋值。

    private int x = 10;
    private String name = "default";
    
  2. 构造器中初始化:在构造函数中赋值。

    public MyClass() {this.x = 10;this.name = "default";
    }
    
  3. 初始化块中初始化

    • 实例初始化块:在类中使用{}块,每次创建对象时执行。
      {x = 10;name = "default";
      }
      
    • 静态初始化块:使用static{}块,用于初始化静态属性,在类加载时执行一次。
  4. 通过方法初始化:在对象创建后,通过setter方法或其他方法初始化。

    MyClass obj = new MyClass();
    obj.setX(10);
    
  5. 延迟初始化:在第一次访问属性时初始化,通常结合null检查。

    private String data;
    public String getData() {if (data == null) {data = loadData(); // 加载数据}return data;
    }
    

这些方法可以根据需要组合使用,以确保属性在对象使用前被正确初始化。

相关文章:

第2周-预习作业

Java 相关问题解答 1. 方法相关问题 1.1 changeStr与changeArr的功能各是什么?changeStr功能:该方法接收一个String参数x,并尝试将x赋值为"xyz"。但由于String是不可变类,且Java采用值传递,所以该方法不会改变原始字符串的值。它只会修改方法内部局部变量x的引用…...

P12546 [UOI 2025] Convex Array

\(b_{i-1}+b_{i+1}\ge b_i\) 等价 \(b_{i+1}-b_i\ge b_i-b_{i-1}\) 即 \(b\) 数组差分数组单调不降。 若出现次数为 2,则必定是最小值在排列中左右各有 1 个。(不能相同元素放一起否则差分为 0)。 若存在元素出现次数大于 2 且不为最小值,则必定无解(多余的元素无论放在哪…...

一个新词:测试可靠性

提高测试可靠性是为了让我们的测试值得信任。 以前都在讲软件的健壮性、可靠性,好像都在对开发质量提出要求。今天,为了证明自己的工作是值得信任的,提高测试的可靠性势在必行。 提高测试的可靠性,传统做法有哪些呢?测试用例评审、交叉测试、测试复盘总结、线上问题跟踪学…...

CF827F Dirty Arkadys Kitchen

先把 \((u,v,l,r)\) 变成 \((u,v,l,r-1)\)。 不能停留,所以每个时刻有两种选择在某一条边上用 2 个时刻走一个来回浪费时间等某一条需要的边开启。走到下一个点。第 1 种选择启发若时刻 \(t\) 能到 \(u\),那么若存在边 \((u,v,l,r)\),那么所有时刻 \(T\in[l,r],T\equiv t\pm…...

P2839 [国家集训队] middle

经典的二分答案 \(mid\),\(\ge mid\) 的数权值为 1,\(<mid\) 权值为 -1,答案合法当且仅当存在区间 \([l,r]\) 使得权值和 \(\ge 0\),做前缀和 \(s\),即等价于 \(s_r-s_{l-1}\ge 0\to s_r\ge s_{l-1}\)。 对于询问 \((a,b,c,d)\) 只需要 \(\max_{i=c}^ds_i\ge \min_{i=a…...

wuti

...

友链

...

向量化存储与知识图谱的比较

以下内容来自AI对话生成简单来说,它们的核心区别是:向量化存储追求“语义上的相似”,而知识图谱追求“逻辑上的关联”。 我们可以用一个经典的例子来区分:问题:“苹果公司的创始人史蒂夫乔布斯最喜欢吃什么水果?” 向量化存储:可能会找到一段描述“史蒂夫乔布斯饮食习惯…...

力扣17题 电话号码的字母组合

归类:回溯算法 回溯三部曲: 1.确定回溯函数参数 首先需要一个字符串s来收集叶子节点的结果,然后用一个字符串数组result来保存起来,这两个变量依然定义为全局。 参数指定是有题目中给的string digits,然后还有一个参数就是int型的index。 index是用来记录遍历第几个数字了…...

萤火虫文旅年票、为什么能做到低至4.2元一张景区门票、还能高达50%的毛利润?

【商业揭秘萤火虫文旅年票】低至4.2元/张景区门票,毛利润竟超50%!萤火虫文旅年票的盈利模式为何让行业震惊?【商业揭秘萤火虫文旅年票】低至4.2元/张景区门票,毛利润竟超50%!萤火虫文旅年票的盈利模式为何让行业震惊? 当看到"4.2元一张景区门票"这个价格时你的…...

ubuntu服务器docker容器安装nacos

docker pull nacos/nacos-server:latest TOKEN=$(echo -n "nacos-token-$(date +%s)" | base64) # 随机令牌 IDENTITY_KEY="nacos-identity-key" # 自定义身份键 IDENTITY_VALUE="nacos-identity-value" # 自定…...

PWN手的成长之路-02-r3m4ke

启动环境,并下载附件。远程连接之后,输入了一些命令,发现无反应。开始分析附件。 先用checksec查看一下文件的安全属性。 文件是64位的且只开启了NX防御(这个保护开启就是意味着栈中数据没有执行权限,如此一来, 当攻击者在堆栈上部署自己的 shellcode 并利用缓冲区溢出等手…...

SAP 采购订单税率及含税金额取数

税码 联查A003及KONP "采购税码的税率SELECT a~mwskz, "税码k~kbetr "税率INTO TABLE @DATA(t_sl)FROM a003 AS a INNER JOIN konp AS kON a~knumh = k~knumhWHERE a~mwskz IN ( J0 , J1 , J2 , J3 , J4 , J5 , J6 )AND a~aland = CN.SORT t_sl BY mwskz.....…...

深入解析:Linux x86 stability和coredump

深入解析:Linux x86 stability和coredumppre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !impor…...

9.15更新linux命令

...

Jenkins 容器和 Kubernetes Agent

Jenkins 容器和 Kubernetes Agent安装 Jenkins [root@control-plane jenkins]# cat compose.yaml services:jenkins:# Jenkins 2.516.2image: jenkins/jenkins:ltsports:- "8080:8080"# https://github.com/jenkinsci/docker/blob/master/README.md#connecting-agen…...

LGP7916 [CSP-S 2021] 交通规划 学习笔记

LGP7916 [CSP-S 2021] 交通规划 学习笔记 Luogu Link 前言仔细读了十遍题面,硬是一个字都没和交通规划扯上关系,很有可能是出题人编了一个故事,发现编不下去了。——\(\texttt{OMG-WC}\)。题意简述 有一个 \(n\times m\) 个点的网格图。对于这个网格图的最外侧,有些网格线会…...

详细介绍:【Kubernetes】常见面试题汇总(十四)

详细介绍:【Kubernetes】常见面试题汇总(十四)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace…...

萤火虫文旅年票、为何能成为撬动万亿文旅市场的利器

萤火虫文旅年票隶属于四川红色猎人信息技术有限公司、成立于2020年7月24日、致力于为B端企业用户和C端个人用户提供超高性价比的景区门票.用互联网OTA技术整合了全国7000多家景点、用自助餐模式搭建了四款产品:省级版景区门票、大区版景区门票、全国版景区门票、以及企业定制版…...

Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用

Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用牵牛老人 已于 2025-07-25 09:24:54 修改 阅读量645 收藏 10 点赞数 11 文章链接:https://blog.csdn.net/qianniulaoren/article/details/149138758一:USB摄像头开发基础与框架 1.1 QtMultimedia的优势与局限​ 跨平台兼…...

详细介绍:C++(静态函数)

详细介绍:C++(静态函数)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-siz…...

2025.9.15日软件工程学习日志

HBase科技成果管理系统设计与实现 今日设计一个基于HBase的科技成果信息填报系统。 系统分析与设计思路 前端需要实现科技成果信息填报表单,包含多种输入类型和验证 后端使用HBase作为数据库存储数据 需要实现数据的增删改查功能 成果编号需要按规则自动生成 HBase表设计: 表…...

RocketMQ快速实战及核心概念

RocketMQ学习笔记 一、MQ简介 MQ定义MQ:Message Queue,消息队列Message:消息,不同进程之间传递的数据Queue:队列,具有FIFO(先进先出)特性,用于缓存数据广义上,只要能实现消息跨进程传输及队列数据缓存,都可称为消息队列MQ的作用异步例子:快递员发快递,先放到菜鸟驿站…...

【南方科技大学主办】第五届电气工程与机电一体化手艺国际学术会议(ICEEMT 2025)

【南方科技大学主办】第五届电气工程与机电一体化手艺国际学术会议(ICEEMT 2025)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &qu…...

为什么不建议在 Docker 中跑 MySQL?

前言 今天我们来聊聊一个很有趣的话题:为什么我不建议在Docker中运行MySQL数据库? 有些小伙伴在工作中可能为了部署方便,习惯将所有组件都容器化,但数据库真的适合放在容器里吗? 今天就专门跟大家一起聊聊这个话题,希望对你会有所帮助。 一、容器化与数据库:天生的矛盾?…...

reLeetCode 热题 100-1 指针283. 移动零 - MKT

reLeetCode 热题 100-1 指针283. 移动零 class Solution { public:void moveZeroes(vector<int>& nums) {// int cout_=0;// for(int i =0; i<nums.size();i++){// if(nums[i]==0){// cout_++;// }// }// std::cout<< " 0s all …...

解决c# DocX生成的word文档wps打开排版外边距错乱微软office正常问题

public void insertBreak(DocX document, String filename) { DocX tempDocx = DocX.Create(filename); setPageMargin(tempDocx); document.InsertDocument(tempDocx);document.InsertSectionPageBreak(true); }改为public vo…...

The 2025 ICPC Asia East Continent Online Contest (II)

The 2025 ICPC Asia East Continent Online Contest (II)比赛链接 Review 这场非常有参与感哈哈,因为我签到题 C 贪心写了两小时,中间下机若干次让队友过题,写完已经完全不知道队友进度是啥了,后续就当小黄鸭被带飞了哈哈。 Solution C. Jiaxun! 那我确实需要 jiaxun 额额贪…...

工厂方法模式(Factory Method) - 指南

工厂方法模式(Factory Method) - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !importa…...

拾忆录

████,也即言多██,就是少点██,不容易发生██——来自于多种████的通理 择一███,遇一人██——收集自███,████ 知行合一心学理论——王阳明...

从零搭建RAG应用:跳过LangChain,掌握文本分块、向量检索、指代消解等核心技术实现

RAG(检索增强生成)本质上就是给AI模型外挂一个知识库。平常用ChatGPT只能基于训练数据回答问题,但RAG可以让它查阅你的专有文档——不管是内部报告、技术文档还是业务资料,都能成为AI的参考资源。 很多人第一反应是用LangChain或LlamaIndex这些现成框架,确实能快速搭起来。…...

python高阶技巧

闭包:在函数嵌套前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数叫做闭包 简单闭包: def outer(logo): def inner(msg): print(f"<{logo}>{msg}>{logo}") return inner fn1=outer("黑马程…...

机器视觉之图像处理篇 - 指南

机器视觉之图像处理篇 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-s…...

尝试hikari和jdbctemplate

试着基于jdbctemplate包装一个MysqlHelper类。连接池采用springboot默认的hikari。jdbctemplate提供基本的防注入,它的写法比jdbc好看,jdbc还需要putint,putstr。提供的另一个功能是结果集的转换。写完,测试代码的面貌如下:var sqlhp = new SqlHelper();sqlhp.configAddress…...

配置Nginx根据IP地址进行流量限制以及返回JSON格式数据

要在Nginx中根据IP地址进行流量限制并返回JSON格式数据,你需要结合Nginx的 ngx_http_limit_req_module模块和一些配置技巧。这个模块允许你基于定义的键值,比如IP地址,限制请求的速率。不过在进入细节前,别忘了备份你的Nginx配置文件 划重点:配置透视战斗护甲 (limit_req_…...

回归

最近因为████导致██发生████,长期的██也不是办法,我决定以███████发文。 我的很多比如███,███都发生了██,所以██的██████视█。 重新██...

CSS纯文本渐变动效

创建一个令人印象深刻的CSS文本渐变动效就像是在文字上施展魔法。想象你的文字就像是一幅幻灯片,色彩在背后流转,让每个字母都像是被彩虹绘制过一样。 为了让这种魔法发生,你需要进入CSS的巫术领地。我们将把渐变动效的制作分解为简单步骤,这样即使你不是CSS的大师,也能轻…...

泛微流程共享

第一步: 第二步:打开合同审批数据,点击右键,选择共享。 第三步:共享权限的查看,可见Giada没有查看权限。 第四步:添加权限,依次进入下面的选项。...

MySQL报错:未知系统变量tx_isolation及隔离级别查询

MySQL在其各个版本中进行了诸多变更和优化,包括系统变量、参数命名、功能等方面的调整。在这个情况中,遇到“未知系统变量tx_isolation”这个错误是因为在MySQL 8.0及以后的版本中,系统变量 tx_isolation已经被重命名为 transaction_isolation。 如果你像老朋友一样寻找 tx_…...

Redssion

1.使用 // 设置锁定资源名称 RLock disLock = redissonClient.getLock("DISLOCK"); //尝试获取分布式锁 boolean isLock= disLock.tryLock(500, 15000, TimeUnit.MILLISECONDS); if (isLock) {try {//TODO if get lock success, do something;Thread.sleep(15000);} …...

if __name__ == __main__:

if __name__ == "__main__": 是 Python 中的一个标准代码块,用于检查一个脚本是否是直接运行的。 工作原理 当一个 Python 脚本被解释器执行时,它会自动定义一些特殊变量。其中一个就是 __name__。如果脚本是直接运行的,Python 会将 __name__ 变量的值设置为 &quo…...

提升系统可靠性:Air8000多串口硬件设计的黄金法则

串口通信的可靠性直接影响工业系统的连续性。Air8000以多串口工业级连接力赋能设备互联,而硬件设计则是其可靠性的根基。总结黄金法则,从信号隔离、阻抗匹配到热设计,全方位保障串口通信的稳定性与安全性。 本文主要从硬件设计的角度,分享串口设计中的一些关键注意点,软件…...

20250915笔记

svn 版本控制工具 一、svn介绍 二、svn安装 1、下载客户端和服务端 安装流程: (1)先安装服务端 (2)在服务端创建仓库 (3)新建用户,新建用户组 (4)设置权限,服务端安装成功 (5)安装客户端(也叫小乌龟) (6)安装桌面右键连接仓库 (7)输入账号和密码 (8)连接…...

enumerate函数

enumerate() 是 Python 中一个非常实用的内置函数,它用于在遍历一个可迭代对象(如列表、元组、字符串等)的同时,获取每个元素的索引和值。 为什么需要 enumerate()? 在没有 enumerate() 之前,如果你想同时获取索引和值,通常需要手动维护一个计数器: fruits = [apple, b…...

2025国内 HR SaaS 竞争格局:易路以AI深度融合引领行业转型

在中国企业数智化转型的浪潮中,HR SaaS 市场正经历从基础数字化向智能协同的关键跃迁。随着全球化布局与本地化合规要求的双重驱动,中大型企业对人力资源管理系统的需求已从单一模块效率提升转向全流程智能协同与全球合规管理。截至 2025 年,中国 HR SaaS 市场规模已突破 30…...

HyperWorks许可激活

在工程项目中,高效的软件工具是成功的关键。而一个顺畅的许可激活流程,则是确保这些工具能够迅速投入使用的重要环节。HyperWorks,作为一款领先的工程仿真软件,以其快速、简便的许可激活流程,为用户提供了卓越的使用体验。 一、一键激活,轻松上手 HyperWorks的许可激活流…...

f-string用法

在 Python 3.6 及更高版本中,在字符串前加上一个 f,表示这是一个 f-string(格式化字符串字面量)。 f-string 的主要作用是让你在字符串中嵌入 Python 表达式,使得格式化字符串变得非常简洁和直观。 f-string 的基本用法 你只需要在字符串开头加上 f,然后在字符串内部用花…...

OpenStack Nova instance 常见操作

1. 启动实例(start) 场景:启动处于 SHUTOFF 状态的实例 源码路径:API 层:nova/compute/api.py → start() RPC 层:nova/compute/rpcapi.py → start_instance() 执行层:nova/compute/manager.py → start_instance() 驱动层:nova/virt/libvirt/driver.py → power_on()…...

libdpi.dll libdatareport.dll libdash_plugin.dll libcurl-x86.dll libcurl-x64.dll libcurl_x64.dll - 指南

libdpi.dll libdatareport.dll libdash_plugin.dll libcurl-x86.dll libcurl-x64.dll libcurl_x64.dll - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…...

理解 Kubernetes CSI

关于 Kubernetes CSI,现在的资料已经不少,但我仍希望有一篇文档能让人轻松但不失准确地理解 CSI。 本文不涉及代码分析和详细设计。但需要如下基础:会使用至少一种容器,Docker,containerd,Kata 之类的都可以。 protobuf 和 gRPC:会用并有少量的开发经验,会用某种语言(…...