Linux C++
一、引言
冯诺依曼架构是现代计算机系统的基础,它的提出为计算机的发展奠定了理论基础。在学习 C++ 和 Linux 系统时,理解冯诺依曼架构有助于我们更好地理解程序是如何在计算机中运行的,包括程序的存储、执行和资源管理。这对于编写高效、可靠的 C++ 程序以及更好地利用 Linux 系统资源非常重要。
二、冯诺依曼架构概述
存储程序概念
存储程序是冯诺依曼架构的核心思想之一。在 C++ 中,当我们编写源代码时,代码和数据都存储在文件中。经过编译和链接过程,生成的可执行文件存储在存储设备上。当我们运行程序时,可执行文件被加载到内存中,CPU 从内存中读取指令和数据,并按顺序执行。例如:
#include
using namespace std;
int main() {
int a = 5;
int b = 10;
int c = a + b;
cout << c << endl;
return 0;
}
在这个简单的 C++ 程序中,代码和数据(变量 a、b 和 c)都存储在内存中。编译器将源代码转换为机器代码,存储在可执行文件中,加载后 CPU 会执行指令,如将 5 和 10 存储在内存中,执行加法操作,将结果存储在 c 中,然后将 c 的值输出。
运算器
运算器负责执行算术和逻辑运算。C++ 中的运算符对应于运算器的操作:
#include
using namespace std;
int main() {
int result = (10 > 5) && (20 < 30); // 逻辑运算
int sum = 10 + 20; // 算术运算
cout << result << " " << sum << endl;
return 0;
}
这里,>、<、&& 和 + 运算符的操作由运算器执行。编译器将这些运算符转换为相应的机器指令,运算器根据指令进行运算。
控制器
控制器决定程序的执行顺序。C++ 中的流程控制语句体现了这一点:
#include
using namespace std;
int main() {
int num = 10;
if (num > 5) {
cout << “Greater than 5” << endl;
} else {
cout << “Less than or equal to 5” << endl;
}
for (int i = 0; i < 5; ++i) {
cout << i << endl;
}
return 0;
}
控制器根据 if 条件决定执行哪个分支,以及根据 for 循环的条件决定循环次数。
存储器
Linux 系统有多种存储器。在 C++ 中,我们可以这样使用内存:
#include
#include
using namespace std;
int main() {
int* ptr = new int[10]; // 动态内存分配
for (int i = 0; i < 10; ++i) {
ptr[i] = i;
}
delete[] ptr; // 释放内存
return 0;
}
这里使用 new 进行动态内存分配,操作的是主存。指针 ptr 指向分配的内存块,使用完后使用 delete[] 释放内存,以避免内存泄漏。
输入输出设备
在 C++ 中,标准输入输出流提供了方便的 I/O 操作:
#include
#include
using namespace std;
int main() {
int num;
cout << "Enter a number: ";
cin >> num; // 从键盘输入
cout << "You entered: " << num << endl;
ofstream outfile("output.txt"); // 向文件输出
outfile << "Hello, World!" << endl;
outfile.close();
return 0;
}
三、冯诺依曼架构在 Linux 系统中的体现
进程管理
在 Linux 中,进程是程序的执行实例。使用 C++ 可以这样创建进程:
#include
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程
std::cout << “Child process” << std::endl;
exit(0);
} else if (pid > 0) {
// 父进程
std::cout << “Parent process” << std::endl;
wait(NULL);
} else {
std::cerr << “Fork failed” << std::endl;
}
return 0;
}
这里 fork 系统调用创建进程,wait 等待子进程结束,这些操作由控制器协调。
内存管理
Linux 使用虚拟内存,C++ 程序可以使用 mmap 等系统调用进行内存映射:
#include
#include <sys/mman.h>
#include <unistd.h>
int main() {
void* ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (ptr == MAP_FAILED) {
std::cerr << “mmap failed” << std::endl;
return 1;
}
((int*)ptr)[0] = 10;
std::cout << ((int*)ptr)[0] << std::endl;
if (munmap(ptr, 4096) == -1) {
std::cerr << “munmap failed” << std::endl;
return 1;
}
return 0;
}
文件系统
C++ 中的文件操作:
#include
#include
#include
int main() {
std::string filename = “test.txt”;
std::ofstream file(filename);
if (file.is_open()) {
file << “This is a test file.” << std::endl;
file.close();
} else {
std::cerr << “Could not open the file.” << std::endl;
}
std::ifstream inputFile(filename);
std::string line;
if (inputFile.is_open()) {
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
inputFile.close();
} else {
std::cerr << “Could not open the file.” << std::endl;
}
return 0;
}
四、C++ 与 Linux 系统调用的结合
系统调用的重要性
系统调用允许 C++ 程序访问操作系统的资源。例如,使用 open 系统调用打开文件:
#include
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open(“test.txt”, O_RDWR | O_CREAT, 0644);
if (fd == -1) {
std::cerr << “Failed to open file” << std::endl;
return 1;
}
write(fd, “Hello, World!”, 12);
close(fd);
return 0;
}
系统调用的实现
可以使用 syscall 函数直接调用系统调用:
#include
#include <sys/syscall.h>
#include <unistd.h>
int main() {
long result = syscall(SYS_getpid);
std::cout << "Process ID: " << result << std::endl;
return 0;
}
五、C++ 程序在冯诺依曼架构下的性能优化
编译器优化
使用编译器选项优化代码:
g++ -O2 myprogram.cpp -o myprogram
内存优化
使用数据结构优化内存使用:
#include
#include
using namespace std;
int main() {
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
for (int num : v) {
cout << num << endl;
}
return 0;
}
六、案例分析
案例一:简单的网络服务器程序
考虑一个使用 C++ 编写的简单 TCP 网络服务器程序,以下是一个简化的示例:
#include
#include
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include
#include <arpa/inet.h>
#include
// 处理客户端连接的函数
void handleClient(int clientSocket) {
char buffer[1024];
while (true) {
memset(buffer, 0, sizeof(buffer));
int bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0);
if (bytesRead <= 0) {
break;
}
std::string message(buffer);
std::cout << "Received from client: " << message << std::endl;
std::string response = "Server received: " + message;
send(clientSocket, response.c_str(), response.length(), 0);
}
close(clientSocket);
}
int main() {
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == -1) {
std::cerr << “Failed to create socket” << std::endl;
return 1;
}
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(8080);
serverAddress.sin_addr.s_addr = INADDR_ANY;if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1) {std::cerr << "Failed to bind socket" << std::endl;close(serverSocket);return 1;
}if (listen(serverSocket, 5) == -1) {std::cerr << "Failed to listen on socket" << std::endl;close(serverSocket);return 1;
}std::cout << "Server is listening on port 8080" << std::endl;while (true) {struct sockaddr_in clientAddress;socklen_t clientAddressLength = sizeof(clientAddress);int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength);if (clientSocket == -1) {std::cerr << "Failed to accept connection" << std::endl;continue;}std::cout << "Client connected" << std::endl;std::thread clientThread(handleClient, clientSocket);clientThread.detach();
}close(serverSocket);
return 0;
}
分析:
存储程序方面:
整个程序的源代码存储在文件系统中,在编译后生成可执行文件,可执行文件存储在存储设备上。当程序启动时,操作系统将其加载到内存中,遵循存储程序的概念。例如,函数 handleClient 和 main 函数以及相关的字符串常量和变量,都存储在内存中。
数据如 serverSocket、clientSocket 和 buffer 等变量也存储在内存中,程序根据需要对其进行操作。7
运算器和控制器:
运算器在程序中参与各种计算操作,虽然此服务器程序主要是数据的收发和处理,但在 handleClient 函数中,strlen 函数的调用、字符串拼接等操作涉及运算器的运算。
控制器协调程序的执行顺序,决定了程序流程。例如,在 main 函数中,程序按顺序执行 socket 函数创建套接字,bind 函数绑定地址,listen 函数监听端口,accept 函数接受连接,以及 recv 和 send 函数处理数据传输。while 循环和 if 条件判断语句控制程序的流程,这些都是控制器在起作用。
当 accept 函数接收到新连接时,使用 std::thread 创建新线程,控制器需要协调线程的创建和执行,将 handleClient 函数分配到新线程中运行,同时使用 detach 操作,这涉及到操作系统的线程调度,也是控制器的重要体现。
存储器:
内存用于存储程序代码、变量和套接字信息等。动态分配的内存包括为 buffer 分配的空间,它的大小是 1024 字节。如果有大量的客户端连接,多个 handleClient 线程同时运行,将需要更多的内存用于存储它们各自的 buffer 数据。
系统还使用虚拟内存机制,操作系统将根据需要将程序的部分内容从磁盘交换到内存或从内存交换到磁盘,以确保程序的运行。例如,当内存不足时,一些不活跃的线程的数据可能会被交换到磁盘,这涉及到 Linux 系统的内存管理和冯诺依曼架构中的存储器层次结构。
输入输出设备:
输入设备:网络套接字接收来自网络的数据,可视为输入设备,这些数据通过网络接口卡进入系统,存储在 buffer 中。
输出设备:服务器将响应数据通过网络发送出去,通过 send 函数,数据从内存发送到网络接口卡,然后发送给客户端,这里的网络接口卡可视为输出设备。
性能优化:
内存优化:
可以考虑使用内存池技术,对于频繁创建和销毁的 buffer,使用内存池可以减少内存分配和释放的开销,提高性能。例如,可以预先分配一定数量的 buffer 并存储在一个队列中,需要时从队列中获取,使用完后放回队列,避免频繁调用 new 和 delete 或 malloc 和 free。
优化数据结构的使用,比如使用更紧凑的数据结构存储连接信息,避免不必要的内存浪费。
运算器优化:
可以对字符串处理进行优化,如使用更高效的字符串操作函数或库,提高字符串处理速度。
减少冗余计算,例如避免在 handleClient 函数中重复计算 response 的长度,可以在计算一次后存储结果。
案例二:文件处理程序
以下是一个简单的文件处理程序,它读取文件内容,对数据进行处理,然后将结果写入另一个文件:
#include
#include
#include
#include
#include
int main() {
std::ifstream inputFile(“input.txt”);
std::vectorstd::string lines;
std::string line;
while (std::getline(inputFile, line)) {
lines.push_back(line);
}
inputFile.close();
std::transform(lines.begin(), lines.end(), lines.begin(), [](const std::string& s) {std::string result = s;std::transform(s.begin(), s.end(), result.begin(), ::toupper);return result;
});std::ofstream outputFile("output.txt");
for (const auto& l : lines) {outputFile << l << std::endl;
}
outputFile.close();
return 0;
}
分析:
存储程序方面:
程序的代码存储在磁盘上,当运行时,操作系统将其加载到内存中。变量 lines 和 line 存储在内存中,文件的内容也会存储在内存中(存储在 lines 向量中)。
运算器和控制器:
运算器参与字符串处理操作,在 std::transform 函数中,对每个字符进行 toupper 操作,将小写字符转换为大写字符,这涉及字符的 ASCII 码运算。
控制器协调程序的执行,使用 while 循环读取文件内容,使用 std::transform 进行数据转换,使用 for 循环将结果写入文件。
存储器:
内存存储程序代码、变量 lines 和 line 以及文件内容。如果文件很大,可能会占用大量内存,需要考虑内存使用问题。
可能会涉及内存的动态分配,当 lines 向量存储大量数据时,会动态调整其容量,涉及内存的重新分配。
输入输出设备:
输入设备:文件 input.txt 作为输入源,通过文件系统和磁盘读取数据。
输出设备:将处理结果写入文件 output.txt,通过文件系统和磁盘进行存储。
性能优化:
内存优化:
可以考虑分批读取文件,避免一次性将大文件的全部内容加载到内存中,减少内存压力。例如,每次读取一定行数的数据,处理完后再读取下一批。
对于 lines 向量,可以提前预留一定的容量,避免频繁的扩容操作,提高性能。
运算器优化:
可以使用多线程或并行算法对文件内容进行处理,提高转换速度,充分利用多核处理器,发挥运算器的并行处理能力。
七、结论
通过对冯诺依曼架构在 C++ 程序中的深入理解,我们可以更好地把握程序的运行机制,从而优化程序性能和资源利用。在 C++ 编程中,尤其是在 Linux 系统下,我们可以看到程序的每个操作都可以在冯诺依曼架构的框架下找到对应的部分。
对于存储程序,我们需要考虑程序和数据的存储和加载过程,确保代码和数据的高效存储和加载,避免不必要的存储开销。
运算器和控制器的操作反映在程序的执行逻辑和计算操作中,合理的程序结构和算法可以提高运算器的效率,控制器的合理调度可以确保程序的正确执行顺序和资源的合理利用。例如,在多线程或多进程程序中,合理的并发控制和同步机制可以让控制器更有效地调度资源。
存储器的使用直接影响程序的性能和可扩展性。合理的内存管理,包括动态内存分配、内存池的使用、内存数据结构的选择等,能够避免内存泄漏、内存溢出等问题,提高程序的稳定性和性能。
输入输出设备的操作体现了程序与外界的交互,在 C++ 中,我们使用不同的 I/O 方式(如文件 I/O、网络 I/O),这些操作涉及到操作系统和硬件的交互,需要考虑如何优化 I/O 操作,提高数据传输效率。
随着计算机技术的发展,虽然现代计算机在很多方面已经对冯诺依曼架构进行了扩展和优化,如多核处理器、缓存层次结构、并行计算等,但冯诺依曼架构的基本原理仍然是我们理解程序运行的基础。对于 C++ 程序员来说,这种理解可以帮助我们在开发程序时更好地利用 Linux 系统的资源,包括处理器、内存和 I/O 设备,设计出更加高效、可靠、可扩展的程序。
未来,随着技术的不断进步,如非冯诺依曼架构的探索(如量子计算、神经形态计算),我们可能会看到新的计算架构,但冯诺依曼架构仍然会在很长一段时间内作为我们开发和理解传统计算机程序的基础。通过理解冯诺依曼架构,我们能够更好地适应这些变化,将新的技术融入到我们的编程实践中,为计算机系统的发展和创新提供有力的支持。同时,这种对冯诺依曼架构的理解也为我们学习更高级的计算机系统概念,如操作系统、编译器设计、计算机网络等提供了坚实的基础。在 Linux 系统中,我们可以更深入地理解进程管理、内存管理、文件系统和设备驱动等方面的工作原理,进而在 C++ 编程中更加得心应手,从系统层面优化程序,解决复杂的编程问题,开发出高质量的软件应用程序和系统软件。在 C++ 学习和实践中,不断结合对冯诺依曼架构的理解,将使我们的编程能力更上一层楼,不仅能写出功能正确的程序,还能写出高性能、低资源消耗的程序,更好地服务于各种应用场景,如数据处理、网络服务、嵌入式系统开发等。
1
相关文章:

Linux C++
一、引言 冯诺依曼架构是现代计算机系统的基础,它的提出为计算机的发展奠定了理论基础。在学习 C 和 Linux 系统时,理解冯诺依曼架构有助于我们更好地理解程序是如何在计算机中运行的,包括程序的存储、执行和资源管理。这对于编写高效、可靠的…...
gradio 合集
知识点 1:基本 Chatbot 创建 import gradio as gr 定义历史记录 history [gr.ChatMessage(role“assistant”, content“How can I help you?”), gr.ChatMessage(role“user”, content“What is the weather today?”)] 使用历史记录创建 Chatbot 组件 ch…...

996引擎 - NPC-动态创建NPC
996引擎 - NPC-动态创建NPC 创建脚本服务端脚本客户端脚本添加自定义音效添加音效文件修改配置参考资料有个小问题,创建NPC时没有控制朝向的参数。所以。。。自己考虑怎么找补吧。 多重影分身 创建脚本 服务端脚本 Mir200\Envir\Market_Def\test\test001-3.lua -- NPC八门名…...

论文阅读(十三):复杂表型关联的贝叶斯、基于系统的多层次分析:从解释到决策
1.论文链接:Bayesian, Systems-based, Multilevel Analysis of Associations for Complex Phenotypes: from Interpretation to Decision 摘要: 遗传关联研究(GAS)报告的结果相对稀缺,促使许多研究方向。尽管关联概念…...

代码随想录算法训练营第三十九天-动态规划-198. 打家劫舍
动规五部曲 dp[i]表示在下标为i的房间偷或不偷与前面所偷之和所能获得的最大价值递推公式:dp[i] std::max(dp[i - 2] nums[i], dp[i - 1])初始化:要给dp[0]与dp[1]来给定初始值,因为递推公式有-1与-2。dp[0] nums[0], dp[1] std::max(num…...

CF1098F Ж-function
【题意】 给你一个字符串 s s s,每次询问给你 l , r l, r l,r,让你输出 s s s l , r sss_{l,r} sssl,r中 ∑ i 1 r − l 1 L C P ( s s i , s s 1 ) \sum_{i1}^{r-l1}LCP(ss_i,ss_1) ∑i1r−l1LCP(ssi,ss1)。 【思路】 和前一道题一样&#…...

Python 函数魔法书:基础、范例、避坑、测验与项目实战
Python 函数魔法书:基础、范例、避坑、测验与项目实战 内容简介 本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南,旨在帮助读者从基础入门到项目实战,全面提升编程能力。文章结构由 5 个版块组成,内容层层递进…...

vim交换文件的作用
1.数据恢复:因为vim异常的退出,使用交换文件可以恢复之前的修改内容。 2.防止多人同时编辑:vim检测到交换文件的存在,会给出提示,以避免一个文件同时被多人编辑。 (vim交换文件的工作原理:vim交换文件的工作…...

[NOI1995] 石子合并
[NOI1995] 石子合并 题目描述 在一个圆形操场的四周摆放 N N N 堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的 2 2 2 堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。 试设计出一个算法,计算出将 …...

真正的智能与那只蝴蝶
“蝴蝶效应”可以展开为对智能本质与大算力关系的追问,其中“蝴蝶”作为隐喻可能指向多重维度——从混沌理论的“蝴蝶效应”到庄子“物我两忘”的蝴蝶之梦。这种并置本身暗示了智能与宇宙秩序、认知边界之间的深刻张力。以下从三个层面展开分析:一、混沌…...

C++小病毒-1.0勒索(更新次数:2)
内容供学习使用,不得转卖,代码复制后请1小时内删除,此代码会危害计算机安全,谨慎操作 在C20环境下,并在虚拟机里运行此代码!,病毒带来后果自负! 使用时请删除在main()里的注释,并修改位置至C:\\(看我代码注释)//可以改成WIN Main() #include <iostream> #i…...

Node.js 的底层原理
Node.js 的底层原理 1. 事件驱动和非阻塞 I/O Node.js 基于 Chrome V8 引擎,使用 JavaScript 作为开发语言。它采用事件驱动和非阻塞 I/O 模型,使其轻量且高效。通过 libuv 库实现跨平台的异步 I/O,包括文件操作、网络请求等。 2. 单线程事…...

基于Django的豆瓣影视剧推荐系统的设计与实现
【Django】基于Django的豆瓣影视剧推荐系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用了Python作为后端开发语言,采用Django作为后端架构,结…...

P10638 BZOJ4355 Play with sequence Solution
Description 给定 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1,a2,⋯,an),有 m m m 个操作,分以下三种: assign ( l , r , k ) \operatorname{assign}(l,r,k) assign(l,r,k):对每个 i ∈ [ l , r ] i \…...

MySQL误删数据怎么办?
文章目录 1. 从备份恢复数据2. 通过二进制日志恢复数据3. 使用数据恢复工具4. 利用事务回滚恢复数据5. 预防误删数据的策略总结 在使用MySQL进行数据管理时,误删数据是一个常见且具有高风险的操作。无论是因为操作失误、系统故障,还是不小心执行了删除命…...

项目测试之MockMvc
文章目录 基础基础概念Mockxxx一般实现文件位置 实战MockMvc与Test注解不兼容RequestParams参数RequestBody参数 基础 基础概念 定义:是Spring框架提供的一种用于测试Spring MVC控制器的工具,它允许开发者在不启动完整的web服务器的情况下,…...

Unbutu虚拟机+eclipse+CDT编译调试环境搭建
问题1: 安装CDT,直接Help->eclipse Market space-> 搜cdt , install,等待重启即可. 问题2:C变量不识别vector ’could not be resolved 这是库的头文件没加好,右键Properties->C Build->Enviroment,增加…...

时间轮:XXL-JOB 高效、精准定时任务调度实现思路分析
大家好,我是此林。 定时任务是我们项目中经常会遇到的一个场景。那么如果让我们手动来实现一个定时任务框架,我们会怎么做呢? 1. 基础实现:简单的线程池时间轮询 最直接的方式是创建一个定时任务线程池,用户每提交一…...

CTF-web: Python YAML反序列化利用
PyYAML存在以下几个特殊标签,如果这些标签被不安全的解析,会造成解析漏洞 从 PyYaml 版本 6.0 开始,load 的默认加载器已切换到 SafeLoader,以降低远程代码执行的风险。更新后易受攻击的是 yaml.unsafe_load 和 yaml.load(input, Loaderyaml.UnsafeLoade…...

代码随想录算法训练营第三十八天-动态规划-完全背包-139.单词拆分
类似于回溯算法中的拆分回文串题目是要求拆分字符串,问这些字符串是否出现在字典里。但这道题可以反着来考虑,从字典中的单词能不能组成所给定的字符串 如果这样考虑, 这个字符串就背包,容器字典中的单词就是一个一个物品问题就转…...

ML基础-Jupyter notebook中的魔法命令
在 Jupyter Notebook 或 IPython 环境中,“魔法命令”(Magic Commands)是一些以百分号(%)或惊叹号(!)开头的特殊命令,用于执行一些与代码运行环境相关的操作,而不仅仅是执行普通的 P…...

Zookeeper入门部署(单点与集群)
本篇文章基于docker方式部署zookeeper集群,请先安装docker 目录 1. docker初期准备 2.启动zookeeper 2.1 单点部署 2.2 集群部署 3. Linux脚本实现快速切换启动关闭 1. docker初期准备 拉取zookeeper镜像 docker pull zookeeper:3.5.6 如果拉取时间过长…...

Kafa分区策略实现
引言 Kafka 的分区策略决定了生产者发送的消息会被分配到哪个分区中,合理的分区策略有助于实现负载均衡、提高消息处理效率以及满足特定的业务需求。 轮询策略(默认) 轮询策略是 Kafka 默认的分区策略(当消息没有指定键时&…...

Pyside/Pyqt中QWebEngineView和QWebEnginePage的区别
在 PySide/Qt 的 WebEngine 模块中,QWebEngineView 和 QWebEnginePage 是两个紧密相关但职责不同的类。以下是它们的核心区别和关系: 1. 职责区分 类名核心职责模块归属QWebEngineView作为可视化的窗口部件(Widget),负…...

Kafka的内部通信协议
引言 kafka内部用到的常见协议和优缺点可以看看原文 Kafka用到的协议 本文奖详细探究kafka核心通信协议和高性能的关键 网络层通信的实现 基于 Java NIO:Kafka 的网络通信层主要基于 Java NIO 来实现,这使得它能够高效地处理大量的连接和数据传输。…...

强大到工业层面的软件
电脑数据删不干净,简直是一种让人抓狂的折磨!明明已经把文件扔进了回收站,清空了,可那些残留的数据就像牛皮癣一样,怎么也除不掉。这种烦恼简直无处不在,让人从头到脚都感到无比烦躁。 首先,心…...

数据分析和AI丨应对AI实施挑战,工程领域AI应用的五大方法
工程领域的人工智能 (AI) 已经开始发挥价值,低代码和无代码工具正在使曾经仅属于专业数据科学家的 AI 能力变得大众化。 然而,并非工程领域的每个人都能从中受益,使用新的便捷的 AI 工具提高工作效率并不难,…...

54. UDP协议
UDP协议 UDP(User Datagram Protocol,用户数据报协议)是一个无连接的传输层协议,它提供简单的、不可靠的信息传送服务。与TCP(传输控制协议)不同,UDP不提供数据包的排序、错误检查(仅…...

AJAX笔记入门篇
黑马程序员视频地址: 黑马程序员前端AJAX入门到实战全套教程https://www.bilibili.com/video/BV1MN411y7pw?vd_source0a2d366696f87e241adc64419bf12cab&spm_id_from333.788.videopod.episodes&p2https://www.bilibili.com/video/BV1MN411y7pw?vd_source…...

深入解析Java集合框架:春招面试要点
在上一篇文章中,我们深入探讨了Java核心基础,这是学习Java的基石。而在实际的Java开发中,集合框架的使用频率极高,它为我们提供了丰富的数据结构和算法实现,极大地提高了开发效率。对于春招面试来说,集合框…...