linux设置自动运行任务管理器,自己实现Linux系统任务管理器(附源码)
一、前言
之前在操作系统课程中,使用Java实现的任务管理器,使用了Swing界面、Runtime、Process相关类。文章总结和程序下载在下面:
虽然基本功能实现了,Java跨平台的特性,也使得这个应用在Linux上跑,但是在实现这个版本之后就已经感觉到Java对操作系统信息的提取与封装是有限的,Process包含的进程信息有限,且操作不方便。
因此最近在Linux课程中,决定用Qt界面+Linux方式实现自己的Linux版任务管理器。在程序设计之前,有必要先了解下Linux系统进程信息提取方式,因为这种“Linux方式”不像Java的Process类封装那样,不管底层,只管调用 process.getInputStream();去读取流。
二、Linux下/proc目录简介
Linux内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。
系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的 PID号为目录名,它们是读取进程信息的接口。而self目录则是读取进程本身的信息接口,是一个link。
直接打开自己安装的Linux系统,进入/proc,可以看到很多数字命名的文件夹;文件夹名的数字,代表当前运行的一个进程的PID,它是读取进程信息的接口。
Linux下/proc下其他重要目录
/proc/cpuinfo --cpu的信息
/proc/devices --已经加载的设备并分类
/proc/modules --所有加载到内核的模块列表
/proc/stat --所有的CPU活动信息,可采点计算cpu的利用率
/proc/version --Linux内核版本和gcc版本
三、Qt实现Linux版任务管理器
用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。
我们要显示系统信息,只需进行相应的文件操作就行了。
Qt的发展势头相当猛,qt的可移植性相当强,现在应用程序做界面基本都用Qt。Qt是诺基亚开发的一个跨平台的C++图形用户界面应用程序框架。Qt商业版只能试用30天,不过有GPL版的,可以免费使用。有一个非常不错的免费Qt集成开发环境QtCreator IDE。Linux版任务管理器采用的是Qt来实现图形界面。
步骤:
1、Linux下安装Qt Creator,打开新建一个工程,工程目录下,相关文件会有6个,具体见下图--工程文件夹:
编译完成后的实现效果:
“内存信息”模块:
“进程信息”模块:
“模块信息”模块:
“系统信息”模块:
“关于”模块:
完整源码如下:
main.cpp 工程运行的入口,创建工程时自动创建的,不需要修改。
#include
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h 工程头文件,定义资源和事件响应函数声明。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;//界面资源类,所有的界面元素都是通过该类来调用
QTimer *timer; //计时器
private slots:
void on_pushButton_pkill_clicked();
void on_pushButton_prefresh_clicked();
void on_pushButton_Model_install_clicked();
void on_pushButton_Model_remove_clicked();
void on_pushButton_Model_refresh_clicked();
void on_pushButton_reboot_clicked();
void on_pushButton_halt_clicked();
void on_tabWidget_INFO_currentChanged(int index);
void timer_update_currentTabInfo();
//显示tab中的内容
void show_tabWidgetInfo(int index);
};
#endif // MAINWINDOW_H
mainwindow.cpp 工程最重要的源文件,完成主要的业务逻辑。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
int a0 = 0, a1 = 0, b0 = 0, b1 = 0;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
timer = new QTimer(this);
QWidget::connect( timer, SIGNAL( timeout() ), this, SLOT( timer_update_currentTabInfo() ) );//ui控件-事件响应
QWidget::connect( ui->tabWidget_INFO, SIGNAL( currentChanged() ),
this, SLOT( on_tabWidget_currentChanged() ) );
timer->start(1000);
}
MainWindow::~MainWindow()
{
delete ui;
delete timer;
}
void MainWindow::timer_update_currentTabInfo()
{
int index = ui->tabWidget_INFO->currentIndex();
//定时器只刷新内存tab页面,用于进度条动态显示
if (index == 0)
{
show_tabWidgetInfo(index);
}
}
void MainWindow::show_tabWidgetInfo(int index)
{
QString tempStr; //读取文件信息字符串
QFile tempFile; //用于打开系统文件
int pos; //读取文件的位置
if (index == 0) //内存資源
{
tempFile.setFileName("/proc/meminfo"); //打开内存信息文件
if ( !tempFile.open(QIODevice::ReadOnly) )
{
QMessageBox::warning(this, tr("warning"), tr("The meminfo file can not open!"), QMessageBox::Yes);
return ;
}
QString memTotal;
QString memFree;
QString memUsed;
QString swapTotal;
QString swapFree;
QString swapUsed;
int nMemTotal, nMemFree, nMemUsed, nSwapTotal, nSwapFree, nSwapUsed;
while (1)
{
tempStr = tempFile.readLine();
pos = tempStr.indexOf("MemTotal");
if (pos != -1)
{
memTotal = tempStr.mid(pos+10, tempStr.length()-13);
memTotal = memTotal.trimmed();
nMemTotal = memTotal.toInt()/1024;
}
else if (pos = tempStr.indexOf("MemFree"), pos != -1)
{
memFree = tempStr.mid(pos+9, tempStr.length()-12);
memFree = memFree.trimmed();
nMemFree = memFree.toInt()/1024;
}
else if (pos = tempStr.indexOf("SwapTotal"), pos != -1)
{
swapTotal = tempStr.mid(pos+11, tempStr.length()-14);
swapTotal = swapTotal.trimmed();
nSwapTotal = swapTotal.toInt()/1024;
}
else if (pos = tempStr.indexOf("SwapFree"), pos != -1)
{
swapFree = tempStr.mid(pos+10,tempStr.length()-13);
swapFree = swapFree.trimmed();
nSwapFree = swapFree.toInt()/1024;
break;
}
}
nMemUsed = nMemTotal - nMemFree;
nSwapUsed = nSwapTotal - nSwapFree;
memUsed = QString::number(nMemUsed, 10);
swapUsed = QString::number(nSwapUsed, 10);
memFree = QString::number(nMemFree, 10);
memTotal = QString::number(nMemTotal, 10);
swapFree = QString::number(nSwapFree, 10);
swapTotal = QString::number(nSwapTotal, 10);
ui->label_RAM_Used->setText(memUsed+" MB");
ui->label_RAM_Left->setText(memFree+" MB");
ui->label_RAM_Total->setText(memTotal+" MB");
ui->label_SWAP_Used->setText(swapUsed+" MB");
ui->label_SWAP_Left->setText(swapFree+" MB");
ui->label_SWAP_Total->setText(swapTotal+" MB");
ui->progressBar_RAM->setValue(nMemUsed*100/nMemTotal);
ui->progressBar_SWAP->setValue(nSwapUsed*100/nSwapTotal);
tempFile.close(); //关闭内存信息文件
int tt = 2; //取2个点采样计算cpu当前利用律
int cpuInfo[2][7];
int cpuTotal[2][2];
while (tt)
{
tempFile.setFileName("/proc/stat"); //打开CPU使用状态信息
if ( !tempFile.open(QIODevice::ReadOnly) )
{
QMessageBox::warning(this, tr("warning"), tr("The stat file can not open!"), QMessageBox::Yes);
return;
}
tempStr = tempFile.readLine();
for (int i = 0; i < 7; i++)
{
cpuInfo[2-tt][i] = tempStr.section(" ", i+1, i+1).toInt();
cpuTotal[1][2-tt] += cpuInfo[2-tt][i];
if (i == 3)
{
cpuTotal[0][2-tt] += cpuInfo[2-tt][i];
}
}
tt--;
tempFile.close(); //关闭stat文件
}
int a = cpuTotal[0][1] - cpuTotal[0][0];
int b = cpuTotal[1][1] - cpuTotal[1][0];
if (a < 0)
{
a = -a;
}
if (b < 0)
{
b = -b;
}
ui->progressBar_CPU->setValue(a*100/b);
tempFile.setFileName("/proc/stat"); //linux下用/proc/stat文件来计算cpu的利用率
//这个文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。
if ( !tempFile.open(QIODevice::ReadOnly) )
{
QMessageBox::warning(this, tr("warning"), tr("The stat file can not open!"), QMessageBox::Yes);
return;
}
tempStr = tempFile.readLine();
a0 = a1;
b0 = b1;
a1 = b1 = 0;
int gg;
for (int i = 0; i < 7; i++)
{
b1 += tempStr.section(" ", i+2, i+2).toInt();
gg = b1;
if (i == 3)
{
a1 += tempStr.section(" ", i+2, i+2).toInt();
}
}
int m, n;
m = a1 - a0;
n = b1 - b0;
if (m < 0)
{
m = -m;
}
if (n < 0)
{
n = -n;
}
ui->progressBar_CPU->setValue( (n-m)*100/n );
tempFile.close(); //关闭stat文件
}
else if (index == 1) //进程信息
{
ui->listWidget_process->clear();
QDir qd("/proc");
QStringList qsList = qd.entryList();
QString qs = qsList.join("\n");
QString id_of_pro;
bool ok;
int find_start = 3;
int a, b;
int nProPid; //进程PID
int number_of_sleep = 0, number_of_run = 0, number_of_zombie = 0;
int totalProNum = 0; //进程总数
QString proName; //进程名
QString proState; //进程状态
QString proPri; //进程优先级
QString proMem; //进程占用内存
QListWidgetItem *title = new QListWidgetItem("PID\t" + QString::fromUtf8("名称") + "\t\t" +
QString::fromUtf8("状态") + "\t" +
QString::fromUtf8("优先级") + "\t" +
QString::fromUtf8("占用内存"), ui->listWidget_process);
//循环读取进程
while (1)
{
//获取进程PID
a = qs.indexOf("\n", find_start);
b = qs.indexOf("\n", a+1);
find_start = b;
id_of_pro = qs.mid(a+1, b-a-1);
totalProNum++;
nProPid = id_of_pro.toInt(&ok, 10);
if(!ok)
{
break;
}
//打开PID所对应的进程状态文件
tempFile.setFileName("/proc/" + id_of_pro + "/stat");
if ( !tempFile.open(QIODevice::ReadOnly) )
{
QMessageBox::warning(this, tr("warning"), tr("The pid stat file can not open!"), QMessageBox::Yes);
return;
}
tempStr = tempFile.readLine();
if (tempStr.length() == 0)
{
break;
}
a = tempStr.indexOf("(");
b = tempStr.indexOf(")");
proName = tempStr.mid(a+1, b-a-1);
proName.trimmed(); //删除两端的空格
proState = tempStr.section(" ", 2, 2);
proPri = tempStr.section(" ", 17, 17);
proMem = tempStr.section(" ", 22, 22);
switch ( proState.at(0).toLatin1() )
{
case 'S': number_of_sleep++; break; //Sleep
case 'R': number_of_run++; break; //Running
case 'Z': number_of_zombie++; break; //Zombie
default : break;
}
if (proName.length() >= 12)
{
QListWidgetItem *item = new QListWidgetItem(id_of_pro + "\t" +
proName + "\t" +
proState + "\t" +
proPri + "\t" +
proMem, ui->listWidget_process);
}
else
{
QListWidgetItem *item = new QListWidgetItem(id_of_pro + "\t" +
proName + "\t\t" +
proState + "\t" +
proPri + "\t" +
proMem, ui->listWidget_process);
}
}
QString temp;
temp = QString::number(totalProNum, 10);
ui->label_pNum->setText(temp);
temp = QString::number(number_of_run, 10);
ui->label_pRun->setText(temp);
temp = QString::number(number_of_sleep, 10);
ui->label_pSleep->setText(temp);
temp = QString::number(number_of_zombie, 10);
ui->label_pZombie->setText(temp);
tempFile.close(); //关闭该PID进程的状态文件
}
else if (index == 2) //模块信息
{
ui->listWidget_model->clear();
//sys/module 是一个 sysfs 目录层次, 包含当前加载模块的信息. /proc/moudles 是旧式的, 那种信息的单个文件版本. 其中的条目包含了模块名, 每个模块占用的内存数量, 以及使用计数. 另外的字串追加到每行的末尾来指定标志, 对这个模块当前是活动的.
tempFile.setFileName("/proc/modules"); //打开模块信息文件
if ( !tempFile.open(QIODevice::ReadOnly) )
{
QMessageBox::warning(this, tr("warning"), tr("The modules file can not open!"), QMessageBox::Yes);
return ;
}
//设置模块首行项目
QListWidgetItem *title = new QListWidgetItem( QString::fromUtf8("名称") + "\t\t\t" +
QString::fromUtf8("使用内存数") + "\t\t" +
QString::fromUtf8("使用次數"), ui->listWidget_model);
QString mod_Name, mod_Mem, mod_Num;
//循环读取文件内容,查找需要的信息
while (1)
{
tempStr = tempFile.readLine();
if (tempStr.length() == 0)
{
break;
}
mod_Name = tempStr.section(" ", 0, 0);
mod_Mem = tempStr.section(" ", 1, 1);
mod_Num = tempStr.section(" ", 2, 2);
if (mod_Name.length() > 10)
{
QListWidgetItem *item = new QListWidgetItem(mod_Name + "\t\t" +
mod_Mem + "\t\t" +
mod_Num, ui->listWidget_model);
}
else
{
QListWidgetItem *item = new QListWidgetItem(mod_Name + "\t\t\t" +
mod_Mem + "\t\t" +
mod_Num, ui->listWidget_model);
}
}
tempFile.close(); //关闭模块信息文件
}
else if (index == 3) //系统信息
{
//int ok;
tempFile.setFileName("/proc/cpuinfo"); //打开CPU信息文件
if ( !tempFile.open(QIODevice::ReadOnly) )
{
QMessageBox::warning(this, tr("warning"), tr("The cpuinfo file can not open!"), QMessageBox::Yes);
return;
}
//循环读取文件内容,查找需要的信息
while (1)
{
tempStr = tempFile.readLine();
//QMessageBox::warning(this, tr("msg"), tempStr, QMessageBox::Yes);
if(tempStr==NULL){//文件读完,跳出
break;
}
pos = tempStr.indexOf("model name");
if (pos != -1)
{
pos += 13; //跳过前面的"model name:"所占用的字符
QString *cpu_name = new QString( tempStr.mid(pos, tempStr.length()-13) );
ui->label_CPUName->setText(*cpu_name);
}
else if (pos = tempStr.indexOf("vendor_id"), pos != -1)
{
pos += 12; //跳过前面的"vendor_id:"所占用的字符
QString *cpu_type = new QString( tempStr.mid(pos, tempStr.length()-12) );
ui->label_CPUType->setText(*cpu_type);
}
else if (pos = tempStr.indexOf("cpu MHz"), pos != -1)
{
pos += 11; //跳过前面的"cpu MHz:"所占用的字符
QString *cpu_frq = new QString( tempStr.mid(pos, tempStr.length()-11) );
double cpufrq = cpu_frq->toDouble(); //4核CPU
cpu_frq->setNum(cpufrq*4);
ui->label_CPUFrequency->setText(*cpu_frq + " HZ");
}
else if (pos = tempStr.indexOf("cache size"), pos!=-1)
{
pos += 13; //跳过前面的"cache size:"所占用的字符
QString *cache_size = new QString( tempStr.mid(pos, tempStr.length()-16) );
int cachesize = cache_size->toInt(); //4核CPU
cache_size->setNum(cachesize*4);
ui->label_CatheCapacity->setText(*cache_size + " KB");
}
else //跳过其他的内容
{
}
}
tempFile.close(); //关闭CPU信息文件
//打开操作系统信息文件
tempFile.setFileName("/proc/version");
if ( !tempFile.open(QIODevice::ReadOnly) )
{
QMessageBox::warning(this, tr("warning"), tr("The version file can not open!"), QMessageBox::Yes);
return ;
}
tempStr = tempFile.readLine();
pos = tempStr.indexOf("version");
QString *os_version = new QString( tempStr.mid(0, pos-1) );
ui->label_SystemType->setText(*os_version);
int pos1 = tempStr.indexOf("(");
QString *os_type = new QString( tempStr.mid(pos, pos1-pos-1) );
ui->label_SystemVersion->setText(*os_type);
pos = tempStr.indexOf("gcc version");
pos1 = tempStr.indexOf("#");
QString *gcc_info = new QString( tempStr.mid(pos+12, pos1-pos-14) );
ui->label_GCCVersion->setText(*gcc_info);
tempFile.close(); //关闭操作系统信息文件
}
else //说明
{
}
return;
}
void MainWindow::on_pushButton_halt_clicked()
{
system("halt");
}
void MainWindow::on_pushButton_reboot_clicked()
{
system("reboot");
}
void MainWindow::on_tabWidget_INFO_currentChanged(int index)
{
show_tabWidgetInfo(index); //显示tab中的内容
return ;
}
//杀死进程
void MainWindow::on_pushButton_pkill_clicked()
{
//获得进程号
QListWidgetItem *item = ui->listWidget_process->currentItem();
QString pro = item->text();
pro = pro.section("\t", 0, 0);
system("kill " + pro.toLatin1());
QMessageBox::warning(this, tr("kill"), QString::fromUtf8("该进程已被杀死!"), QMessageBox::Yes);
//回到进程信息tab表
show_tabWidgetInfo(1);
}
//刷新进程信息
void MainWindow::on_pushButton_prefresh_clicked()
{
show_tabWidgetInfo(1);
}
void MainWindow::on_pushButton_Model_install_clicked()
{
show_tabWidgetInfo(2); //安装模块还不知道如何实现
QMessageBox::warning(this, tr("tip"), tr("安装模块还不知道如何实现"), QMessageBox::Yes);
}
void MainWindow::on_pushButton_Model_remove_clicked()
{
show_tabWidgetInfo(2);
//卸载模块还不知道如何实现
QMessageBox::warning(this, tr("tip"), tr("卸载模块还不知道如何实现"), QMessageBox::Yes);
}
void MainWindow::on_pushButton_Model_refresh_clicked()
{
show_tabWidgetInfo(2);
QMessageBox::warning(this, tr("tip"), tr("刷新模块还不知道如何实现"), QMessageBox::Yes);
}
Mainwindow.ui 工程界面文件。
MainWindow
0
0
605
438
MainWindow
0
-10
611
341
WaitCursor
QTabWidget::Triangular
3
false
内存信息
内存信息
内存信息
0
0
591
81
CPU
50
30
431
23
24
0
30
66
17
CPU:
0
80
591
231
内存和交换分区
50
50
431
23
24
50
140
431
23
24
0
50
66
17
内存:
0
140
66
17
交换
50
80
66
17
Used:
200
80
66
17
Left:
380
80
66
17
Total:
380
170
66
17
Total:
50
170
66
17
Used:
200
170
66
17
Left:
90
80
66
17
0
240
80
66
17
0
420
80
66
17
0
420
170
66
17
0
90
170
66
17
0
240
170
66
17
0
进程信息
0
0
421
271
20
280
98
27
kill
170
280
98
27
refresh
430
30
66
17
进程数:
490
30
66
17
0
430
60
66
17
运行数:
430
100
66
17
睡眠数:
430
140
66
17
浆死数:
490
60
66
17
0
490
100
66
17
0
490
140
66
17
0
模块信息
20
280
98
27
Install
180
280
98
27
Romove
350
280
98
27
refresh
0
0
561
271
系统信息
0
0
591
171
处理器信息
50
30
66
17
CPU名称:
50
60
66
17
CPU类型:
50
90
66
17
CPU频率:
50
120
81
17
Cache大小:
140
30
321
17
未知
140
60
151
17
未知
140
90
66
17
未知
140
120
66
17
未知
0
180
591
121
操作系统信息
70
30
111
17
操作系统类型:
70
60
111
17
操作系统版本:
70
90
111
17
GCC编译器:
190
30
151
17
未知
190
60
281
17
未知
190
90
291
17
未知
关于
20
30
66
17
项目名:
100
30
191
17
Linux下Qt实现任务管理器
100
70
191
17
ljheee
20
70
66
17
作者:
100
110
191
17
2017-4-10
20
110
66
17
时间:
100
150
191
17
QQ554278334
20
150
66
17
联系:
380
340
98
27
reboot
500
340
98
27
shutdown
0
0
605
26
SysMontior
TopToolBarArea
false
linux设置自动运行任务管理器,自己实现Linux系统任务管理器(附源码)相关推荐
- wallpaper代码_五行Python代码自动换你的电脑桌面壁纸(内附源码和exe)
很多行友问行哥,Python能不能自动更换电脑壁纸呀,今天它来了 只需要一行代码,指定图片地址即可更换电脑桌面.加上壁纸文件夹路径,让你随机更换电脑桌面,带来不期而遇的新鲜.使用爬虫技术,自动下载壁纸 ...
- linux俄罗斯方块源程序,《俄罗斯方块游戏》项目实作【附源码】
此游戏的界面分为3种,即游戏前界面.游戏时界面和游戏后界面 1.游戏前界面:即在游戏开始之前为用户呈现的界面,其中包括1张背景图和3个按钮,3个按钮分别为"开始"."设置 ...
- 微信、QQ自动抢红包外挂(绿色、无广告--附源码)
为什么80%的码农都做不了架构师?>>> 说明:该外挂仅供学习.娱乐,请勿用于其他用途,否则后果自负. 功能: 1.支持微信.QQ自动抢红包 2.支持手机待机下自动抢红包 3. ...
- win 10 + vs2017+C++的运行环境练习的2048游戏(附源码)
学习cocos2dx练习的2048游戏!练习做完了很久,是跟写的,似懂非懂的,最近感觉又所顿悟.自己就在没看教程的前提下再次写了一次.把源码都放上来了,自己觉得注释清楚了的,有想交流的请留言,请不吝留 ...
- spring boot高校机房自动排课系统 毕业设计-附源码211004
高校机房自动排课系统 摘 要 随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理.在现实运用中,应用软件的工作规则和开发步骤,采用J ...
- python简单代码运用到桌面壁纸_五行Python代码自动换你的电脑桌面壁纸(内附源码和exe)...
很多行友问行哥,Python能不能自动更换电脑壁纸呀,今天它来了 只需要一行代码,指定图片地址即可更换电脑桌面.加上壁纸文件夹路径,让你随机更换电脑桌面,带来不期而遇的新鲜.使用爬虫技术,自动下载壁纸 ...
- 五行Python自动换你的电脑桌面壁纸(内附源码和exe)
很多行友问行哥,Python能不能自动更换电脑壁纸呀,今天他来了. 只需要一行代码,指定图片地址即可更换电脑桌面. 加上壁纸文件夹路径,让你随机更换电脑桌面,带来不期而遇的新鲜.使用爬虫技术,自动下载 ...
- android中设置ListView的选中的Item的背景颜色(附源码)
http://longyi-java.iteye.com/blog/976067 ListView中没有默认的选择颜色,只有选择Item后的焦点颜色,鼠标点击时Item有颜色,放开鼠标后颜色也就没有了 ...
- python pygame字体设置_Python基于pygame实现的font游戏字体(附源码)
本文实例讲述了Python基于pygame实现的font游戏字体.分享给大家供大家参考,具体如下: 在pygame游戏开发中,一个友好的UI中,漂亮的字体是少不了的 今天就给大伙带来有关pygame中 ...
- 在Red Hat Linux中自动运行程序
在Red Hat Linux中自动运行程序 1.开机启动时自动运行程序 Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init.init根据配置文件继续引导过程,启动其它进程.通常 ...
最新文章
- 20种看asp源码的方法及工具
- Java学习笔记_数组
- emoji表情引发的JNI崩溃
- 世界最早投入运行的计算机网络是,世界最早投入运行的计算机网络是
- 柯洁获清华大学免试入学推荐资格
- 2020国开c语言程序设计1075,代号1253国开点大2017年6月春季学期本科期末考试《C语言程序设计》试题及答案.pdf...
- Python机器学习:多项式回归与模型泛化009LASSO回归
- centos 自动补全c语言,YouCompleteMe自动补全C语言大型项目 ycm
- pptx打不开,未安装该文件类型的文本转换程序~[解决方案]
- python矩阵_Python矩阵
- ipa文件反编译_iOS 逆向工程-反编译ipa包
- 论文写作之查找中文对应的英文标题引用格式
- 求解矩阵A的满秩分解的一般方法
- Unity3D VideoPlayer播放视频和音频
- 业务流程(学习笔记)
- 快速入门mybatis(查询、添加日志、插入)
- ajax 实验报告,AJAX实验报告 (4500字).doc
- 小程序(微信公众平台)监控警告来源-【JS脚本错误】
- 除法竖式在MathType中该怎样进行编辑
- 河海大学计算机科学高考分数,河海大学2019年各省各专业录取分数线
热门文章
- 解决双击.jar包无法运行
- 自动对比度、灰阶调整
- Docker - 札记 - Cannot connect to the Docker daemon at tcp://localhost:2375. Is the docker daemon runn
- 体育赛事系统设计方案
- php shopnc.dll,shopnc开发手册-ZX版.doc
- Python中pass的使用
- php限制选择图片数量,ImagePicker组件,限制选择图片数量上限(selectable={images.length 3} )失败...
- 2022下半年软考报名入口!
- (*长期更新)软考网络工程师学习笔记——Section 13 Linux网络配置命令
- matlab数字和字符串转换