当前位置: 首页 > news >正文

Linux 练习六 (IPC 管道)

文章目录

  • 1 标准管道流
  • 2 无名管道(PIPE)
  • 3 命名管道(FIFO)
    • 3.1 创建删除管道文件
    • 3.2 打开和关闭FIFO文件
    • 3.3 管道案例:基于管道的客服端服务器程序

使用环境:Ubuntu18.04
使用工具:VMWare workstations ,xshell

  作者在学习Linux的过程中对常用的命令进行记录,通过思维导图的方式梳理知识点,并且通过xshell连接vmware中ubuntu虚拟机进行操作,并将练习的截图注解,每句话对应相应的命令,读者可以无障碍跟练。第六次练习的重点在于Linux的管道,这次是进程间的管道通信不同于练习四中介绍的管道文件。
  

1 标准管道流

  • 和文件操作的io流一样,管道也支持文件流模式。通过打开和关闭管道流的函数是popen和pclose。
#include <stdio.h>
FILE* popen(const char* command, const char* open_ mode);
int pclose(FILE* fp);
  • 函数popen:允许一个程序将另一个程序作为新的进程启动,并可以传递数据给它或者通过它接收数据。command字符串就是要运行的程序名。open_mode必须是“r”或者“w”,如果是“r“被调用程序的输出就可以被调用程序使用,调用程序使用返回的FILE* 文件流指针,就可以通过调用stdio函数库中的fread来读取被调用程序的输出。如果是“w”,则可以调用fwrite向被调用程序发送数据,而被调用程序可以在自己的标准输入上读取这些数据。
  • 函数pclose:关闭相关联的文件流。
//读取当前目录下file的内容
#include<stdio.h>
int main()
{FILE* fp = open("./file","r");char buf[128] = {0};while(fgets(buf,sizeof(buf),fp)){puts(buf);}pclose(fp);return 0;
}
//写一串字符串到标准管道流,统计buf单词数量(被调用程序必须阻塞等待标准输入)
#include<stdio.h>
int main()
{char buf[128] = {"apple orign banana man fale"};FILE* fp = popen("wc -w","w");//wc -w功能是统计字符串中单词的个数fwrite(buf,sizeof(buf),1,fp);//向被调用的wc -w命令所启动的程序发送buf内容pclose(fp);return 0;
}

2 无名管道(PIPE)

管道通信是linux进程通信的一种方式,例如可以使用ps -elf|grep ntp查询和ntp相关的管道
无名管道的特点:

  1. 只能在亲缘关系进程间通信(父子进程或者兄弟进程)
  2. 半双工通信
  3. 管道是特殊文件可以使用read、write,只能存在内存中
#include<unistd.h>
int pipe(int fds[2]);
  • 管道在程序中使用一对文件描述符表示,其中一个文件描述符有可读属性,一个有可写属性。fds[0]是可读,fds[1]是可写。函数pipe用于创建一个无名管道,如果成功,fds[0]中存放文件描述符,fds[1]存放可写文件描述符,并且函数返回0,否则返回-1。
  • 通过调用pipe获取这对打开的文件描述符后,一个进程就可以从fds[0]中读数据,而另一个进程就可以向fds[1]中写数据。两进程必须有几成关系,才能继承这对打开的文件描述符。
  • 管道文件不是真正的物理文件,存活在内存中不持久。当两进程都终止后,管道就自动消失。

在这里插入图片描述

//创建父子进程,创建无名管道,父进程写数据,子进程读数据
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h> 
#include <sys/types.h>
#include <sys/wait.h>int main()
{	int fds[2];		//设置读和写两个文件描述符pipe(fds);		//使用pipe函数创建进程,并且将两个文件描述符传入参数printf("fds[0] = %d,fds[1] = %d\n",fds[0],fds[1]);char buf[32] = {'\0'};if(fork() == 0){ 		//表示子进程close(fds[1]);	//子进程关闭写操作sleep(2); 		//确保父进程有时间关闭读操作,并且向管道中写内容if(read(fds[0],buf,sizeof(buf))){	//将管道中的内容读到buf缓冲区中puts(buf);close(fds[0]);	//关闭子进程的读端exit(0);  		//结束子进程}}else{		//表示父进程close(fds[0]);				//父进程关闭读write(fds[1],"hello",6);	//从fds[1]向管道中写入hellowaitpid(-1,NULL,0);		//等待子进程关闭//wait(NULL);			//和waitpid同等效果//write(fds[1],"world",6);	//此时会出现断开的管道因为子进程的读已经关闭了close(fds[1]);				//父进程关闭写exit(0);}return 0;
}
  • 管道两端的关闭是有先后顺序的,如果先关闭写端从另一端读取数据时,read函数会返回0,表示管道已经关闭。但是如果先关闭读端从另一端写入数据时,则会将写数据的进程接收到 SIGPIPE 信号,如果写的进程不对此信号处理,导致写进程终止。如果写进程处理了此信号,则写数据的write函数返回一个负值,表示管道已经关闭。看如下代码:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>int main()
{int fds[2];pipe(fds);//注释掉这部分将导致写进程被信号SIGPIPE终止,目的是屏蔽SIGPIPE信号,使进程不被终止sigset_t setSig; 			//设置信号集sigemptyset(&setSig);		//将信号集清空,初始化信号集sigaddset(&setSig,SIGPIPE);	//将SIGPIPE信号添加到信号集sigprocmask(SIG_BLOCK,&setSig,NULL);	//将setSig信号集中的信号加入信号掩码中,作为新的信号屏蔽字char szBuf[10] = {0};if(fork() == 0){  		//子进程close(fds[1]);		//子进程关闭写sleep(2);			//确保父关闭读的时间,并且写入管道中if(read(fds[0], szBuf, sizeof(szBuf)))	//读取管道中的内容puts(szBuf);close(fds[0]);		//子进程关闭读}else{close(fds[0]);//父进程关闭读write(fds[1], "hello", 6);	//父进程通过fds[1]向管道中写入hellowait(NULL);			//等待子进程结束write(fds[1], "world", 6);	//子进程已经关闭了,父进程读不到东西了close(fds[1]);				//父进程关闭读}return 0;
}

3 命名管道(FIFO)

  • 上一节讲了无名管道只能在亲缘关系的进程中通信,很大程度上限制了管道的使用。命名管道可以突破这个限制,通过指定管道文件的路径实现不相关进程之间的通信。实际上,使用管道通信的操作,在Linux 练习四 (目录操作函数 + 文件操作函数)中就有提及,还实现了进程通信的功能。

3.1 创建删除管道文件

创建FIFO文件的方式和创建普通文件的方式一样,其函数名和 Linux下创建FIFO的命令名一样。
删除FIFO文件和 Linux下命令也一样。

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);	//创建管道文件
int unlink(const char *pathname);				//删除管道文件

参数 pathname 为要创建的 FIFO 文件的全路径名;
参数 mode为文件的访问权限
如果创建成功,则返回 0,否则-1。

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc,char *argv[])//演示通过命令行传递参数
{if(argc != 2){	//检查参数数量puts("Usage: MkFifo.exe {filename}");return -1;}if(mkfifo(argv[1], 0666) == -1){ //创建一个管道文件perror("mkfifo fail");return -2;}//删除管道文件unlink(argv[1]);return 0;
} 

还可以使用命令创建和删除FIFO文件使用两个终端完成,必须一边读一边写,否则会卡住。

  • 使用命令mkfifo创建管道文件,不能重复创建同一个管道文件
  • 可以使用unlink删除管道文件
  • 通过cat命令和echo命令和输入输出指向>和<来读写管道文件的案例,注意不要使用vim打开管道文件。
    在这里插入图片描述

3.2 打开和关闭FIFO文件

  • 对 FIFO 类型的文件的打开/关闭跟普通文件一样,都是使用 open 和 close 函数。如果打开时使用O_WRONLY 选项,则打开 FIFO 的写入端,如果使用 O_RDONLY 选项,则打开FIFO 的读取端,写入端和读取端都可以被几个进程同时打开。在Linux 练习四 (目录操作函数 + 文件操作函数)中2.10 管道中有提及。
  • 如果以读取方式打开 FIFO,并且还没有其它进程以写入方式打开 FIFO,open 函数将被阻塞;同样,如果以写入方式打开 FIFO,并且还没其它进程以读取方式 FIFO,open 函数也将被阻塞。
  • 与 PIPE 相同,关闭 FIFO 时,如果先关读取端,将导致继续往 FIFO 中写数据的进程接收 SIGPIPE 的信号

3.3 管道案例:基于管道的客服端服务器程序

  • 服务器端:
    维护服务器管道,接受来自客户端发来的字符串,将小写字母转换为大写字母,然后通过每个客户端维护的管道发给客户端。
//客户端代码
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<ctype.h>
//定义客户端数据结构体
typedef struct tagmag
{int client_pid;char my_data[512];
}MSG;int main()
{int server_fifo_fd,client_fifo_fd;	//定义客户端管道描述符和用户端管道描述符char client_fifo[256];				//设置客户端缓冲区MSG my_msg;		char* pstr;memset(&my_msg,0,sizeof(MSG));		//清空my_msgmkfifo("SERVER_FIFO",0777);			//新建一个管道文件,权限是0777server_fifo_fd = open("./SERVER_FIFO",O_RDONLY);	//以只读的方式打开管道文件if(server_fifo_fd == -1){	//打开失败的处理perror("server_fifo_fd");exit(-1);}int iret;//读取管道文件不为空的情况,将管道内容读到结构体的my_data中while((iret = read(server_fifo_fd,&my_msg.my_data,sizeof(MSG))>0)){ pstr = my_msg.my_data;		printf("%s\n",my_msg.my_data);		//打印客户端数据while(*pstr!='\0'){					//将所有字符转为大写字符*pstr = toupper(*pstr);pstr++;	}memset(client_fifo,0,256);	//清空管道文件sprintf(client_fifo,"CLIENT_FIFO_%d",my_msg.client_pid);//客户端pid格式化写入client_fifo中client_fifo_fd = open(client_fifo,O_WRONLY);//客户端以只写的方式打开client_fifo命名的文件客户管道if(client_fifo_fd == -1){perror("client_fifo_fd");exit(-1);}write(client_fifo_fd,&my_msg,sizeof(MSG)); //将结构体写入管道内容printf("%s\n",my_msg.my_data);printf("OVER!\n");close(client_fifo_fd);}return 0;
}
  • 客户端:
    想服务器端发送数据,然后从自己的客户端管道中接受服务器返回的数据。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
//定义客户端数据结构体
typedef struct tagmag
{int client_pid;char my_data[512];
}MSG;int main()
{int server_fifo_fd,client_fifo_fd;char client_fifo[256] = {0};sprintf(client_fifo,"CLIENT_FIFO_%d",getpid());//将客户端id写入client_fifo字符串中MSG my_msg;memset(&my_msg,0,sizeof(MSG));	//清空结构体my_msg.client_pid = getpid();	//获取客户端的进程idserver_fifo_fd = open("./SERVER_FIFO_NAME",O_WRONLY);	//以只写的方式打开服务端管道文件,并获取文件描述符mkfifo(client_fifo,0777); //以client_fifo的内容,创建属于该进程的管道文件while(1){int n = read(STDIN_FILENO,my_msg.my_data,512);//从标准输入读入字符串到my_datamy_msg.my_data[n] = '\0';write(server_fifo_fd,&my_msg,sizeof(MSG));//将结构体内容写入服务器管道文件中client_fifo_fd = open(client_fifo,O_RDONLY);//以只读的方式打开客户端管道文件,并且获取文件描述符n = read(client_fifo_fd,&my_msg,sizeof(MSG));//将结构体读入客户端管道文件中my_msg.my_data[n] = 0;	write(STDOUT_FILENO,my_msg.my_data,strlen(my_msg.my_data));//将my_data内容写入标准输入输出中close(client_fifo_fd);//关闭客户端}unlink(client_fifo);//删除客户端管道文件return 0;
}

相关文章:

Linux 练习六 (IPC 管道)

文章目录1 标准管道流2 无名管道&#xff08;PIPE&#xff09;3 命名管道&#xff08;FIFO&#xff09;3.1 创建删除管道文件3.2 打开和关闭FIFO文件3.3 管道案例&#xff1a;基于管道的客服端服务器程序使用环境&#xff1a;Ubuntu18.04 使用工具&#xff1a;VMWare workstati…...

合并两个有序链表(精美图示详解哦)

全文目录引言合并两个有序链表题目描述方法一&#xff1a;将第二个链表合并到第一个思路实现方法二&#xff1a;尾插到哨兵位的头节点思路实现总结引言 在前面两篇文章中&#xff0c;我们介绍了几道链表的习题&#xff1a;反转链表、链表的中间结点、链表的倒数第k个结点&…...

33 JSON操作

目录 一、介绍 二、JSON的特点 三、JSON语法 1、json中的数据类型 四、JSON文件的定义 五、读取JSON文件 1、读取json文件的两种方式 &#xff08;1&#xff09;read、write &#xff08;2&#xff09;json.load 2、使用json.load读取json文件的步骤 3、练习读取json文件 六、练…...

三八妇女节快乐----IT女神活动随笔

献丑了&#xff0c;一首小小散文诗&#xff0c;请大家轻喷 O(≧口≦)O 我的答案 天下芸芸众生&#xff0c;好似夜幕漫天繁星。 与你相识&#xff0c;只是偶然。 简单的一个招呼&#xff0c;于是开始了一段故事。 我们或是诉说&#xff0c;或是分享&#xff1b; 我们彼此倾听&…...

【PSO-PID】使用粒子群算法整定PID参数控制起动机入口压力值

最近在学优化算法&#xff0c;接触到了经典寻优算法之粒子群PSO&#xff0c;然后就想使用PSO算法来调节PID参数&#xff0c;在试验成功之后将此控制算法应用到了空气起动系统上&#xff0c;同时与之前的控制器进行对比看看哪种控制效果最好。 0 引言 PID参数整定主要有两种&…...

当代数据分析指南:激发商业洞见的七个方法(上)

如果说眼下的发生的事能证明什么&#xff0c;那就是基于实时可信的数据分析正在变得越来越重要。但是要是想要在需要的时候准确地获取中肯的洞察&#xff0c;我们所需要的可不只是漂亮的可视化。 如何让你的员工都有能力和机会都做出最好的决策&#xff0c;不管这个决策会有多…...

javaWeb核心02-JSP、EL、JSTL、MVC

文章目录JSP1&#xff0c;JSP 概述2&#xff0c;JSP 快速入门2.1 搭建环境2.2 导入 JSP 依赖2.3 创建 jsp 页面2.4 编写代码2.5 测试3&#xff0c;JSP 原理4&#xff0c;JSP 脚本4.1 JSP 脚本分类4.2 案例4.2.1 需求4.2.2 实现4.2.3 成品代码4.2.4 测试4.3 JSP 缺点5&#xff0…...

spring-boot+mybatis-plus连接Oracle数据库,及查询相关数据

配置java 略&#xff08;这里我用的是jdk1.8&#xff09; 配置maven 环境变量&#xff1a; M2_HOME&#xff1a;D:\LJ\software\java\maven\apache-maven-3.6.3 Path&#xff1a;%M2_HOME%\bin 仓库/jdk/镜像云设置(./config/sitting) 仓库 <localRepository> D:/…...

电商使用CRM系统有什么好处,如何选择

数据显示&#xff0c;使用电商CRM客户管理系统后&#xff0c;企业销售额提高了87%&#xff0c;客户满意度提高了74%&#xff0c;业务效率提高了73%。要在竞争激烈的电商市场取得成功&#xff0c;与目标受众的有效沟通是有效的方法。下面说说什么是电商CRM系统&#xff1f;电商C…...

Nacos2.2.0多数据源适配oracle12C-修改Nacos源码

从2.2.0版本开始,可通过SPI机制注入多数据源实现插件,并在引入对应数据源实现后,便可在Nacos启动时通过读取application.properties配置文件中spring.datasource.platform配置项选择加载对应多数据源插件.本文档详细介绍一个多数据源插件如何实现以及如何使其生效。 文章目录一…...

第十四届蓝桥杯三月真题刷题训练——第 5 天

目录 题目1&#xff1a;数的分解 题目描述 运行限制 代码&#xff1a; 题目2&#xff1a;猜生日 题目描述 运行限制 代码&#xff1a; 题目3&#xff1a;成绩分析 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码&#xff1a; 题目4&#xff1a;最大和…...

大数据框架之Hive:第3章 DDL(Data Definition Language)数据定义

第3章 DDL&#xff08;Data Definition Language&#xff09;数据定义 3.1 数据库&#xff08;database&#xff09; 3.1.1 创建数据库 1&#xff09;语法 CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPER…...

概率论小课堂:统计学是大数据方法的基础

文章目录 引言I 统计学1.1 统计学的内容1.2 统计学的目的II 用好数据的五个步骤2.1 设立研究目标2.2 设计实验,选取数据。2.3 根据实验方案进行统计和实验,分析方差。2.4 通过分析进一步了解数据,提出新假说。2.5 使用研究结果III 数据没用好的原因3.1 霍桑效应3.2 数据的稀…...

监控集群概念讲解

监控概述 1、监控的重要性 监控是运维日常的重要工作之一&#xff1b; 监控是有多重要&#xff1f; 监控可以帮助运维监控服务器的状态&#xff1b;要及时解决&#xff1b; 如果淘宝、腾讯宕机了1个小时&#xff1f; 损失是无法估量的&#xff1b; 服务器是否故障、宕不…...

如何通过DAS连接GaussDB

文章目录1 实验介绍2 实验目的3 配置DAS服务4 SQL使用入门1 实验介绍 本实验主要描述如何通过华为云数据管理服务 (Data Admin Service&#xff0c;简称DAS) 来连接华为云GaussDB数据库实例&#xff0c;DAS是一款专业的简化数据库管理工具&#xff0c;提供优质的可视化操作界面…...

支持在局域网使用的项目管理系统有哪些?5款软件对比

一、选择私有部署的原因以及该方案的优点有很多可能的原因导致人们更倾向于使用私有部署的企业管理软件&#xff0c;其中一些原因可能包括&#xff1a;1.数据安全性要求&#xff1a;一些企业管理软件包含敏感的商业数据和隐私信息&#xff0c;为了保护这些信息不被未经授权的第…...

Linux CentOS7 MySQL 5.7安装

准备工作 //创建目录 mkdir /opt/mysql //跳转目录 cd /opt/mysql下载MySQL 请耐心等待&#xff0c;也可以在Windows下载以后上传到 /opt/mysql目录 wget http://dev.mysql.com/get/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar解压 tar -xvf mysql-5.7.26-1.el7.x86_64.rpm-b…...

Kubernetes学习(四)控制器

ReplicaSet ReplicaSet的目的是维护一组在任何时候都处于运行状态的Pod副本的稳定集合。因此&#xff0c;它通常用来保证给定数量的、完全相同的Pod的可用性。 ReplicaSet的工作原理 ReplicaSet是通过一组字段来定义的&#xff0c;包括一个用来识别可获得的pod的集合的选择符…...

vue组件间通信的几个方法

一&#xff0c;props属性传递数据 适用场景&#xff1a;父组件传递数据给子组件 子组件设置props属性&#xff0c;定义接收父组件传递过来的参数 父组件在使用子组件标签中通过字面量来传递值 Children.vue props:{ // 字符串形式 name:String // 接收的类型参数 // 对象…...

商品价格区间设置与排序--课后程序(Python程序开发案例教程-黑马程序员编著-第4章-课后作业)

实例2&#xff1a;商品价格区间设置与排序 在网上购物时&#xff0c;面对琳琅满目的商品&#xff0c;我们应该如何快速选择适合自己的商品呢&#xff1f;为了能够让用户快速地定位到适合自己的商品&#xff0c;每个电商购物平台都提供价格排序与设置价格区间功能。假设现在某平…...

mybatis中sqlSession的使用

文章目录sqlsession的使用依赖jdbc.propertiesmysql-config.xml配置逆向工程创建sqlSessionsqlsession的使用 在最开始我们使用jdbcUtil的方式进行硬编码&#xff0c;sql字符串写的很难受&#xff0c;使用mybatis可以解决这个问题&#xff0c;它提供了数据库与实体类的关系映射…...

TPOT(Tree-based Pipeline Optimization Tool) API简介

文章目录TPOT简介TPOT APIClassification接口形式&#xff1a;Parameters&#xff1a;Attributes:Functions&#xff1a;Regression接口形式Parameters:&#xff08;只列与分类任务有差异的参数&#xff09;TPOT简介 TPOT是一个Python自动机器学习&#xff08;AML&#xff09;…...

Java 19和IntelliJ IDEA,如何和谐共生?

Java仍然是目前比较流行的编程语言&#xff0c;它更短的发布节奏让开发者每六个月左右就可以试用新的语言或平台功能&#xff0c;IntelliJ IDEA帮助我们更流畅地发现和使用这些新功能。IntelliJ IDEA v2022.3正式版下载(Q技术交流&#xff1a;786598704&#xff09;在本文中&am…...

js循环判断的方法

js循环判断的方法if语句if else语句if else if else if......三元表达式switchswitch语句和if语句的区别for循环while循环do while循环for inforEachfor of性能问题if语句 条件满足就执行&#xff0c;不满足就不执行 if(条件){语句}if else语句 条件满足&#xff0c;执行语句…...

git快速入门(1)

1 git的下载与安装1&#xff09;下载git安装包下载路径&#xff1a;https://git-scm.com/我的操作系统是window&#xff0c;64位的&#xff0c;我下载的Git-2.33.0-64-bit.exe&#xff0c;从官网下载或者从网址下载链接&#xff1a;链接地址&#xff1a;https://pan.baidu.com/…...

韩国绿芯1~16通道触摸芯片型号推荐

随着技术的发展&#xff0c;触摸感应技术正日益受到更多关注和应用&#xff0c;目前实现触摸感应的方式主要有两种&#xff0c;一种是电阻式&#xff0c;另一种是电容式。电容式触摸具有感应灵敏、功耗低、寿命长等特点&#xff0c;因此逐步取代电阻式触摸&#xff0c;成为当前…...

Go语言设计与实现 -- http服务器编程

Go http服务器编程 初始 http 是典型的 C/S 架构&#xff0c;客户端向服务端发送请求&#xff08;request&#xff09;&#xff0c;服务端做出应答&#xff08;response&#xff09;。 golang 的标准库 net/http 提供了 http 编程有关的接口&#xff0c;封装了内部TCP连接和…...

MySQL-视图

视图是什么&#xff1f; 一张虚表&#xff0c;和真实的表一样。视图包含一系列带有名称的行和列数据。视图是从一个或多个表中导出来的&#xff0c;我们可以通过insert&#xff0c;update&#xff0c;delete来操作视图。当通过视图看到的数据被修改时&#xff0c;相应的原表的数…...

都工作3年了,怎么能不懂双亲委派呢?(带你手把手断点源码)

&#x1f497;推荐阅读文章&#x1f497; &#x1f338;JavaSE系列&#x1f338;&#x1f449;1️⃣《JavaSE系列教程》&#x1f33a;MySQL系列&#x1f33a;&#x1f449;2️⃣《MySQL系列教程》&#x1f340;JavaWeb系列&#x1f340;&#x1f449;3️⃣《JavaWeb系列教程》…...

Hive 运行环境搭建

文章目录Hive 运行环境搭建一、Hive 安装部署1、安装hive2、MySQL 安装3、Hive 元数据配置到 Mysql1) 拷贝驱动2) 配置Metastore 到 MySQL3) 再次启动Hive4) 使用元数据服务的方式访问Hive二、使用Dbaver连接HiveHive 运行环境搭建 HIve 下载地址&#xff1a;http://archive.a…...

网站宣传夸大处罚/重庆网站建设维护

1&#xff0c;font-size属性设置字体的大小 声明&#xff1a; 有能力管理文本的大小在 web 设计领域很重要。但是&#xff0c;您不应当通过调整文本大小使段落看上去像标题&#xff0c;或者使标题看上去像段落。 请始终使用正确的 HTML 标题&#xff0c;比如使用 <h1> - …...

网站建设支付接口/seo怎样才能优化网站

这学期的算法&#xff0c;编译这些不限语言的课&#xff0c;我基本都用了ocaml自己写&#xff08;这样就不会被同学要代码了&#xff09; 之前我在JavaScript写函数式&#xff0c;总觉着怪怪的&#xff0c;直到我找到了OCaml 虽然这个语言和我一样大&#xff0c;但是普及度堪忧…...

discuz可以做公司网站/公司的网站制作

前言:想必大家在实际编码中都遇到过JDBC的操作, 这里仅做自己的一个总结, 有错误和不完整之处还请大家提出来. 1,JDBC其实一套规范(接口)数据库厂商需要实现此接口(实现类)--数据库驱动 2,jdbc的作用: 可以和数据库创建链接 发送sql语句 接收返回值,处理结果 3,api详解(java.sq…...

网上可以报警备案吗/大连seo优化

你已经在虚拟机中安装了Ubuntu&#xff0c;你可能会发现拥有一个带有Windows主机操作系统的共享文件夹很有用。 1&#xff1a;在Windows 下共享一个文件目录&#xff0c;文件目录上右键&#xff0c;属性&#xff0c;共享。 2&#xff1a;虚拟机上关电Ubuntu。 3&#xff1a;…...

这个网站最近运转怎么样?安全性怎么样? 另外建设银行的网银能在这里存取款吗?/百度搜索关键词排名靠前

单元测试注定是我程序生涯最重要的工作之一。 http://www.cnblogs.com/leoo2sk/archive/2010/01/13/pragmatic-unit-testing-with-nunit.html 转载于:https://www.cnblogs.com/ToughGuy/p/3486002.html...

单位网站建设开发公司/2023年12月疫情又开始了吗

/** *author blovedr * 功能&#xff1a; java绘图原理------在窗口界面&#xff08;或面板上&#xff09;画出一张或多张图片问题解决方法 * 日期&#xff1a; 2018年4月28日 16:20 * 注释&#xff1a; 学习java的点点记录&#xff0c; 欢迎各位大神批评指导与交流。 */ p…...