项目——员工管理系统

news2025/1/15 19:17:37

开发环境:vmware ubuntu18.04

实现功能:基本功能包括管理者和普通员工用户的登录,管理者拥有操作所有员工信息的最高权限,可以进行增删改   查等操作,普通用户仅拥有查看、修改个人部分信息的权限

具体功能详解:

1)服务器负责管理所有员工表单(以数据库形式或文件形式都可),客户端可通过网络连接服务器来查询员工表单。

2)需要账号密码登陆,其中需要区分管理员账号还是普通用户账号。

3)管理员账号可以查看、修改员工表单,管理员要负责管理所有的普通用户。

4)普通用户只能查询修改与本人有关的部分相关信息,其他员工信息(出于保密原则)不得泄露,个人职务、工资等信息(出于公司管理角度)员工无法自己进行更改。

5)有查询历史记录功能。

6)能同时处理多台客户端的请求功能。

项目职责:

使用socket实现TCP通信

使用多进程实现并发服务器

使用SQLite数据库管理用户和学生信息

使用SQLite数据库记录系统运行的日志信息

 服务器流程及设计知识简介:

一、TCP通信编程步骤:

1、创建套接字——socket;

2、绑定服务器ip和端口号——bind;

3、设置为被动监听状态——listen;

4、等待客户端连接——accept;

5、数据的交互——recv、send;

二、服务器模型:

1>循环服务器

//1. 一次只能处理一个客户端,等这个客户端退出后,才能处理下一个客户端。 
//2. 缺点多个客户端不能同时处理。
sfd = socket();
bind();
listen();
while(1)
{
newfd = accept();
while(1)
{
recv();
send();
}
close(newfd);
}
close(sfd);

2>并发服务器

①多进程并发服务器:

Ⅰ可以同时处理多个客户端的请求,创建子进程或者分支线程来处理客户端处理客户端的请求。

Ⅱ父进程/主线程只负责连接,子进程/分支线程 只负责与客户端交互。

void handler(int sig)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
signal(17, handler);
sfd=socket();
bind();
listen();
while(1)
{
newfd=accept();
pid=fork();
if(0 == pid)
{
close(sfd);
while(1)
{
recv();
send();
}
close(newfd);
exit(0);
}
else if(pid > 0)
{
close(newfd);
}
}

②多线程并发服务器

sfd = socket();
bind();
listen();
while(1)
{
newfd = accept();
info.newfd = newfd;
info.cin = cin;
.....
pthread_create(&tid, NULL, callBack, &info);
pthread_detach(tid);
}
void* callBack(void* arg)
{
while(1)
{
recv();
send();
}
close(newfd);
}

③IO多路复用

        a. select:
                基本思想:
                        1. 先构造一张有关文件描述符的表(集合、数组); fd_set fd;
                        2. 将你关心的文件描述符加入到这个表中;FD_SET();
                        3. 然后调用一个函数。 select / poll 
                        4. 当这些文件描述符中的一个或多个已准备好进行I/O操作的时候,该函数才返回(阻塞)。
                        5. 判断是哪一个或哪些文件描述符产生了事件(IO操作);
                        6. 做对应的逻辑处理;
                        ****select函数返回之后,会自动将除了产生事件的文件描述符以外的位全部清空;
                        程序步骤:
                                1.把关心的文件描述符放入集合--FD_SET
                                2.监听集合中的文件描述符--select
                                3.依次判断哪个文件描述符有数据--FD_ISSET
                                4.依次处理有数据的文件描述符的数据
 

socket();
bind();
listen();
fd_set readfds, tempfds;
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(sfd, &readfds);
while(1)
{
    tempfds = readfds;
    select(maxfd+1, &tempfds, NULL, NULL, NULL);
    for(i=0; i<=maxfd; i++)
    {
        if(FD_ISSET(i, &tempfds) == 0) continue;
        if(0 == i){ fgets() } //键盘输入事件
        else if(sfd == i){ //客户端连接事件
            newfd = accept();
            FD_SET(newf, &readfds);
            maxfd = maxfd>newfd?maxfd:newfd;
    }
    else { //客户端交互事件
        recv();
        判断是否要关闭文件描述符
        判断是否要将文件描述符从readfds中剔除;
        判断是否需要更新maxfd;
        }
    }
 }
close(sfd);

        select弊端: 
                        1. 一个进程最多只能监听1024个文件描述符 (千级别)
                        2. select是一种轮询的机制;
                        3. 涉及到用户态和内核态的数据拷贝;

        b. poll
                        1. 优化文件描述符个数的限制;
                        2. poll是一种轮询的机制;
                        3. 涉及到用户态和内核态的数据拷贝;
                函数接口:   
                        int poll(struct pollfd *fds, nfds_t nfds, int timeout);
                参数:
                                struct pollfd *fds
                                关心的文件描述符数组struct pollfd fds[N];
                                nfds:个数
                        timeout: 超时检测
                                毫秒级的:如果填1000,1秒
                                  如果-1,阻塞

        问题:
                        我想检测是键盘事件(标准输入 文件描述如为0 ),
                        还是鼠标事件(文件描述符是/dev/input/mouse1);  
                1. 创建一个结构体数组
                        struct pollfd fds[2];
                2. 将你关心的文件描述符加入到结构体成员中
                        struct pollfd {
                                           int   fd;         // 关心的文件描述符;
                                           short events;     // 关心的事件,读
                                           short revents;    // 如果产生事件,则会自动填充该成员的值
                                                };

                                // 键盘
                                fds[0].fd = 0;
                                fds[0].events = POLLIN;

                                / /鼠标
                                fds[1].fd = mouse1_fd;
                                fds[1].events = POLLIN;

                    3. 调用poll函数
                                如果返回表示有事件产生;
                                poll(fds,2,1000)
                4. 判断具体是哪个文件描述符产生了事件
                        if(fds[0].revents == POLLIN)
                        {
                                ....
                                }

       c. epoll
                1. 没有文件描述符的限制
                2. 异步IO,当有事件产生,文件描述符主动调用callback
                3. 不用数据拷贝;

                3个功能函数:
                                #include <sys/epoll.h>

                                #include <sys/epoll.h>
                                int epoll_create(int size);//创建红黑树根节点
                                //成功时返回epoll文件描述符,失败时返回-1

                                //控制epoll属性
                                int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
                                epfd:epoll_create函数的返回句柄。
                                op:表示动作类型。有三个宏 来表示:
                                EPOLL_CTL_ADD:注册新的fd到epfd中
                                EPOLL_CTL_MOD:修改已注册fd的监听事件
                                EPOLL_CTL_DEL:从epfd中删除一个fd
                                FD:需要监听的fd。
                                event:告诉内核需要监听什么事件
                                EPOLLIN:表示对应文件描述符可读
                                EPOLLOUT:可写
                                EPOLLPRI:有紧急数据可读;
                                EPOLLERR:错误;
                                EPOLLHUP:被挂断;
                                EPOLLET:触发方式,电平触发;
                                 ET模式:表示状态的变化;
                                //成功时返回0,失败时返回-1

                                //等待事件到来
                int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
                        功能:等待事件的产生,类似于select嗲用
                        epfd:句柄;
                        events:用来从内核得到事件的集合;
                        maxevents:表示每次能处理事件最大个数;
                        timeout:超时时间,毫秒,0立即返回,-1阻塞
                        //成功时返回发生事件的文件描述数,失败时返回-1

三、数据库函数接口

        1.int   sqlite3_open(char  *path,   sqlite3 **db);        
           功能:打开sqlite数据库  
           参数:
                path: 数据库文件路径         
                db: 指向sqlite句柄的指针     
                返回值:成功返回0,失败返回错误码(非零值)

        2.int   sqlite3_close(sqlite3 *db);
                功能:关闭sqlite数据库
                返回值:成功返回0,失败返回错误码

        3.int sqlite3_exec(sqlite3 *db, const  char  *sql,  sqlite3_callback callback, void *,  char **errmsg);
                功能:执行SQL语句
                参数:
                         db:数据库句柄
                         sql:SQL语句 ("create table stu .....;")
                         callback:回调函数
                         void * arg: 
                        当使用查询命令的时候,callback和arg才有意义;
                        select .....
                                 errmsg:错误信息指针的地址
                                 char *errmsg;    
                                 &errmsg;
                返回值:成功返回0,失败返回错误码

                int callback(void *para, int f_num, char **f_value, char **f_name);
                功能:每找到一条记录自动执行一次回调函数
                参数:
                        para:   传递给回调函数的参数
                        f_num:  记录中包含的字段数目(id name score) 相当于有多少列;
                        f_value:包含每个字段值的指针数组
                        f_name:包含每个字段名称的指针数组
                返回值:成功返回0,失败返回-1

        4.int  sqlite3_get_table(sqlite3 *db, const  char  *sql,char ***resultp,  int *nrow,  int *ncolumn, char **errmsg);
            功能:执行SQL操作
                参数:
                        db:数据库句柄
                        sql:SQL语句
                        resultp:用来指向sql执行结果的指针;实际上就是“指针数组指针”;
                        nrow:满足条件的记录的数目,实际上就是有多少行数据;
                        ncolumn:每条记录包含的字段数目,实际上就是有多少个字段(多少列);
                        errmsg:错误信息指针的地址
                    返回值:成功返回0,失败返回错误码

 客户端流程及涉及知识简介:

TCP客户端流程

1、创建套接字

2、连接服务器

3、完成数据的收发,实现增删改查功能

 服务器测试结果:

ubuntu-staff$ ./a.out
sqlite3 open staff success
create table staff success
create table history success
bind success
listen success
192.168.250.100:57954 newfd=5 accept
1 boss 1员工登录系统 2022-12-10 11:08:17
1 boss 1管理员成功添加3 ppp用户 2022-12-10 11:08:53
1 boss 1管理员查询员工信息
1 boss 1管理员查询员工信息
1 boss 1管理员查询员工信息
1 boss 1员工修改3 员工姓名信息为ooo 2022-12-10 11:09:30

192.168.250.100:57956 newfd=5 accept
1 boss 1员工登录系统 2022-12-10 11:11:38
1 boss 1管理员成功添加4 wang用户 2022-12-10 11:12:13
192.168.250.100:57960 newfd=5 accept
4 wang 4员工登录系统 2022-12-10 11:12:32
4 wang 4管理员查询员工信息
4 li 4员工修改4 员工姓名信息为li 2022-12-10 11:12:42

192.168.250.100:57962 newfd=5 accept
4 li 4员工登录系统 2022-12-10 11:13:33
4 li 4管理员查询员工信息
4 li 4员工修改4 员工年龄信息为1997 2022-12-10 11:13:49

4 li 4管理员查询员工信息

 管理员登录功能测试:

ubuntu-staff$ ./c
connect success
 ___________________________
|                           |
|**********登录界面*********|
|*******1.管理员登录********|
|*******2.普通用户登录******|
|*******3.退出界面**********|
|___________________________|
请输入您的选择(数字):1
请输入您的用户名(工号):1
请输入密码:success
管理员登录成功
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.添加用户***********|
|******2.查询用户***********|
|******3.删除用户***********|
|******4.修改用户信息*******|
|******5.查询历史记录*******|
|******6.退出登录***********|
|___________________________|
请输入您的选择(数字):1
请输入员工工号:3
请输入员工权限(管理员权限:1 普通用户权限:0:1
请输入要添加的用户姓名:ppp
请输入用户密码(6位):999999
请输入员工年龄(18-60岁):19
请输入员工电话:0000
请输入员工家庭住址:99
请输入员工职位:09
请输入员工入职年月:90
请输入员工职等(1-10等):9
请输入员工工资:90
3 ppp员工信息添加成功
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.添加用户***********|
|******2.查询用户***********|
|******3.删除用户***********|
|******4.修改用户信息*******|
|******5.查询历史记录*******|
|******6.退出登录***********|
|___________________________|
请输入您的选择(数字):2
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.根据人名查找*******|
|******2.根据工号查找*******|
|******3.查询所有***********|
|******4.退出查询***********|
|___________________________|
请输入您的选择(数字):1
请输入要查找的员工姓名:ppp
工号	姓名	年龄 电话   地址     职位   入职年月  职等  工资 
3	ppp	19	0000	99	09	90	9	90.000000
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.根据人名查找*******|
|******2.根据工号查找*******|
|******3.查询所有***********|
|******4.退出查询***********|
|___________________________|
请输入您的选择(数字):2
请输入要查找的员工工号:3
工号   姓名 年龄 电话   地址     职位   入职年月  职等  工资 
3	ppp	19	0000	99	09	90	9	90.000000
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.根据人名查找*******|
|******2.根据工号查找*******|
|******3.查询所有***********|
|******4.退出查询***********|
|___________________________|
请输入您的选择(数字):3
工号   姓名 年龄 电话   地址     职位   入职年月  职等  工资 
1	boss	18	100010	china	老板	1990	18	500.000000
3	ppp	19	0000	99	09	90	9	90.000000
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.根据人名查找*******|
|******2.根据工号查找*******|
|******3.查询所有***********|
|******4.退出查询***********|
|___________________________|
请输入您的选择(数字):4
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.添加用户***********|
|******2.查询用户***********|
|******3.删除用户***********|
|******4.修改用户信息*******|
|******5.查询历史记录*******|
|******6.退出登录***********|
|___________________________|
请输入您的选择(数字):4
 ___________________________
|                           |
|******管理员修改界面*******|
|******1.修改姓名***********|
|******2.修改密码***********|
|******3.修改电话***********|
|******4.修改地址***********|
|******5.修改职位***********|
|******6.修改职等***********|
|******7.修改工资***********|
|******8.修改年龄***********|
|******9.退出修改***********|
|___________________________|
请输入您的选择(数字):1
请输入要修改员工的工号:3
请输入要修改后的姓名:ooo
1员工修改3 员工姓名信息为ooo (null)

 ___________________________
|                           |
|******管理员修改界面*******|
|******1.修改姓名***********|
|******2.修改密码***********|
|******3.修改电话***********|
|******4.修改地址***********|
|******5.修改职位***********|
|******6.修改职等***********|
|******7.修改工资***********|
|******8.修改年龄***********|
|******9.退出修改***********|
|___________________________|
请输入您的选择(数字):9
 ___________________________
|                           |
|******管理员登录界面*******|
|******1.添加用户***********|
|******2.查询用户***********|
|******3.删除用户***********|
|******4.修改用户信息*******|
|******5.查询历史记录*******|
|******6.退出登录***********|
|___________________________|
请输入您的选择(数字):5
工号	姓名	操作信息 
1	boss	1员工登录系统 2022-12-10 11:05:58
1	boss	1管理员查询员工信息
1	boss	1管理员查询员工信息
1	boss	1员工登录系统 2022-12-10 11:06:44
1	boss	1管理员查询员工信息
1	boss	1员工修改1 员工姓名信息为boss 2022-12-10 11:07:25

1	boss	1员工登录系统 2022-12-10 11:08:17
1	boss	1管理员成功添加3 ppp用户 2022-12-10 11:08:53
1	boss	1管理员查询员工信息
1	boss	1管理员查询员工信息
1	boss	1管理员查询员工信息
1	boss	1员工修改3 员工姓名信息为ooo 2022-12-10 11:09:30

 ___________________________
|                           |
|******管理员登录界面*******|
|******1.添加用户***********|
|******2.查询用户***********|
|******3.删除用户***********|
|******4.修改用户信息*******|
|******5.查询历史记录*******|
|******6.退出登录***********|
|___________________________|
请输入您的选择(数字):6
ubuntu-staff$ ^C

 普通用户登录功能测试

ubuntu-staff$ ./c
connect success
 ___________________________
|                           |
|**********登录界面*********|
|*******1.管理员登录********|
|*******2.普通用户登录******|
|*******3.退出界面**********|
|___________________________|
请输入您的选择(数字):2
请输入您的用户名(工号):4
请输入密码:888888
普通用户登录成功
 ___________________________
|                           |
|*****普通用户登录界面******|
|******1.查询个人信息*******|
|******2.修改个人信息*******|
|******3.退出登录***********|
|___________________________|
请输入您的选择(数字):1
工号	姓名	年龄 电话   地址     职位   入职年月  职等  工资 
4	li	18	8888	888i	jl	9709	8	90.000000
 ___________________________
|                           |
|*****普通用户登录界面******|
|******1.查询个人信息*******|
|******2.修改个人信息*******|
|******3.退出登录***********|
|___________________________|
请输入您的选择(数字):2
 ___________________________
|                           |
|******普通用户修改界面*****|
|******1.修改姓名***********|
|******2.修改密码***********|
|******3.修改电话***********|
|******4.修改地址***********|
|******5.修改年龄***********|
|******6.退出修改***********|
|___________________________|
请输入您的选择(数字):5
请输入要修改后的出生年份:1997
4员工修改4 员工年龄信息为1997 (null)

 ___________________________
|                           |
|******普通用户修改界面*****|
|******1.修改姓名***********|
|******2.修改密码***********|
|******3.修改电话***********|
|******4.修改地址***********|
|******5.修改年龄***********|
|******6.退出修改***********|
|___________________________|
请输入您的选择(数字):6
 ___________________________
|                           |
|*****普通用户登录界面******|
|******1.查询个人信息*******|
|******2.修改个人信息*******|
|******3.退出登录***********|
|___________________________|
请输入您的选择(数字):1
工号	姓名	年龄 电话   地址     职位   入职年月  职等  工资 
4	li	1997	8888	888i	jl	9709	8	90.000000
 ___________________________
|                           |
|*****普通用户登录界面******|
|******1.查询个人信息*******|
|******2.修改个人信息*******|
|******3.退出登录***********|
|___________________________|
请输入您的选择(数字):3
ubuntu-staff$ 

附:代码实现见员工管理系统代码实现链接

https://blog.csdn.net/ww1106/article/details/128265598?spm=1001.2014.3001.5502

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 学习笔记

解决执行python"ImportError: No module named requests"问题 #切换到python的安装目录执行如下命令 D:\Python27>pip install requestsImportError: No module named bs4错误解决方法 运行脚本时提示ImportError: No module named bs4错误&#xff0c;原因&…

[附源码]计算机毕业设计基于vue的软件谷公共信息平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Python——有限状态机

有限状态机&#xff08;Finite-state machine, FSM&#xff09;&#xff0c;又称有限状态自动机&#xff0c;简称状态机&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。FSM是一种算法思想&#xff0c;简单而言&#xff0c;有限状态机由一组状态…

【Lilishop商城】No3-5.模块详细设计,商品模块-1(商品分类、品牌管理、规格管理、参数、计量单位、店铺分类)的详细设计

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑&#xff0c;其中重点包括接口类、业务类&#xff0c;具体的结合源代码…

人脸特征点检测入门

基础 人脸特征点可以用来做脸型、眼睛形状、鼻子形状等分析&#xff0c;从而对人脸的特定位置进行修饰加工&#xff0c;实现人脸的特效美颜。人脸识别等算法可以通过对人脸的姿态进行对齐从而提高模型的精度。 68点标注是现今最通用的一种标注方案&#xff0c;早期在1999年的…

Effective C++条款30:透彻了解inlining的里里外外(Understand the ins and outs of inlining)

Effective C条款30&#xff1a;透彻了解inlining的里里外外&#xff08;Understand the ins and outs of inlining&#xff09;条款30&#xff1a;透彻了解inlining的里里外外1、inline函数的优缺点2、隐式内联和显式内联2.1 隐式内联2.2 显式内联3、函数模板必须inline么&…

自动驾驶之3D点云聚类算法调研

1. 方法 总共分为4类 基于欧式距离的聚类Supervoxel 聚类深度(Depth) 聚类Scanline Run 聚类 1.1 基于欧氏距离的聚类 思路: 在点云上构造kd-tree, 然后在某个半径阈值(例如0.5m), 则分割为一个实例。 相似算法: RBNN (radially bounded nearest neighbor graph), 2008. …

在 Ubuntu 上安装 Discourse 开发环境

本指南只针对 Discourse 开发环境的配置&#xff0c;如果你需要在生产环境中安装 Discourse &#xff0c;请访问页面&#xff1a;Install Discourse in production with the official, supported instructions - sysadmin - Discourse Meta 中的内容。 有关开发环境的设置英文原…

[Java EE初阶] 进程调度的基本过程

纪念Java EE初阶开篇文章,不放弃,不摆烂,踏平所有障碍吧!少年!奥利给!(操作系统这方面的所有文章均不作为操作系统的专业课知识学习) 文章目录1. 进程的概念2. PCB --- 进程控制块3. 并发与并行4. 进程调度的相关属性5. 内存管理总结1. 进程的概念 进程,就是跑起来的程序,我们…

【学习笔记】《Python深度学习》第七章:高级的深度学习最佳实践

文章目录1 Keras 函数式 API1.1 函数式 API 简介1.2 多输入模型1.3 多输出模型1.4 层组成的有向无环图1.5 共享层权重1.6 将模型作为层2 使用 Keras 回调函数 和 TensorBoard 检查并监控深度学习模型2.1 训练过程中将回调函数作用于模型2.2 TensorBoard 简介&#xff1a;Tensor…

【Lilishop商城】No3-4.模块详细设计,店铺店员(店铺店员、店铺部门、店铺角色)的详细设计

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑&#xff0c;其中重点包括接口类、业务类&#xff0c;具体的结合源代码…

exfat文件系统

DBR&#xff1a; DBR偏移量 字段长度&#xff08;字节&#xff09; 说明 0x40 - 0x47 8 分区的起始扇区号&#xff08;隐藏扇区数&#xff09; 0x48 - 0x4F 8 分区总扇区数 0x50 - 0x53 4 FAT表起始扇区号&#xff08;从DBR到FAT表的扇区个数&#xff09; 0x54 - 0x57 4…

【Redis】持久化操作

一、RDB(Redis Database) 1、持久化 redis一般是将数据写到内存中&#xff0c;但也可以将数据写到磁盘中&#xff0c;这个过程称之为持久化 2、什么是RDB 在指定的时间间隔内将内存中的数据集快照写入磁盘中 3、RDB是如何执行备份操作的 redis会单独创建(fork)一个子进程进行…

FPGA 20个例程篇:18.SD卡存放音频WAV播放(下)

第七章 实战项目提升&#xff0c;完善简历 18.SD卡存放音频WAV播放&#xff08;下&#xff09; 进一步地我们再结合图1的示意图来分析wav_play模块的时序逻辑设计&#xff0c;大家可以清楚地看到WM8731在Right justified和主从时钟模式下&#xff0c;是先发左声道后发右声道数…

【LeetCode】专题一 二叉树层序遍历

二叉树层序遍历 在本文中&#xff0c;我将会选取LeetCode上二叉树层序遍历的多道例题&#xff0c;并给出解答&#xff0c;通过多道题我们就可以发现&#xff0c;二叉树的层序遍历并不复杂&#xff0c;并且有着共通点。 102. 二叉树的层序遍历 给你二叉树的根节点 root &…

【Labivew】简易计算器

&#x1f6a9;write in front&#x1f6a9; &#x1f50e;大家好&#xff0c;我是謓泽&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f3c5;2021年度博客之星物联网与嵌入式开发TOP5&#xff5…

Secure CRT远程连接很快断线问题

问题描述 我们使用Secure CRT连接远程主机时可能会遇到几分钟没操作就无法操作了&#xff0c;需要断开重新连接&#xff0c;非常的麻烦&#xff0c;假如客户端或者服务端能够在快要超时的时候给对方发送一个心跳&#xff0c;得到对方响应就重置下超时时间&#xff0c;这样就能…

arm架构 --- 中断

ARM的异常 终止程序的正常执行过程而不得不去完成的一些特殊工作 中断是异常的一种&#xff0c;包括外部硬件产生的异常和芯片内部硬件产生的内部中断。 ARM有七种处理器模式&#xff0c;其中用户模式和系统模式之外的5钟处理器模式叫做异常模式&#xff0c;用户模式之外的6…

osgEarth示例分析——osgearth_terrainprofile

前言 osgearth_terrainprofile示例&#xff0c;涉及到一个新的类 TerrainProfileCalculator(地形轮廓计算器类)&#xff0c;用来计算两个点连线之间的地形数据。左下角会根据点击的起点和终点进行计算&#xff0c;并更新显示地形信息。 效果 拖动地球&#xff0c;到某一个视…

[附源码]Python计算机毕业设计SSM基于的智慧校园安防综合管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…