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

【Linux】自定义shell的编写

📝前言:
这篇文章我们来讲讲==【Linux】简单自定义shell的编写==,通过这个简单的模拟实现,进一步感受shell的工作原理。

🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏


目录

  • 一,要实现的基本功能
  • 二,打印命令行提示符
    • (1)获取环境变量
      • 对应接口 / 函数用法
      • 实现
    • (2)格式化打印提示符
      • 对应接口 / 函数用法
      • 实现
  • 三,读取用户命令
    • 对应接口 / 函数用法
    • 实现
  • 四,分析命令
    • 用到的全局变量
    • 对应接口 / 函数用法
    • 实现
  • 五,处理命令
    • 对应接口 / 函数用法
    • 实现
  • 六,内建命令
    • (1)cd
      • 全局变量
      • 对应接口 / 函数用法
      • 实现
    • (2)echo
      • 实现
    • (3)判断内建并调用
  • 七,模拟导入环境变量
    • 全局变量
    • 对应接口 / 函数用法
    • 实现
  • 八,完整实现代码

一,要实现的基本功能

  1. 打印命令行提示符
  2. 读取用户输入命令
  3. 分析命令,得到命令行参数表
  4. 处理内建命令
  5. 处理命令

以及补充的:

  • 加载环境变量和 更新环境变量(在cd后更新环境变量)

下面我们分别对这些功能的实现进行讲解

二,打印命令行提示符

先看系统的shell的命令行提示符
在这里插入图片描述
格式:USERNAME@主机名:工作路径$
为了区分,我们计划实现的格式为:USERNAME@主机名:工作路径#

(1)获取环境变量

我们可以通过getenv来获取环境变量一下是对应关系

  • USERNAME:环境变量USER
  • 工作路径:环境变量PWD
  • 主机名:环境变量HOSTNAME(但是我的电脑上getenv(HOSTNAME)拿不到,所以我用库函数:gethostname

对应接口 / 函数用法

  • getenv
    • 头文件:<stdlib.h>
    • 用法:getenv(变量名)
    • 返回值:
      • 成功:对应的字符串指针
      • 失败:NULL
  • gethostname
    • 头文件:<unistd.h>
    • 用法:gethostname(char *name, size_t len)
      • name:字符指针,指向用来存储获取到的hostname的缓冲区(这缓冲区就是代指一篇空间)
      • len:表示name的大小
    • 返回
      • 成功:0
      • 失败:1

实现

 31 const char* GetName()32 {33     char* user = getenv("USER");34     return user == NULL? "None" : user;35 }36 37 const char* GetPwd()38 {39     // 因为在我们 chdir 改变工作路径以后,shell先获取变化,然后才会更新环境变量40     char* pwd = getenv("PWD");41     return pwd == NULL? "None" : pwd;42 }                                                                                                                                                                                                            43 44 const char* GetHost() {45     static char hostname[128]; // 这个要设置成全局的,不然不能返回cosnt46     if (gethostname(hostname, sizeof(hostname)) == 0) {47         return hostname;48     }49     return "None";50 }51 52 const char* GetHome()53 {54     char* home = getenv("HOME");55     return home == NULL? "None" : home;56 }

(2)格式化打印提示符

这里我们用到snprintf,将格式化的数据写入字符串缓冲区。

对应接口 / 函数用法

memset(用来给指定内存设置值):

  • 头文件:<stdio.h>
  • 用法:void *memset(void *s, int c, size_t n)
    • s:要操作的内存块的指针
    • c:要设置的值
    • n:要设置的字节数

snprintf

  • 头文件:<stdio.h>
  • 用法:int snprintf(char *str, size_t size, const char *format, ...);
    • str:指向字符串缓冲区
    • size:缓冲区的大小
    • format:格式化字符串,就像printf里面的格式化一样

实现

 58 void PrintCommandPrompt()59 {60     char Prompt[128];61     memset(Prompt, 0, sizeof(Prompt));62     snprintf(Prompt, sizeof(Prompt), "%s@%s:%s# ", GetName(), GetHost(), GetPwd());63     printf("%s", Prompt);64 }

三,读取用户命令

先看系统的:
在这里插入图片描述
我们输入ls -a -l的本质是,把它当做了一个长字符串"ls -a -l"

对应接口 / 函数用法

fgets

  • 头文件:<stdio.h>
  • 用法:char *fgets(char *str, int size, FILE *stream);
    • stream流里面读一行数据到str,遇到空格和不会停止,直到读取完size - 1个字符或者读完\n才停止。
    • 读完以后末尾会加\0
    • str:用来存储的缓冲区
    • size:缓冲区大小

实现

 66 bool GetCommand(char* buffer, int size) // 获取用户输入的命令67 {68     char* s = fgets(buffer, size, stdin); // 当输入内容小于size - 1,有多少读多少,当输入内容大于size - 1,读size - 1个【末尾都加 \0】69     if(s == NULL) return false;70     s[strlen(buffer) - 1] = 0; // 清理\n (strlen也会计算 \n 的长度)71     if(strlen(buffer) == 0) return false;72     return true;73 }

四,分析命令

分析命令,就是形成命令行参数表,为后续的调用程序准备

用到的全局变量

 11 // 命令行参数表12 #define MAX_ARGC 128 // 命令行参数个数最大值13 char* argv[MAX_ARGC]; // 命令行参数表14 int argc = 0; // 命令行参数实际个数

对应接口 / 函数用法

strtok

  • 用法:char *strtok(char *str, const char *delim);
    • 功能说明:把字符串strdelim进行切割
  • 返回值
    • 本次有遇到分隔符:把分隔符替换成\0然后返回切下来那一段字符
    • 最后一段字符串后面没有分割符:返回后面的整个字符串
    • 当最后一段字符串也切割完了:返回NULL
  • str传参讲究:
    • 第一次:str传要分割的字符串
    • 第一次后:strnullptr

实现

 75 bool CommandParse(char* command) // 得到argv命令行参数表76 {77     argc = 0;78     argv[argc++] = strtok(command, " "); // strtok按字符串将字符切割,把分割字符替换成 \0,当没有分隔符的时候返回整个字符串,当最后一个字符串也遍历了,就返回NULL79     while(bool(argv[argc++] = strtok(nullptr," "))); // 实际 argc 会比参数个数大180     argc--;81     return argc > 0? true: false;82 }

我们就会得到类似这样的一张参数表:
在这里插入图片描述

五,处理命令

处理命令的本质
命令处理的本质是:调用了ls程序,怎么调用的?
bash进程创建了一个子进程,然后子进程通过程序切换完成调用的

对应接口 / 函数用法

forkexecvp,这两用法就不说了,不懂的可以看:进程控制

实现

 94 int Execute()95 {96     pid_t ret = fork();97     if(ret == 0)98     {99         execvp(argv[0], argv);
100         exit(1); // 如果没调成功,返回码为 1 代表返回结果不正确
101     }
102     // father
103     // 这里实现 echo $? 功能,修改lastcode
104     int status = 0;
105     pid_t id = waitpid(ret, &status, 0);
106     if(id > 0)
107     {
108         lastcode = WEXITSTATUS(status);
109     }
110     return 0;
111 }

六,内建命令

内建命令需要shell亲自执行,这里我们主要实现cdecho内建命令的部分功能

(1)cd

主要实现:cdcd -cd ~cd pathpath为自己写的路径,并且要确保正确)

思路:

  • 得到对应的要改变的路径,然后通过父进程chdir来改变。在-
  • 这里不能fork() + cd,因为如果fork了改变的只是子进程的工作路径,而一个父进程有多个子进程,我们的shell的工作路径还是没有改变,所以这里直接在父进程上chdir

全局变量

 25 #define MAX_P 100 // 最长路径长26 char CWD[MAX_P];27 28 // 及时更新环境变量PWD29 char PWD[MAX_P];30 char OLDPWD[MAX_P];

对应接口 / 函数用法

putenv

  • 头文件:<stdlib.h>
  • 已存在:覆盖,不存在:创建
  • 仅修改当前进程及其子进程的环境变量,不会影响父进程或系统全局环境

这里用它是为了,通过直接覆盖的方式,更新环境变量PWDOLDPWD,因为cd会用到这两个变量

实现

139 bool Cd()
140 {
141     memset(PWD, 0, sizeof(PWD));
142     if(argc == 1)
143     {
144         string home = GetHome();
145         if(home.empty()) return true;
146         snprintf(OLDPWD, sizeof(OLDPWD), "OLDPWD=%s", getcwd(CWD, sizeof(CWD))); // 在更新路径之前记录OLDPWD
147         putenv(OLDPWD);
148         chdir(home.c_str());
149         snprintf(PWD, sizeof(PWD), "PWD=%s", home.c_str());
150         putenv(PWD);
151     }
152     else
153     {
154         string where = argv[1];
155         if(where == "-")
156         {
157             char* oldpwd = getenv("OLDPWD");
158             if(oldpwd == NULL) return true;
159             snprintf(OLDPWD, sizeof(OLDPWD), "OLDPWD=%s", getcwd(CWD, sizeof(CWD))); // 在更新路径之前记录OLDPWD
160             putenv(OLDPWD);
161             chdir(getenv("OLDPWD"));
162             snprintf(PWD, sizeof(PWD), "PWD=%s", oldpwd);
163             putenv(PWD);
164         }
165         else if(where == "~")
166         {
167             string home = GetHome();
168             if(home.empty()) return true;
169             snprintf(OLDPWD, sizeof(OLDPWD), "OLDPWD=%s", getcwd(CWD, sizeof(CWD))); // 在更新路径之前记录OLDPWD
170             putenv(OLDPWD);
171             chdir(home.c_str());
172             snprintf(PWD, sizeof(PWD), "PWD=%s", home.c_str());
173             putenv(PWD);
174         }
175         else
176         {                                                                                                                                                                                                    
177             snprintf(OLDPWD, sizeof(OLDPWD), "OLDPWD=%s", getcwd(CWD, sizeof(CWD))); // 在更新路径之前记录OLDPWD
178             putenv(OLDPWD);
179             chdir(where.c_str());
180             snprintf(PWD, sizeof(PWD), "PWD=%s", where.c_str());
181             putenv(PWD);
182         }
183     }
184 
185     return true;
186 }

(2)echo

主要实现:echo $?echo $环境变量名echo 长字符串

实现

189 bool Echo()
190 {
191     if(argc == 1) return false;
192     string s = argv[1];
193     if(s == "$?")
194         printf("%d\n", lastcode);
195     else if(s[0] == '$')
196     {
197         string ss = "";
198         for(int i = 1; i < s.size(); i++)
199             ss += s[i];
200         if(getenv(ss.c_str()))
201             printf("%s\n",getenv(ss.c_str()));
202         else return false;
203     }
204     else
205     {
206         string ss = "";
207         int i = 1;
208         while(argv[i])
209         {
210             string tmp = argv[i];
211             ss += tmp + " ";
212             i++;
213         }
214         printf("%s\n", ss.c_str());
215     }
216     return true;
217 }

(3)判断内建并调用

220 bool CheckAndExecBuiltin()
221 {
222     string cmd = argv[0];
223     // 识别内建命令
224     if(cmd == "cd")
225         Cd();
226     else if(cmd == "echo")
227         Echo();
228     else
229     {
230         return false;
231     }
232     return true;
233 }

七,模拟导入环境变量

最后我们再加一个模拟导入环境变量,实际上应该是从配置文件导入的,这里我们从系统bash获取了,然后模拟导入

全局变量

 19 #define MAX_ENVS 10020 21 // 全局环境变量表22 char* env[MAX_ENVS];23 int env_nums = 0;

对应接口 / 函数用法

strcpy

  • char *strcpy(char *dest, const char *src);
  • 将源字符串 src 复制到目标字符串 dest 中,其中包含字符串结束符 '\0'(是简单的浅拷贝)

实现

113 void InitEnv()
114 {
115     memset(env, 0, sizeof(env));
116     env_nums = 0;
117     extern char** environ;
118 
119     // 获取环境变量
120     for(int i = 0; environ[i]; i++)
121     {
122         env[i] = (char*)malloc(strlen(environ[i]) + 1); // 多开一个bit放\0
123         strcpy(env[i], environ[i]);
124         env_nums++;
125     }
126     env[env_nums++] = (char*)"myvalue=12345";
127     env[env_nums] = NULL;
128 
129     // 加载环境变量
130     for(int i = 0; env[i]; i++)                                                                                                                                                                              
131     {
132         putenv(env[i]); // 这里对于已经存在的环境变量,putenv会更新。
133     }
134     environ = env;
135     // 上面模拟从配置文件加载的过程
136 }

八,完整实现代码

当然,这份实现,还存在者各种各样的问题,主要是用来巩固学习到的知识。

如果想要获取完整代码,可以访问我的Github


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

相关文章:

【Linux】自定义shell的编写

&#x1f4dd;前言&#xff1a; 这篇文章我们来讲讲【Linux】简单自定义shell的编写&#xff0c;通过这个简单的模拟实现&#xff0c;进一步感受shell的工作原理。 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;Linux &#x1f380;CSDN主页…...

【C/C++】为什么要noexcept

为什么要noexcept 在C中&#xff0c;noexcept修饰符用于指示函数不会抛出异常 1. 性能优化 减少异常处理开销&#xff1a;编译器在生成代码时&#xff0c;若函数标记为noexcept&#xff0c;可以省略异常处理的相关机制&#xff08;如栈展开代码&#xff09;&#xff0c;从而减…...

运用fmpeg写一个背英文单词的demo带翻译

-男生会因为不配而离开那个深爱的她吗&#xff1f;&#xff1f; 一&#xff0c; fmpeg-7.0.1 是做什么用的&#xff1f;&#xff1f; FFmpeg 7.0.1 是 FFmpeg 的一个版本&#xff0c;FFmpeg 是一个开源的多媒体框架&#xff0c;用于处理音视频数据。FFmpeg 提供了强大的工具和…...

Android 项目中配置了多个 maven 仓库,但依赖还是下载失败,除了使用代理,还有其他方法吗?

文章目录 前言解决方案gradlemaven 仓库 前言 我们在Android 开发的过程中&#xff0c;经常会遇到三方依赖下载不下来的问题。一般情况下我们会在项目的build.gradle文件中配置多个 maven 仓库来解决。 // Top-level build file where you can add configuration options com…...

vue3: pdf.js5.2.133 using typescript

npm install pdfjs-dist5.2.133 项目结构&#xff1a; <!--* creater: geovindu* since: 2025-05-09 21:56:20* LastAuthor: geovindu* lastTime: 2025-05-09 22:12:17* 文件相对于项目的路径: \jsstudy\vuepdfpreview\comonents\pdfjs.vue* message: geovindu* IDE: vscod…...

doxygen 生成 html 网页的一个简单步骤

假设项目源码目录是 src 那么在 src 上一级运行&#xff1a; doxygen -g生成 Doxyfile 随后配置 Doxyfile # 项目相关配置 PROJECT_NAME "你的项目名称" PROJECT_NUMBER "1.0" PROJECT_BRIEF "项目简短描述" …...

云原生环境下服务治理体系的构建与落地实践

📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:服务治理正在从“框架能力”向“平台能力”演进 随着微服务架构逐步成熟,越来越多的企业开始向云原生迁移,Kubernetes、Service Mesh、Serverless 等新兴技术不断推动系统的基础设施演进。 与…...

vue 监听元素大小变化 element-resize-detector

1&#xff0c;安装 npm install element-resize-detector --save2、设置成全局插件 element-resize-detector.js&#xff1a; import ElementResizeDetectorMaker from element-resize-detectorexport default {install: function(Vue, name $erd) {Vue.prototype[name] …...

智芯Z20K144x MCU开发之时钟架构

这里写目录标题 一、zhixin时钟架构1.时钟源2.系统时钟控制器&#xff08;SCC&#xff09;3.外设时钟控制器&#xff08;PARCC&#xff09; 二、软件应用三、总结 一、zhixin时钟架构 可以将时钟架构分解为三个部分来理解&#xff1a; 时钟源&#xff08;OSC、FIRC、LPO&#…...

levelDB的数据查看(非常详细)

起因:.net大作业天气预报程序(WPF)答辩时&#xff0c;老师问怎么维持数据持久性的&#xff0c;启动时加载的数据存在哪里&#xff0c;我明白老师想考的应该是json文件的解析&#xff08;正反&#xff09;&#xff0c;半天没答上来存那个文件了&#xff08;老师默认这个文件是自…...

OpenHarmony平台驱动开发(十),MMC

OpenHarmony平台驱动开发&#xff08;十&#xff09; MMC 概述 功能简介 MMC&#xff08;MultiMedia Card&#xff09;即多媒体卡&#xff0c;是一种用于固态非易失性存储的小体积大容量的快闪存储卡。 MMC后续泛指一个接口协定&#xff08;一种卡式&#xff09;&#xff0…...

【Go底层】http标准库服务端实现原理

目录 1、背景2、核心数据结构【1】Server对象【2】Handler对象【3】ServeMux对象 3、服务端代码示例4、路由注册5、路由匹配 1、背景 http协议的交互框架是C-S架构&#xff0c;C对应客户端模块&#xff0c;S对应服务端模块&#xff0c;接下来我们就基于Go1.23源码来熟悉http标…...

现代健康养生新主张

在充满挑战与压力的现代生活中&#xff0c;健康养生已成为提升生活品质的关键。无需复杂的理论与传统养生模式&#xff0c;通过践行以下科学方法&#xff0c;便能轻松拥抱健康生活。​ 压力管理是现代养生的核心。长期高压力状态会引发激素失衡、免疫力下降等问题。尝试每天进…...

Spring 必会之微服务篇(1)

目录 引入 单体架构 集群和分布式架构 微服务架构 挑战 Spring Cloud 介绍 实现方案 Spring Cloud Alibaba 引入 单体架构 当我们刚开始学开发的时候&#xff0c;基本都是单体架构&#xff0c;就是把一个项目的所有业务的实现功能都打包在一个 war 包或者 Jar 包中。…...

创始人 IP 的破局之道:从技术突围到生态重构的时代启示|创客匠人评述

在 2025 年的商业版图上&#xff0c;创始人 IP 正以前所未有的深度介入产业变革。当奥雅股份联合创始人李方悦在 “中国上市公司品牌价值榜” 发布会上&#xff0c;将 IP 赋能与城市更新大模型结合时&#xff0c;当马斯克在特斯拉财报电话会议上宣称 “未来属于自动驾驶和人形机…...

C++ stl中的stack和queue的相关函数用法

文章目录 stackstack的定义stack的使用 queuequeue的定义queue的使用 stack的使用 包含头文件< stack > #include <stack>queue的使用 包含头文件< queue > #include <queue>stack stack是一种容器适配器&#xff0c;用于具有后进先出操作的场景中&…...

Navicat BI 数据分析功能上线 | 数据洞察新方法

Navicat 17.2 版本一经发布&#xff0c;便以 AI 助手赋能智能交互、Snowflake 支持拓展数据连接版图、拓展对关系型、维度以及数据仓库 2.0 建模方法的支持等新特性与功能抓住了用户的目光&#xff0c;但其中一项低调且实用的更新 - 在 BI 数据预览中深度集成数据分析工具&…...

【网络编程】四、守护进程实现 前后台作业 会话与进程组

文章目录 Ⅰ. 守护进程的概念Ⅱ. 理解会话和作业&#x1f38f; 会话和进程组的特性小总结Ⅳ. 作业的前后台转换1、fg 指令2、bg 指令 Ⅴ. 守护进程实现1、常见接口① 创建守护进程 -- daemon② 自成会话函数 -- setsid③ 获取会话ID函数 -- getsid 2、自主实现守护进程函数 Ⅰ.…...

【深度学习新浪潮】智能追焦技术全解析:从算法到设备应用

一、智能追焦技术概述 智能追焦是基于人工智能和自动化技术的对焦功能,通过深度学习算法识别并持续跟踪移动物体(如人、动物、运动器械等),实时调整焦距以保持主体清晰,显著提升动态场景拍摄成功率。其核心优势包括: 精准性:AI 算法优化复杂运动轨迹追踪(如不规则移动…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】电商数据分析案例-9.3 商品销售预测模型

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 9.3 商品销售预测模型9.3.1 数据清洗与特征工程9.3.1.1 数据清洗流程1. 缺失值处理2. 异常值检测3. 数据一致性校验 9.3.1.2 特征工程实现1. 时间特征提取2. 用户行为特征3.…...

Docker容器启动失败?无法启动?

Docker容器无法启动的疑难杂症解析与解决方案 一、问题现象 Docker容器无法启动是开发者在容器化部署中最常见的故障之一。尽管Docker提供了丰富的调试工具&#xff0c;但问题的根源往往隐藏在复杂的配置、环境依赖或资源限制中。本文将从环境变量配置错误这一细节问题入手&am…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】电商数据分析案例-9.4 可视化报告输出

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 电商数据分析实战&#xff1a;基于PostgreSQL的可视化报告生成全流程9.4 可视化报告输出9.4.1 可视化报告设计框架9.4.1.1 报告目标与受众9.4.1.2 数据准备与指标体系 9.4.2…...

字符串---Spring字符串基本处理

一、String类的特性 不可变性 String对象一旦创建&#xff0c;内容不可更改&#xff0c;任何修改操作都会生成新对象。字符串常量池 字符串字面量&#xff08;如"abc"&#xff09;直接存储在常量池中&#xff0c;重复字面量共享同一内存地址。创建方式 虽然都是字符…...

车载以太网转USB接口工具选型指南(2025版)

一、车载以太网转USB接口工具的核心需求 在新能源汽车研发中&#xff0c;车载以太网与USB接口的转换工具需满足以下核心需求&#xff1a; 物理层兼容性&#xff1a;支持100BASE-T1/1000BASE-T1车载以太网标准&#xff0c;适应车内EMC环境。协议解析能力&#xff1a;支持SOME/…...

Docker基础入门:容器化技术详解

Docker基础入门&#xff1a;容器化技术详解 1. Docker简介 Docker是一个开源的容器化平台&#xff0c;它允许开发者将应用及其依赖打包到一个可移植的容器中&#xff0c;从而确保应用在不同环境中的一致运行。Docker于2013年发布&#xff0c;迅速成为软件开发领域的革命性工具…...

SQL注入的绕过方式

1.注释与空白符绕过 利用#,--,/**/替代被过滤的注释符 利用%09&#xff08;Tab&#xff09;,%0A(换行) &#xff0c;/**/代替空格&#xff1a;如union%0Aselect%0A1,2,3 2.编码绕过&#xff1a; URL编码&#xff0c;双重编码&#xff0c;十六进制编码&#xff0c;Unicode编…...

Java 23种设计模式 - 结构型模式7种

Java 23种设计模式 - 结构型模式7种 1 适配器模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口&#xff0c;从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 优点 将目标类和适配者类解耦增加了类的透明性和复用性&#xff0c;将具体的实现封…...

Linux快速入门

Linux概述 Linux系统版本 Linux系统分为内核版和发行版 内核版 由Linux核心团队开发、维护 免费、开源 负责控制硬件 发行版 基于Linux内核版进行扩展 由各个Linux厂商开发、维护 有收费版本和免费版本 Linux系统发行版&#xff1a; Ubuntu:以桌面应用为主&#xff0c;免费 …...

了解Hadoop

Hadoop了解 Hadoop 是 Apache 基金会开发的一个开源分布式计算平台&#xff0c;主要用于存储和处理大规模数据集。 它能让用户在不了解分布式系统底层细节的情况下&#xff0c;轻松进行分布式程序的开发&#xff0c;将应用程序自动部署到由大量普通机器组成的集群上进行高效运…...

FPGA:如何提高RTL编码能力?

要提升RTL&#xff08;寄存器传输级&#xff09;编码能力&#xff0c;需从硬件设计思维建立、典型电路建模、编码规范掌握、工具链应用和工程实践五个维度系统性训练。以下是具体提升路径&#xff1a; 一、建立硬件设计思维&#xff1a;理解RTL与软件的本质区别 RTL代码最终会…...

高频微服务面试题总结

微服务基础概念 什么是微服务架构? 将单一应用拆分为一组小型服务每个服务运行独立进程,轻量级通信独立开发、部署和扩展特点:松耦合、独立技术栈、独立数据库微服务与单体架构对比 维度单体架构微服务架构开发效率初期快初期慢部署整体部署独立部署扩展性整体扩展细粒度扩展…...

【RAG】Milvus、Pinecone、PgVector向量数据库索引参数优化

Milvus 、PgVector 索引参数优化 IVF类索引关键参数&#xff08;基于聚类算法&#xff09; nlist (倒排列表数量): 决定将向量空间划分为多少个聚类中心值越大搜索越精确但耗时越长推荐值: 通常设置为数据量的4√n到n/1000之间例如: 1百万数据量可设nlist1000到4000 nprobe (…...

基金基础知识-指数基金 | 投资理财(4) 【待续】

基金通常是由股票、债券等多种资产组合而成的投资工具​​&#xff0c;核心是分散化&#xff0c;将资金投向一篮子资产&#xff08;动态&#xff09;&#xff0c;避免单一资产的风险。 按投资标的分类&#xff1a; 基金类型 相当于 特点 适合人群 货币基金 活期钱包&…...

【K8S系列】Kubernetes常用 命令

以下为的 Kubernetes 超全常用命令文档&#xff0c;涵盖集群管理、资源操作、调试排错等核心场景&#xff0c;结合示例与解析&#xff0c; 高效运维 Kubernetes 环境。 一、集群与节点管理 1. 集群信息查看 查看集群基本信息kubectl cluster-info # 显示API Server、DNS等核…...

高性能编程相关

​​​​​​​常见高性能编程技巧&#xff1a; 一&#xff0c;系统级性能优化&#xff1a;从系统架构设计考虑&#xff0c;例如消息队列&#xff0c;模块分成分级&#xff0c;IO读写带宽等 二&#xff0c;算法级性能优化&#xff1a;时间和空间优化 三&#xff0c;代码级性能优…...

使用 NV‑Ingest、Unstructured 和 Elasticsearch 处理非结构化数据

作者&#xff1a;来自 Elastic Ajay Krishnan Gopalan 了解如何使用 NV-Ingest、Unstructured Platform 和 Elasticsearch 为 RAG 应用构建可扩展的非结构化文档数据管道。 Elasticsearch 原生集成了行业领先的生成式 AI 工具和提供商。查看我们的网络研讨会&#xff0c;了解如…...

k8s之statefulset

什么是statefulset(sts) statefulset是用来管理有状态应用的工作负载API对象,也是一种工作负载资源 有状态和无状态 无状态应用:当前应用不会记录状态(网络可能会变、挂载的东西可能会变、顺序可能会变) 有状态应用:需要记录当前状态(网络不变、存储不变、顺序不变) 使…...

在自然语言处理任务中,像 BERT 这样的模型会在输入前自动加上一些特殊token

&#x1f331; 1. 什么是 BERT&#xff1f; BERT 是一个自然语言理解模型。你可以把它想象成一个超级聪明的“语言理解机器人”。你把一句话丢进去&#xff0c;它能&#xff1a; 理解这句话的意思&#xff1b;告诉你哪个词是实体&#xff08;人名、地名&#xff09;&#xff…...

java学习笔记

Java 方法返回值 Java 是一种强类型语言,方法在定义时必须明确指定返回值的类型。 这确保了类型安全和代码的可预测性. 方法返回值不能缺省。 必须显式声明返回类型. 如果方法没有返回值,需要使用 void 关键字来表示。 void 意味着该方法执行某些操作但不返回任何值。 访问修…...

动态规划--两个数组的dp问题

目录 1 最长公共子序列 2 最长回文子序列 3 不相交的线 4 不同的子序列 5 通配符匹配 6 正则表达式匹配 7 交错字符串 8 两个字符串的最小ASCII删除和 9 最长重复子数组 本文主要讲解两个数组的动态规划问题的几个经典例题&#xff0c;希望看完本文之后能够对大家做这…...

Xcavate 上线 Polkadot |开启 Web3 房地产投资新时代

在传统资产 Tokenization 浪潮中&#xff0c;Xcavate 以房地产为切口迅速崛起。作为 2023 年 OneBlock 冬季波卡黑客松冠军&#xff0c;Xcavate 凭借创新的资产管理与分发机制&#xff0c;在波卡生态中崭露头角。此次主网上线&#xff0c;标志着 Xcavate 正式迈入全球化应用阶段…...

在企业级项目中高效使用 Maven-mvnd

1、引言 1.1 什么是 Maven-mvnd? Maven-mvnd 是 Apache Maven 的一个实验性扩展工具(也称为 mvnd),基于守护进程(daemon)模型构建,目标是显著提升 Maven 构建的速度和效率。它由 Red Hat 推出,通过复用 JVM 进程来减少每次构建时的启动开销。 1.2 为什么企业在构建过…...

[论文阅读]Deeply-Supervised Nets

摘要 我们提出的深度监督网络&#xff08;DSN&#xff09;方法在最小化分类误差的同时&#xff0c;使隐藏层的学习过程更加直接和透明。我们尝试通过研究深度网络中的新公式来提升分类性能。我们关注卷积神经网络&#xff08;CNN&#xff09;架构中的三个方面&#xff1a;&…...

使用零样本LLM在现实世界环境中推广端到端自动驾驶——论文阅读

《Generalizing End-To-End Autonomous Driving In Real-World Environments Using Zero-Shot LLMs》2024年12月发表&#xff0c;来自纽约stony brook大学、UIC和桑瑞思&#xff08;数字化医疗科技公司&#xff09;的论文。 传统的自动驾驶方法采用模块化设计&#xff0c;将任务…...

多视图密集对应学习:细粒度3D分割的自监督革命

原文标题&#xff1a;Multi-view Dense Correspondence Learning (MvDeCor) 引言 在计算机视觉与图形学领域&#xff0c;3D形状分割一直是一个基础且具有挑战性的任务。如何在标注稀缺的情况下&#xff0c;实现对3D模型的细粒度分割&#xff1f;近期&#xff0c;斯坦福大学视觉…...

【论文阅读】——Articulate AnyMesh: Open-Vocabulary 3D Articulated Objects Modeling

文章目录 摘要一、介绍二、相关工作2.1. 铰接对象建模2.2. 部件感知3D生成 三、方法3.1. 概述3.2. 通过VLM助手进行可移动部件分割3.3. 通过几何感知视觉提示的发音估计3.4. 通过随机关节状态进行细化 四、实验4.1. 定量实验发音估计设置: 4.2. 应用程序 五、结论六、思考 摘要…...

Docker Compose 的详细使用总结、常用命令及配置示例

以下是 Docker Compose 的详细使用总结、常用命令及配置示例&#xff0c;帮助您快速掌握这一容器编排工具。 一、Docker Compose 核心概念 定位&#xff1a;用于定义和管理多容器 Docker 应用&#xff0c;通过 YAML 文件配置服务、网络、卷等资源。核心概念&#xff1a; 服务 …...

2025.05.08-得物春招研发岗-第三题

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 03. 矩阵魔法变换 问题描述 A先生是一位著名的魔法师,他最近发明了一种特殊的矩阵魔法。这种魔法可以同时改变矩阵中特定区域内所有元素的值。 A先生有一个 n m n \times m...

【Spring AI 实战】基于 Docker Model Runner 构建本地化 AI 聊天服务:从配置到函数调用全解析

【Spring AI 实战】基于 Docker Model Runner 构建本地化 AI 聊天服务&#xff1a;从配置到函数调用全解析 前沿&#xff1a;本地化 AI 推理的新范式 随着大语言模型&#xff08;LLM&#xff09;应用的普及&#xff0c;本地化部署与灵活扩展成为企业级 AI 开发的核心需求。Do…...

【数据机构】2. 线性表之“顺序表”

- 第 96 篇 - Date: 2025 - 05 - 09 Author: 郑龙浩/仟墨 【数据结构 2】 文章目录 数据结构 - 2 -线性表之“顺序表”1 基本概念2 顺序表(一般为数组)① 基本介绍② 分类 (静态与动态)③ 动态顺序表的实现**test.c文件:****SeqList.h文件:****SeqList.c文件:** 数据结构 - 2 …...