第九周预习报告
文章目录
- 第九周预习报告
- 学习内容
- AI 对学习内容的总结
- 章节概述
- 内容总结
- 对知识总结的反思
- 思维导图
- 基于AI的学习
- 知识点1:系统调用
- 知识点2:进程控制
- 学习实践过程遇到的问题与解决方式
- 问题1:`fork()` 调用后,子进程和父进程同时运行导致输出混乱
- 问题2:`exec()` 调用失败,程序无法执行新程序
- 问题3:`open()` 系统调用失败,无法打开文件
- 问题4:`wait()` 调用后,父进程无法正确捕获子进程的退出状态
- 问题5:环境变量传递失败,子进程无法获取正确的环境变量
- 参考资料
第九周预习报告
学习内容
- Head First C 第9章
AI 对学习内容的总结
章节概述
- 本章主要介绍进程和系统调用的概念,学习如何在自己的代码内部使用其他程序,学会如何使用系统服务来创建和控制进程。使程序能够访问电子邮件、Web以及其他任何安装的工具。
内容总结
-
系统调用:
- 定义:系统调用是用户程序与操作系统内核之间的接口,允许用户程序请求操作系统执行特定的任务。
- 常见系统调用:
open():打开文件。read():从文件中读取数据。write():将数据写入文件。close():关闭文件。fork():创建一个新进程。exec():执行一个新程序。wait():等待子进程结束。exit():终止当前进程。
- 工作原理:当用户程序调用一个系统调用时,CPU会从用户模式切换到内核模式,内核执行相应的操作,完成后返回结果,CPU再切换回用户模式。
-
进程控制:
- 进程:进程是操作系统进行资源分配和调度的基本单位,每个进程都有自己的地址空间、文件描述符、环境变量等。
- 创建进程:
fork():创建一个新进程,新进程是调用进程的副本,两者几乎完全相同,但有一个唯一的区别:fork()返回值不同。在父进程中返回子进程的PID,在子进程中返回0。
- 执行新程序:
exec():有一系列函数(如execl()、execlp()、execle()、execv()、execvp()、execvpe()),用于替换当前进程的地址空间,使其开始执行一个新程序。
- 等待子进程:
wait():父进程调用wait()等待子进程结束,wait()会阻塞父进程直到子进程结束。
- 终止进程:
exit():终止当前进程,可以传递一个退出状态码给父进程。
-
环境变量传递:
- 定义:环境变量是操作系统提供的一种机制,用于在进程之间传递配置信息。
- 传递方式:子进程会继承父进程的环境变量,可以通过
exec()系列函数传递新的环境变量。
-
错误处理:
- 返回值:大多数系统调用都有一个返回值,成功时返回一个有意义的值,失败时返回一个错误码(通常是负数)。
- errno:全局变量
errno用于存储系统调用的错误代码,可以通过strerror()函数将错误代码转换为人类可读的字符串。#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h>int main() {int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {fprintf(stderr, "Error opening file: %s\n", strerror(errno));return 1;}close(fd);return 0; }
-
RSS订阅:
- 定义:RSS(Really Simple Syndication)是一种用于发布经常更新的内容的标准格式,如博客文章、新闻等。
- 实现:通过系统调用读取RSS源,解析XML数据,提取所需信息。
#include <stdio.h> #include <curl/curl.h>size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {size_t written = fwrite(ptr, size, nmemb, stream);return written; }int main() {CURL *curl;FILE *file;CURLcode res;curl_global_init(CURL_GLOBAL_DEFAULT);curl = curl_easy_init();if(curl) {file = fopen("rss_feed.xml", "wb");curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/rss.xml");curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);res = curl_easy_perform(curl);if(res != CURLE_OK) {fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));}fclose(file);curl_easy_cleanup(curl);}curl_global_cleanup();return 0; }
-
父子进程关系:
- 父子关系:通过
fork()创建的子进程是父进程的子进程,子进程可以调用getppid()获取父进程的PID。#include <stdio.h> #include <unistd.h> #include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);} else {// 父进程printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0; }
- 父子关系:通过
对知识总结的反思
-
系统调用:
- 系统调用是用户程序与操作系统内核之间的桥梁,通过系统调用可以执行各种底层操作,如文件操作、进程控制等。
- 在实际编程中,需要仔细检查每个系统调用的返回值,以确保调用成功,并处理可能出现的错误。
-
进程控制:
- 进程控制是操作系统管理进程生命周期的关键部分,通过
fork()和exec()可以创建和执行新的进程。 - 在使用
fork()和exec()时,需要注意父子进程的关系,确保程序逻辑的正确性。
- 进程控制是操作系统管理进程生命周期的关键部分,通过
-
环境变量传递:
- 环境变量是进程之间传递配置信息的重要机制,子进程会继承父进程的环境变量。
- 在调用
exec()系列函数时,可以通过参数传递新的环境变量。
-
错误处理:
- 错误处理是确保程序健壮性的关键,通过检查系统调用的返回值和使用
errno,可以有效地处理错误。
- 错误处理是确保程序健壮性的关键,通过检查系统调用的返回值和使用
-
RSS订阅:
- RSS订阅是一个实际应用的例子,展示了如何使用系统调用和网络编程来获取和处理外部数据。
- 通过CURL库,可以方便地实现HTTP请求和数据下载。
思维导图
mindmap本周学习内容进程和系统调用章节概述系统调用定义常见系统调用openreadwritecloseforkexecwaitexit进程控制进程创建进程fork执行新程序exec等待子进程wait终止进程exit环境变量传递定义传递方式错误处理返回值errnoRSS订阅定义实现使用CURL库解析XML数据父子进程关系父子关系getppid重点内容系统调用定义常见系统调用openreadwritecloseforkexecwaitexit进程控制进程创建进程fork执行新程序exec等待子进程wait终止进程exit环境变量传递定义传递方式错误处理返回值errnoRSS订阅定义实现使用CURL库解析XML数据父子进程关系父子关系getppid

基于AI的学习
知识点1:系统调用
AI: 举一个常见的系统调用例子。
我: 打开文件是一个常见的系统调用。当程序想要读取或写入文件时,它会调用 open() 系统调用。这个调用会请求操作系统打开指定的文件,并返回一个文件描述符,程序可以使用这个文件描述符进行后续的读写操作。
AI: 系统调用 fork() 和 exec() 有什么区别?
我: fork() 和 exec() 是两个不同的系统调用,它们分别用于不同的目的。
fork()用于创建一个新的进程。新进程是调用进程的副本,具有相同的代码段、数据段和堆栈段,但有自己的独立内存空间。fork()返回一个值,如果返回值为0,则表示当前进程是子进程;如果返回值大于0,则表示当前进程是父进程,返回值是子进程的PID。exec()用于在当前进程中加载并运行一个新的程序。exec()有多个变种,如execl()、execlp()、execle()、execv()、execvp()和execvpe(),它们的主要区别在于参数的传递方式。调用exec()之后,当前进程的代码段、数据段和堆栈段会被新程序的代码段、数据段和堆栈段替换。
AI: wait() 系统调用的作用是什么?
我: wait() 系统调用用于父进程等待子进程结束。父进程调用 wait() 会阻塞,直到一个子进程结束。wait() 返回子进程的PID,并且可以通过返回值和 wait() 的参数来获取子进程的退出状态。
AI: 如何处理系统调用的错误?
我: 处理系统调用的错误通常涉及以下几个步骤:
- 检查系统调用的返回值。大多数系统调用在成功时返回一个有意义的值,而在失败时返回一个错误码(通常是负数)。
- 如果系统调用失败,检查全局变量
errno以获取具体的错误代码。 - 使用
strerror()函数将错误代码转换为人类可读的错误信息,并进行适当的错误处理,如打印错误信息、记录日志或采取其他补救措施。
AI: 举一个处理 open() 系统调用错误的例子。
我: 当然,以下是一个处理 open() 系统调用错误的示例代码:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>int main() {int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {fprintf(stderr, "Error opening file: %s\n", strerror(errno));return 1;}close(fd);return 0;
}
在这个例子中,如果 open() 调用失败,fd 将被设置为 -1,程序会检查 errno 并使用 strerror() 函数将错误代码转换为错误信息,然后打印错误信息并返回1表示程序异常退出。
知识点2:进程控制
AI: 什么是进程?
我: 进程是操作系统进行资源分配和调度的基本单位。每个进程都有自己的地址空间、文件描述符、环境变量等。进程可以包含一个或多个线程,每个线程共享进程的资源。
AI: fork() 系统调用的返回值有什么含义?
我: fork() 系统调用的返回值有三种可能:
- 如果
fork()成功,它会在父进程中返回子进程的PID(进程标识符),在子进程中返回0。 - 如果
fork()失败,它会返回-1,并设置全局变量errno以指示具体的错误原因。
AI: exec() 系统调用的变种有哪些?
我: exec() 系统调用有多个变种,它们的主要区别在于参数的传递方式:
execl(): 以固定数量的参数调用新程序。execlp(): 类似于execl(),但会在环境变量PATH中查找可执行文件。execle(): 类似于execl(),但允许传递环境变量。execv(): 以数组形式传递参数。execvp(): 类似于execv(),但会在环境变量PATH中查找可执行文件。execvpe(): 类似于execvp(),但允许传递环境变量。
AI: wait() 系统调用的参数和返回值是什么?
我: wait() 系统调用的原型如下:
pid_t wait(int *status);
- 参数
status是一个指向整数的指针,用于接收子进程的退出状态。如果不需要获取退出状态,可以将status设为NULL。 - 返回值是子进程的PID。如果没有子进程结束,
wait()会阻塞父进程。如果wait()失败,它会返回-1,并设置全局变量errno以指示具体的错误原因。
AI: 举一个使用 fork() 和 exec() 的示例。
我: 当然,以下是一个使用 fork() 和 exec() 的示例代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);fprintf(stderr, "Failed to execute ls\n");return 1;} else {// 父进程printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0;
}
在这个例子中,父进程调用 fork() 创建一个子进程。子进程调用 execlp() 执行 /bin/ls 命令,列出当前目录的详细信息。父进程调用 wait() 等待子进程结束,然后打印一条消息表示子进程已经结束。
学习实践过程遇到的问题与解决方式
问题1:fork() 调用后,子进程和父进程同时运行导致输出混乱
描述:在使用 fork() 创建子进程后,子进程和父进程同时运行,导致输出混乱,难以区分哪个输出来自哪个进程。
解决方式:
- 使用
sleep()临时解决:#include <stdio.h> #include <unistd.h> #include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程sleep(1); // 让子进程稍微延迟一下printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);} else {// 父进程printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0; } - 使用
wait()确保子进程先结束:#include <stdio.h> #include <unistd.h> #include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);} else {// 父进程wait(NULL); // 等待子进程结束printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);printf("Child process finished\n");}return 0; }
问题2:exec() 调用失败,程序无法执行新程序
描述:在调用 exec() 系列函数时,程序无法成功执行新程序,导致程序挂起或报错。
解决方式:
- 检查路径和文件名:
确保提供的路径和文件名是正确的。如果使用execlp()或execvp(),确保环境变量PATH中包含了可执行文件的路径。 - 检查错误信息:
使用perror()或strerror(errno)打印详细的错误信息。#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程execlp("/bin/ls", "ls", "-l", NULL);perror("Failed to execute ls"); // 打印错误信息return 1;} else {// 父进程wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0; }
问题3:open() 系统调用失败,无法打开文件
描述:在调用 open() 系统调用时,无法打开指定的文件,导致程序出错。
解决方式:
- 检查文件路径和权限:
确保文件路径是正确的,并且当前用户有权限访问该文件。 - 检查错误信息:
使用perror()或strerror(errno)打印详细的错误信息。#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h>int main() {int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {fprintf(stderr, "Error opening file: %s\n", strerror(errno));return 1;}close(fd);return 0; }
问题4:wait() 调用后,父进程无法正确捕获子进程的退出状态
描述:在调用 wait() 系统调用后,父进程无法正确捕获子进程的退出状态,导致程序逻辑出错。
解决方式:
使用 WIFEXITED 和 WEXITSTATUS 宏:
使用 WIFEXITED 检查子进程是否正常退出,使用 WEXITSTATUS 获取子进程的退出状态。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程execlp("/bin/ls", "ls", "-l", NULL);perror("Failed to execute ls");return 1;} else {// 父进程int status;pid_t child_pid = wait(&status);if (WIFEXITED(status)) {printf("Child process %d exited with status %d\n", child_pid, WEXITSTATUS(status));} else {printf("Child process %d terminated abnormally\n", child_pid);}}return 0;
}
问题5:环境变量传递失败,子进程无法获取正确的环境变量
描述:在使用 exec() 系列函数时,子进程无法获取正确的环境变量,导致程序出错。
解决方式:
检查环境变量的传递方式:
确保在调用 exec() 系列函数时正确传递了环境变量。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程char *new_env[] = {"PATH=/usr/bin:/bin", "MY_VAR=value", NULL};execle("/bin/ls", "ls", "-l", NULL, new_env);perror("Failed to execute ls");return 1;} else {// 父进程wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0;
}
参考资料
- HeadFirstC嗨翻C语言
- 通义千问
- Linux System Calls
- Process Control in Linux
- Error Handling in C
- 课程 mindmap
- Mermaid Live Editor
相关文章:
第九周预习报告
文章目录 第九周预习报告学习内容AI 对学习内容的总结章节概述内容总结 对知识总结的反思思维导图基于AI的学习知识点1:系统调用知识点2:进程控制 学习实践过程遇到的问题与解决方式问题1:fork() 调用后,子进程和父进程同时运行导…...
【分享】这篇教程助力你成为 JavaScript 糕手!(四)
第四章:运算符与表达式 4.1 算术运算符 加法运算符():用于数字相加,如console.log(5 3);结果为8。 当用于字符串时,它表示字符串拼接。例如console.log(‘Hello’ ‘world’);输出Hello world。如果一个操…...
双亲委派模型的破坏
双亲委派模型的第一次“被破坏”其实发生在双亲委派模型出现之前--即JDK1.2发布之前。由于双亲委派模型是在JDK1.2之后才被引入的,而类加载器和抽象类java.lang.ClassLoader则是JDK1.0时候就已经存在,面对已经存在 的用户自定义类加载器的实现代码,Java设计者引入双亲委派模…...
Android关机流程知多少?
在 Android 中,关机流程涉及系统各个组件的协同工作,确保设备在断电之前能够安全地关闭所有活动并保存数据。以下是 Android 系统中关机流程的详细介绍: 1. 用户触发关机请求 关机流程由用户的操作触发,通常有以下几种方式&#…...
深入理解指针end(总结篇)
如果有不会的智识点,请移动到博主前四篇指针博客! 可以当一个指针智商检阅博客看。 看看你是否掌握了这些知识 1:内存,指针变量 内存单元的编号地址指针; 指针变量和其他变量没有区别,指针变量是来存放…...
C# 程序暂停的两种方式
C# 程序暂停的两种方式:EventWaitHandle 与 volatile bool pause 在C#中,线程控制是多线程编程的重要组成部分,其中实现暂停的需求经常出现。本文将详细探讨使用EventWaitHandle和设置volatilebool来实现线程暂停的不同方式,它们…...
【LeetCode】【算法】160.相交链表
Leetcode 160. 相交链表 题目描述 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 思路 AB,一个指针,访问完A访问B;另一个指针&#…...
光伏破局 引领能源革命
为进一步推进商业信用体系建设,促进企业诚实守信经营,面向企业普及诚信与品牌建设的意义,指导企业加强诚信品牌建设,提升其整体竞争力,“崛起的民族品牌”专题系列节目以诚信为内涵,在全国范围内遴选出有行…...
Jenkins声明式Pipeline流水线语法示例
系列文章目录 docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等) docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法 文章目录 系列文章目录jenkins流水线基础1、pipeline1.1、什么是pipeline?1.2、为什么使用pi…...
互联网技术净土?原生鸿蒙开启全新技术征程
鸿蒙生态与开发者的崭新机会 HarmonyOS NEXT承载着华为对未来操作系统的深刻理解,如今已发展为坚实的数字底座。它不仅在技术层面取得了全面突破,还在中国操作系统市场中站稳了脚跟。 当前,HarmonyOS NEXT的代码行数已超过1.1亿,…...
关于Django 模型字段 `choices`自定义数据类型的枚举——补充
文章目录 1. 处理 datetime 类型的 choices2. 处理 time 类型的 choices3. 处理 Decimal 类型的 choices4. 处理 UUID 类型的 choices5. 处理 float 类型的 choices 在 Choices 类的基础上扩展,可以将 choices 与特定数据类型(如 date 或 datetime&a…...
CAP理论的延申--BASE理论
上一篇文章我简单介绍了一下什么是CAP理论,本篇文章讲解一下随着技术的演变,CAP理论是如何发展为BASE理论的。 CAP理论回顾 首先我们回顾一下CAP理论,CAP理论指得是分布式系统发生网络等故障时,不同节点之间无法同步数据…...
【傻呱呱】phpMyAdmin怎样给特定用户授权特定数据库权限?
前期准备 phpMyAdmin数据库(MySQL) END...
『VUE』21. 组件注册(详细图文注释)
目录 组件注册局部注册全局注册全局注册示例总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 组件注册 组件注册有两种方式:全局注册和局部注册。全局注册只需要注册依次,其他组件可以直接调用无需再次像局部注册一…...
如何产看SQL 查询的执行时间
要查看 SQL 查询的执行时间,尤其是毫秒级别,可以使用以下几种方法: 方法 1:使用 SET STATISTICS TIME 查看执行时间 SET STATISTICS TIME 会显示执行时间的详细信息,包括 CPU 时间和总耗时。启用后,SQL S…...
计算机网络——路由器构成
算路由表是分布式去算——你算你的,我算我的 输出队列非先来先传 调度发生在哪里 缓存队列一般是应对——来数据方向的速度过快问题...
架构师之路-学渣到学霸历程-48
实现域名跳转的实验 今天继续还是分享域名跳转的实验;继续整,看看效果 意思就是你本来访问www.liangjiawei.net的网站然后跳转到blog.liangjiawei.net的网站 1、基础的环境部署 安装好nginx(这里最好的就是干净的环境)创建两个…...
HappyChart——一款简单好用的专业绘图软件
HappyChart是一款新出的专业绘图软件,灵感来自于类PS软件,它是以图层的方式进行绘图。相比与Excel图表或其他专业绘图软件,HappyChart界面简洁明了,操作简单,没有复杂的选项,它只调整绘图相关参数即可实时展…...
【Linux】进程信号全攻略(二)
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 再谈信号的捕捉 🦋 关于信号捕捉的细节部分(sigaction函数) 二:🔥 穿插话题 - 操作系统是怎么运…...
redis用法(二)
文章目录 02-redis数据类型篇生产环境下的redis实况图 1.全局命令redis数据存储格式set设置k-v查看当前redis的key的数量危险命令,新手请在于超老师陪同下执行为什么危险?如何正确搜索redis的key 查看库下有多少个key查询redis库信息切换redis库查看key是…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...
