【0】复习

sockfd=socket();
//指定网络信息
bind();
listen();
//创建表 fd_set rfds,tempfds;
FD_ZERO();
FD_SET(sockfd);
max =sockfd
while(1)
{
    tempfds=rfds;
    select(max+1,&tempfds)
    if(FD_ISSET(scokfd,&tempfds))
    {    acceptfd=accept();
        FD_SET(acceptfd,&rfds);
        if(max<acceptfd)max=acceptfd;
    }
    for(int i=sockfd+1;i<=max;i++)
    {    if(FD_ISSET(i,&tempfds))
        {    ret=recv(i);
            if(ret==0)
            {close(i);    FD_CLR(i,&rfds);
                while(!FD_ISSET(max,&rfds))max--;        
            }
            printf();
        }
    }
}

【1】组播(多播)

理论

单播方式只能发给一个接收方。

广播方式发给所有的主机。过多的广播会大量占用网络带宽,造成广播风暴,影响正常的通信。

播是一个人发送,加入到多播组的人接收数据。

多播方式既可以发给多个主机,又能避免像广播那样带来过多的负载(每台主机要到传输层才能判断广播包是否要处理)

多播地址

D类:224.0.0.1-239.255.255.254

接收者

  1. 创建套接字(socket)
  2. 置多播属性,将自己的IP加入到多播组中

  1. 指定网络信息
  2. 绑定套接字(bind)
  3. 接收消息(recvfrom)
  4. 关闭套接字(close)
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{char buf[128] = {0};int ret = 0;int acceptfd;// 1.创建数据包套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket err");return -1;}printf("sockfd:%d\n", sockfd);// 设置多播属性struct ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr(argv[2]); // 组播IP
    mreq.imr_interface.s_addr = INADDR_ANY;         // 自己IPsetsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq));// 指定网络信息struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[1])); // 端口// saddr.sin_addr.s_addr = inet_addr("192.168.50.79"); // IP//  saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); // IP
    saddr.sin_addr.s_addr = INADDR_ANY; // IPint len = sizeof(caddr);// 绑定:绑定服务器信息(IP地址\端口号等)if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0){perror("bind err");return -1;}printf("bind okk\n");while (1){// read(acceptfd,buf,sizeof(buf));
        ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&caddr, &len);if (ret < 0){perror("recv err");return -1;}elseprintf("ip:%s port:%d says:%s\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port), buf);memset(buf, 0, sizeof(buf));}close(sockfd);return 0;
}

发送者

  1. 创建套接字(socket)
  2. 指定网络(服务器)信息
  3. 发送消息(sendto)
  4. 关闭套接字(close)

【2】数据库:SQLite

SQLITE的存储结构:B树

1. 数据库安装

测试数据库是否安装

sqlite3 -version

2. 数据库安装命令

将压缩包拿到虚拟机路径下

tar xf sqlite-autoconf-3460000.tar.gz

cd sqlite-autoconf-3460000

./configure

make

sudo make install

3.  图形化工具的安装

sudo apt-get install sqlitebrowser

2. 数据库的概念

数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。

数据库是存放数据的仓库。它的存储空间很大,可以存放百万条、千万条、上亿条数据。但是数据库并不是随意地将数据进行存放,是有一定的规则的,否则查询的效率会很低。当今世界是一个充满着数据的互联网世界,充斥着大量的数据。即这个互联网世界就是数据世界。数据的来源有很多,比如出行记录、消费记录、浏览的网页、发送的消息等等。

3. 常用的数据库

大型数据库 :Oracle

中型数据库 :Server是微软开发的数据库产品,主要支持windows平台

小型数据库 : MySQL是一个小型关系型数据库管理系统。开放源码 (嵌入式不需要存储太多数据)

MySQLSQLite区别:

MySQL和SQLite是两种不同的数据库管理系统,它们在多个方面有所不同。

1. 性能和规模:MySQL通常用于大型应用程序和网站,它可以处理大量数据和高并发访问。SQLite则更适合于小型应用程序或移动设备,因为它是一个轻量级的数据库引擎,不需要独立的服务器进程,可以直接访问本地文件。

2. 部署和配置:MySQL需要单独的服务器进程来运行,需要配置和管理数据库服务器。而SQLite是一个嵌入式数据库,可以直接嵌入到应用程序中,不需要单独的服务器进程。

3. 功能和特性:MySQL提供了更多的功能和高级特性,比如存储过程、触发器、复制和集群支持等。SQLite则是一个轻量级的数据库引擎,功能相对较少,但对于简单的数据存储和检索已经足够。

4. 跨平台支持:SQLite在各种操作系统上都能够运行,而MySQL需要在特定的操作系统上安装和配置数据库服务器。

总之,MySQL适用于大型应用程序和网站,需要处理大量数据和高并发访问,而SQLite适用于小型应用程序或移动设备,对性能和规模要求没有那么高。

4. SQLite基础

SQLite的源代码是C,其源代码完全开放。它是一个轻量级的嵌入式数据库。

SQLite有以下特性:

零配置一无需安装和管理配置;

储存在单一磁盘文件中的一个完整的数据库;

数据库文件可以在不同字节顺序的机器间自由共享;

支持数据库大小至2TB(1024G = 1TB);//嵌入式足够

足够小,全部源码大致3万行c代码,250KB;

比目前流行的大多数数据库对数据的操作要快;

操作方式:

手动:

使用sqlite3工具,手工输入命令

命令行输入

代码:

利用代码编程,调用接口

5. 基本语句的基本使用

【腾讯文档】SQL基础语句基本使用

SQL基础语句基本使用

sqlile3编程

官方文档:List Of SQLite Functions

中本版:SQLite Insert 语句 - SQLite 中文版 - UDN开源文档

头文件:#include <sqlite3.h>

编译:gcc sqlite.c -lsqlite3

6. 函数接口

打开数据库
 

int sqlite3_open(char *path, sqlite3 **db);

功能:打开sqlite数据库,如果数据库不存在则创建它

参数:path: 数据库文件路径

db: 指向sqlite句柄的指针

返回值:成功返回SQLITE_OK(0),失败返回错误码(非零值)

返回错误信息

char *sqlite3_errmsg(sqlite3 *db);

功能: 获取错误信息

返回值:返回错误信息

使用: fprintf(stderr,"sqlite3_open failed %s\n",sqlite3_errmsg(db));

关闭数据库

int sqlite3_close(sqlite3 *db);

功能:关闭sqlite数据库

返回值:成功返回SQLITE_OK,失败返回错误码

执行sql语句接口

int sqlite3_exec(

sqlite3 *db, /* An open database */

const char *sql, /* SQL to be evaluated */

int (*callback)(void*,int,char**,char**), /* Callback function */

void *arg, /* 1st argument to callback */

char **errmsg /* Error msg written here */

);

功能:执行SQL操作

参数:db:数据库句柄

sql:要执行SQL语句

callback:回调函数(满足一次条件,调用一次函数,用于查询)

再调用查询sql语句的时候使用回调函数打印查询到的数据

arg:传递给回调函数的参数

errmsg:错误信息指针的地址

返回值:成功返回SQLITE_OK,失败返回错误码

回调函数:

typedef int (*sqlite3_callback)(void *para, int f_num,

char **f_value, char **f_name);

功能:select:每找到一条记录自动执行一次回调函数

参数:para:传递给回调函数的参数(由 sqlite3_exec() 的第四个参数传递而来)

f_num:记录中包含的字段数目

f_value:包含每个字段值的指针数组(列值)

f_name:包含每个字段名称的指针数组(列名)

返回值:成功返回SQLITE_OK,失败返回-1,每次回调必须返回0后才能继续下次回调

不使用回调函数执行SQL语句(只用于查询)
int sqlite3_get_table(sqlite3 *db, const  char  *sql, char ***resultp,  int *nrow,  int *ncolumn, char **errmsg);功能:执行SQL操作
参数:db:数据库句柄
    sql:SQL语句
    resultp:用来指向sql执行结果的指针
    nrow:满足条件的记录的数目(但是不包含字段名(表头 id name score))
    ncolumn:每条记录包含的字段数目
    errmsg:错误信息指针的地址
返回值:成功返回SQLITE_OK,失败返回错误码

#include <sqlite3.h>
#include <stdio.h>int callback(void *buf, int num, char **value, char **name);int main(int argc, char const *argv[])
{sqlite3 *db;// 打开或创建数据库if (sqlite3_open("stu.db", &db) != SQLITE_OK){fprintf(stderr, "open err:%s\n", sqlite3_errmsg(db));return -1;}printf("open okk\n");// 创建表char *errmsg = NULL;if (sqlite3_exec(db, "create table if not exists stu (id int ,name string,score float)", NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "create err:%s\n", sqlite3_errmsg(db));fprintf(stderr, "create err:%s\n", errmsg);return -1;}printf("create okk\n");// 插入数据/*if(sqlite3_exec(db,"insert into stu values(1,'lihua',0)",NULL,NULL,&errmsg)!=SQLITE_OK){fprintf(stderr, "insert err:%s\n", errmsg);return -1;}printf("insert okk\n");*/int num = 0;printf("请输入要输入的学生人数:");scanf("%d", &num);char sql[64] = {0};int id;char name[32] = {0};float score;for (int i = 0; i < num; i++){printf("请输入学生信息:");scanf("%d %s %f", &id, name, &score);sprintf(sql, "insert into stu values(%d,'%s',%f)", id, name, score);if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "insert err:%s\n", errmsg);return -1;}printf("insert okk\n");}// 查找数据if (sqlite3_exec(db, "select * from stu where id=10", callback, "hello", &errmsg) != SQLITE_OK){fprintf(stderr, "select err:%s\n", errmsg);return -1;}printf("select okk\n");// 专门用于查询的函数// char **result = NULL;// int row, column;// sqlite3_get_table(db, "select * from stu where id=10", &result, &row, &column, &errmsg);// printf("row:%d column:%d\n", row, column);// int k=0;// printf("aaaa:%s ", result[k++]);// for (int i = 0; i <= row; i++)// {//     for (int j = 0; j < column; j++)//         printf("%s ", result[k++]);//     putchar(10);// }// 关闭数据库sqlite3_close(db);return 0;
}// 每查询到一条符合条件的数据,就调用一次此函数
int callback(void *buf, int num, char **value, char **name)
{static int a = 1;printf("******************** \n");printf("%d :%s \n", a++, (char *)buf);// num:列数// name:列名// value:查询到的值for (int i = 0; i < num; i++)printf("%s ", name[i]);putchar(10);for (int i = 0; i < num; i++)printf("%s ", value[i]);putchar(10);return 0; // 必须返回0,不然报错
}

练习:数据库基本语句的使用,并完成下面练习题

sqlite3 stu2.db
CREATE TABLE stu2 (
    学号 VARCHAR(10) PRIMARY KEY,
    姓名 VARCHAR(50),
    年龄 INT,
    性别 VARCHAR(10),
    家庭住址 VARCHAR(100),
    联系电话 VARCHAR(20)
);
ALTER TABLE stu2 ADD 学历 VARCHAR(50);
ALTER TABLE stu2 DROP COLUMN 家庭住址;
INSERT INTO stu2 (学号, 姓名, 年龄, 性别, 联系电话, 学历)
VALUES ('1', 'A', 22, '男', '123456', '小学'), 
('2', 'B', 20, '女', '114567', '初中'),
('3', 'C', 25, '男', '345678', '高中')
('4', 'D', 22, '男', '345678', '大专');UPDATE stu2
SET 学历 = '大专'
WHERE 联系电话 LIKE '11%';DELETE FROM stu2
WHERE 姓名 LIKE 'C%' AND 性别 = '男';SELECT 姓名, 学号
FROM stu2
WHERE 年龄 < 22 AND 学历 = '大专';SELECT 姓名, 性别, 年龄
FROM stu2
ORDER BY 年龄 DESC;

  1. 完成FTP项目

模拟FTP核心原理:客户端连接服务器后,向服务器发送一个文件。文件名可以通过参数指定,服务器端接收客户端传来的文件(文件名随意),如果文件不存在自动创建文件,如果文件存在,那么清空文件然后写入。

项目功能介绍:

均有服务器和客户端代码,基于TCP写的。

在同一路径下,将客户端可执行代码复制到其他的路径下,接下来在不同的路径下运行服务器和客户端。

相当于另外一台电脑在访问服务器。

客户端和服务器链接成功后出现以下提示:三个功能

***********put filename**********//从客户端所在路径上传文件

***********get filename**********//从服务器所在路径下载文件

**************quit***************//退出(可只退出客户端,服务器等待下一个客户端链接)

可拓展功能:客户端可以获取服务器路径下有哪些文件

list:客户端请求文件列表 → 服务器遍历目录 → 发送文件名 → 发送 "end" 结束。

putfile:客户端发送 "put filename" → 服务器创建文件 → 接收数据写入文件 → 收到 "end" 结束。

getfile:客户端发送 "get filename" → 服务器读取文件 → 发送数据 → 发送 "end" 结束。

服务器

#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>void putfile(int, char *);
void getfile(int acceptfd, char *p);int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int ret;
    int acceptfd;
    // 1.创建套接字(socket())------------------------》有手机
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {        perror("socket err");
        return -1;
    }
    printf("sockfd:%d\n", sockfd); // 3
    // 2.指定网络信息--------------------------------------》有号码
    struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[1])); // 网络字节序端口号
    // saddr.sin_addr.s_addr = inet_addr("192.168.51.78"); // 虚拟机IP
    // saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); // 虚拟机IP
    saddr.sin_addr.s_addr = INADDR_ANY; // 虚拟机IP
    int len = sizeof(caddr);
    // 3.绑定套接字(bind())----------------------------》绑定手机(插卡)
    if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        perror("bind err");
        return -1;
    }    printf("bind okk\n");
    // 4.监听套接字(listen())--------------------------》待机
    // 将主动套接字变为被动套接字
    // 队列1(未完成连接队列):4 5 6
    // 队列2(已完成连接队列):3
    if (listen(sockfd, 6) < 0)
    {
        perror("listen err");
        return -1;
    }
    printf("listen okk\n");
    while (1)
    {
        // 5.阻塞等待接收客户端连接请求(accept())-------------》接电话
        acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
        // accept会返回一个用于通信的文件描述符
        // 在tcp服务器中,有两类套接字,一类是socket函数返回(1个),用于链接的文件描述符
        // 一类是accept函数返回的(1个或者多个),用于通信的文件描述符
        if (acceptfd < 0)
        {
            perror("acceptfd err");
            return -1;
        }
        printf("acceptfd:%d\n", acceptfd);
        printf("ip:%s    port: %d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
        // 6.接受发送消息(send()/recv())-------------》通话
        while (1)
        {
            ret = recv(acceptfd, buf, sizeof(buf), 0); //==>read
            if (ret < 0)
            {
                perror("recv err");
                return -1;
            }
            else if (ret == 0)
            {
                printf("client exit\n");
                break;
            }
            printf("buf:%s\n", buf);            if (!strncmp(buf, "put ", 4))
                putfile(acceptfd, buf);
            if (!strncmp(buf, "get ", 4))
                getfile(acceptfd, buf);
            memset(buf, 0, sizeof(buf));
        }        // 7.关闭套接字(close)---------------------------》挂断电话
        close(acceptfd);
    }
    close(sockfd);
    return 0;
}void putfile(int acceptfd, char *p)
{
    int ret = 0;
    int fd = open(p + 4, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0)
    {
        perror("open err");
        return;
    }
    char buf[128] = {0};
    while (1)
    {
        ret = recv(acceptfd, buf, sizeof(buf), 0);
        if (ret < 0)
        {
            perror("recv err");
            return;
        }
        if (!strcmp(buf, "end"))
            break;
        write(fd, buf, strlen(buf));
        memset(buf, 0, sizeof(buf));
    }
}void getfile(int acceptfd, char *p)
{
    char buf[128] = {0};
    int ret = 0;
    int fd = open(p + 4, O_RDONLY);
    if (fd < 0)
    {
        perror("open err");
        return;
    }
    while (1)
    {
        ret = read(fd, buf, sizeof(buf) - 1);
        buf[ret] = '\0';
        if (ret == 0)
            break;
        send(acceptfd, buf, sizeof(buf), 0);
    }
    send(acceptfd, "end", sizeof(buf), 0);
    close(fd);
    return;
}

客户端

#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>void show();
void list(int sockfd);
void putfile(int, char *);
void getfile(int sockfd, char *p);int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int ret;
    // 1.创建套接字(socket())-
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {        perror("socket err");
        return -1;
    }
    printf("sockfd:%d\n", sockfd); // 3
    // 2.指定网络信息
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    // saddr.sin_port = htons(5678);                       // 网络字节序端口号
    // saddr.sin_addr.s_addr = inet_addr("192.168.51.78"); // 虚拟机IP
    saddr.sin_port = htons(atoi(argv[2]));      // 网络字节序端口号
    saddr.sin_addr.s_addr = inet_addr(argv[1]); // 虚拟机IP
    // 3.请求连接
    if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        perror("connect err");
        return -1;
    }
    printf("connect okk\n");
    // 4.接受发送消息(send()/recv())-------------》通话
    while (1)
    {
        show();
        fgets(buf, sizeof(buf), stdin);
        // HELLO
        // printf("buf:%s\n", buf);
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = '\0';
        if (!strcmp(buf, "quit"))
            break;
        send(sockfd, buf, sizeof(buf), 0);        if (!strncmp(buf, "put ", 4))
            putfile(sockfd, buf);
        if (!strncmp(buf, "get ", 4))
            getfile(sockfd, buf);
    }    // 7.关闭套接字(close)---------------------------》挂断电话
    close(sockfd);
    return 0;
}void show()
{
    printf("------------put filename------------\n");
    printf("------------get filename------------\n");
    printf("----------------quit----------------\n");
}void putfile(int sockfd, char *p)
{
    char buf[128] = {0};
    int ret = 0;
    int fd = open(p + 4, O_RDONLY);
    if (fd < 0)
    {
        perror("open err");
        return;
    }
    while (1)
    {
        ret = read(fd, buf, sizeof(buf) - 1);
        buf[ret] = '\0';
        if (ret == 0)
            break;
        send(sockfd, buf, sizeof(buf), 0);
    }
    send(sockfd, "end", sizeof(buf), 0);
    close(fd);
    return;
}void getfile(int sockfd, char *p)
{
    int ret = 0;
    int fd = open(p + 4, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0)
    {
        perror("open err");
        return;
    }
    char buf[128] = {0};
    while (1)
    {
        ret = recv(sockfd, buf, sizeof(buf), 0);
        if (ret < 0)
        {
            perror("recv err");
            return;
        }
        if (!strcmp(buf, "end"))
            break;
        write(fd, buf, strlen(buf));
        memset(buf, 0, sizeof(buf));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/97369.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/97369.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/97369.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows系统提示“找不到文件‘javaw‘”

1. Java 未安装或安装不完整javaw.exe 是 Java 运行环境&#xff08;JRE&#xff09;的核心文件&#xff0c;用于运行 Java 程序&#xff08;如.jar 文件&#xff09;。如果你的电脑没有安装 Java&#xff0c;或安装过程中 javaw.exe 被误删&#xff0c;系统就会找不到它。2. J…

【PCIE系列】1---PCIE系统拓扑结构分析

架构由点对点链路&#xff08;Links&#xff09;组成&#xff0c;用于互连组成系统的一系列组件。下图展示了一个示例拓扑结构。该图描述了一个有层次的体系架构实例&#xff0c;其包含根复合体&#xff08;Root Complex, RC&#xff09;、多个端点&#xff08;I/O设备&#xf…

SpringBoot防止重复提交(2)

例如&#xff1a;多次点击提现按钮问题描述&#xff1a;在提现操作中&#xff0c;用户可能会多次点击提现按钮&#xff0c;导致多个相同的请求发送到服务器&#xff0c;从而引发重复提现的问题。为了解决这一问题&#xff0c;必须保证每个提现请求只能执行一次&#xff0c;防止…

mysql zip包安装步骤

下载地址 windows MSI Install 安装包程序。 这里下载zip包&#xff0c;执行安装过程 确认my.ini 配置的路径&#xff0c;创建mysql数据服务的data目录管理员身份cmd 进入bin目录&#xff0c;开始初始化服务 mysqld --initialize-insecure --usermysql mysqld -install#启动…

Python 的 argparse 模块中,add_argument 方法的 nargs 参数

在 Python 的 argparse 模块中&#xff0c;add_argument 方法的 nargs 参数用于指定命令行参数可以接受的参数数量。你提到的 nargs* 和 nargs 是两种常见设置&#xff0c;它们分别表示不同的参数数量要求。以下是两者的详细区别和含义&#xff1a;1. nargs*: 接受零个或多个参…

嵌入式Linux LED驱动开发

嵌入式Linux LED驱动开发 一、LED驱动概述 本笔记基于IMX6ULL处理器的LED驱动开发&#xff0c;详细介绍了字符设备驱动开发的基本流程。该驱动实现了对LED的基本控制功能&#xff0c;通过字符设备接口供用户空间程序调用。 二、LED驱动核心概念 1. 寄存器地址定义 本驱动涉…

Excel Word Pdf 格式转换

引入aspose包手动更新本地mvn仓库mvn install:install-file -DfileC:\aspose-cells-22.9.jar -DgroupIdaspose -DartifactIdaspose-cells -Dversion22.9 -Dpackagingjar mvn install:install-file -DfileC:\aspose-pdf-22.9.jar -DgroupIdaspose -DartifactIdaspose-pdf -Dvers…

变频器实习DAY40 调整测试零伺服PI LDO

目录变频器实习DAY40一、工作内容1.1 调整测试零伺服PI二、学习内容2.1 LDOLDO的核心工作原理——“采样-比较-调整”闭环控制LDO的关键参数——选型核心依据LDO与其他稳压器的选型对比附学习参考网址欢迎大家有问题评论交流 (* ^ ω ^)变频器实习DAY40 一、工作内容 1.1 调整…

【半导体制造流程概述】

半导体制造流程概述 半导体制造是一个高度复杂且精密的过程&#xff0c;涉及多个关键步骤&#xff0c;通常分为以下几个主要阶段&#xff1a;设计、晶圆制备、光刻、刻蚀、掺杂、薄膜沉积、互连和封装测试。 文章目录半导体制造流程概述晶圆制备光刻刻蚀掺杂薄膜沉积互连封装测…

为什么大模型需要文档预处理:从数据到智能的关键一步

在人工智能&#xff0c;尤其是大语言模型&#xff08;LLM, Large Language Models&#xff09;的应用落地过程中&#xff0c;数据质量与处理流程的重要性正逐渐被各行各业所认识。无论是企业内部构建知识库、自动化文档审核&#xff0c;还是面向用户提供智能问答服务&#xff0…

50.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--二期功能规划

啰嗦了这么多文章&#xff0c;我们终于进入到了二期功能的开发。这篇文章我们先来规划一下二期要做的功能&#xff0c;在一期功能中&#xff0c;我们完成了基础的记账功能&#xff0c;但是作为一个记账软件&#xff0c;仅有这些功能是远远不够的。我们需要更多的功能来满足用户…

Oracle下载安装(学习版)

1. 下载&#xff08;学习版&#xff09; 网址&#xff1a;软件下载 | Oracle 中国 2. 安装 解压缩 双击可执行文件 下一步 选同意&#xff0c;下一步 下一步 设置密码&#xff08;自己记住&#xff09; 开始安装 测试安装是否成功

`basic_filebuf`、`basic_ifstream`、`basic_ofstream`和 `basic_fstream`。

C 文件 I/O 模板类深度解析 文章目录C 文件 I/O 模板类深度解析1. basic_filebuf 深度解析1.1 类模板定义详解1.2 关键成员变量1.3 核心成员函数实现原理1.3.1 open() 函数实现1.3.2 overflow() 函数实现1.4 完整示例&#xff1a;自定义缓冲策略2. basic_ifstream 深度解析2.1 …

计算机毕设 java 阿歹果园养鸡场管理系统 基于 SSM 框架的果园养鸡场全流程管理系统设计与实现 Java+MySQL 的养殖生产与进销存一体化平台开发

计算机毕设 java 阿歹果园养鸡场管理系统ky7dc9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09;本套源码可以先看具体功能演示视频领取&#xff0c;文末有联xi 可分享 随着农业养殖规模化发展&#xff0c;传统果园养鸡场依赖人工记录、纸质台账的管理模式&#xf…

生成式BI工具(WrenAI)

生成式 BI 工具支持自然语言查询数据库&#xff0c;自动生成 SQL 与可视化图表&#xff0c;被金融分析师和数据科学家广泛采用。 WrenAI是由Canner团队开发的开源生成式BI&#xff08;GenBI&#xff09;智能体&#xff0c;致力于通过自然语言交互实现数据库查询、可视化生成和洞…

论文Review 3DGS PGSR | TVCG2024 ZJU-3DV | 几何约束的3DGS表面重建

基本信息 题目&#xff1a;PGSR: Planar-based Gaussian Splatting for Efficient and High-Fidelity Surface Reconstruction 来源&#xff1a;TVCG2024 学校&#xff1a;ZJU-3DV 是否开源&#xff1a;https://github.com/zju3dv/PGSR 摘要&#xff1a;3DGS表面重建 最近…

最新After Effects2025下载安装(含安装包)AE 2025 保姆级下载一键安装图文教程

文章目录一、After Effects 2025下载二、After Effects 2025安装教程三、核心功能升级详解四、系统配置与兼容性说明一、After Effects 2025下载 ①夸克网盘下载链接&#xff1a;https://pan.quark.cn/s/a06e6200e64c 二、After Effects 2025安装教程 1.解压安装包:找到下载…

【网络安全领域】边界安全是什么?目前的发展及应用场景

在网络安全领域&#xff0c;边界安全&#xff08;Perimeter Security&#xff09; 是指围绕企业或组织网络的 “物理与逻辑边界” 构建的防护体系&#xff0c;核心目标是阻止未授权访问从外部网络&#xff08;如互联网、合作方网络&#xff09;侵入内部可信网络&#xff0c;同时…

虚拟机快照对内存与磁盘空间的影响

核心概念&#xff1a;快照是什么&#xff1f;虚拟机快照捕获的是在某个特定时间点上虚拟机的完整状态。这包括&#xff1a;磁盘状态&#xff1a;虚拟磁盘的数据。内存状态&#xff1a;当时虚拟机内存中的所有内容&#xff08;如果选择&#xff09;。配置状态&#xff1a;虚拟机…

免费开源的 Gemini 2.5 Flash 图片生成器

免费开源的 Gemini 2.5 Flash 图片生成器&#xff1a;gemini-nano-banana 项目详解 在 AI 图片生成领域&#xff0c;大多数工具要么收费昂贵&#xff0c;要么需要复杂的配置。今天为大家介绍一个完全免费开源的解决方案——gemini-nano-banana&#xff0c;一个基于 Google Gemi…