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

在线OJ项目核心思路

文章目录

  • 在线OJ项目核心思路
    • 1. 项目介绍
    • 2.预备知识
      • 理解多进程编程
      • 为啥采用多进程而不使用多线程?
      • 标准输入&标准输出&标准错误
    • 3.项目实现
      • 题目API实现
        • 相关实体类定义
        • 新增/修改题目
        • 获取题目列表
      • 编译运行
        • 编译运行流程
    • 4.统一功能处理


在线OJ项目核心思路

在这里插入图片描述

1. 项目介绍

该项目是一个类似于力扣的在线OJ平台,可以进行题目的编写和提交编译运行以及结果展示,使用的技术栈有:Java、MySQL、SpringBoot、MyBatis、Redis、Nginx、Docker

主要功能如下:

  1. 登录和注册(Session持久化+密码加盐)
  2. 图形验证码验证登录
  3. 题目管理(题目的添加和修改)
  4. 题目提交(编译+运行)
  5. 题目编译/运行结果展示
  6. Nginx+Docker实现负载均衡

在这里插入图片描述

2.预备知识

理解多进程编程

什么是进程?

进程可以看做操作系统中一个正在运行的程序的一个抽象,也可以把进程看做是程序的一次运行过程。在操作系统内部,进程是操作系统进行资源分配的基本单位

  • 使用 PCB(进程控制块) 描述进程

  • 组织:使用一定的数据结构来组织,常见做法就是使用双向链表

  • 进程之间是相互独立的

什么是多进程?

一个CPU运行多个进程

由于CPU的运行速度极快,虽然CPU在一直进行切换,但是咱们坐在电脑前的用户,是感知不到这个切换过程的

进程和线程的关系

  1. 进程是包含线程的,一个进程里可以有一个线程,也可以有多个线程
  2. 每个进程都有独立的内存空间(虚拟地址空间),同一个进程的多个线程之间,共用这个虚拟地址空间
  3. 进程是操作系统分配资源的基本单位,线程是操作系统调度执行的基本单位
  4. 如果一个进程挂了, 不会影响到其他进程. 如果一个线程挂了, 则整个进程都要异常终止.
  5. 进程更重量, 线程更轻量. 创建/销毁/调度线程比进程更高效.

Java中的多进程编程

Java中中对系统提供的进程创建、进程终止、进程程序替换、进程间通信进程了限制,最终只给用户提供了两个操作

进程的创建

创建出一个新的进程,让这个新的进程来执行一系列任务,被创建出来的进程,称为"子进程",创建子进程的进程,称为"父进程",服务器的进程就相当于一个父进程

根据收到的用户发送过来的代码再 创建出一个子进程,一个父进程,可以有多个子进程,但是一个子进程,只能有一个父进程

为啥采用多进程而不使用多线程?

一个操作系统上是运行了很多进程的,因为进程之间是相互隔离的,一个进程挂了是不会影响到其它进程的。如果使用多线程,我们并不知道用户提交的会提交什么样的代码,很可能提交一些恶意代码导致线程崩溃,而线程挂了很有可能就影响到了我们的整个服务进程。所以一定要采用多进程而不是多线程。

标准输入&标准输出&标准错误

java和javac是一个控制台程序,它的输出,是输出到“标准输出”和"标准错误"这两个特殊的文件当中的,一个进程启动的时候,就会自动打开三个文件:

  1. 标准输入,对应到键盘
  2. 标准输出,对应到显示器
  3. 标椎错误,对应到显示器

Runtime是Java中内置的一个单例类

  • 通过runtime.exec方法参数是一个字符串,表示一个可执行程序的路径,执行这个方法就会把指定路径的可执行程序,创建出一个子进程并执行。
  • runtime.exec()方法返回的是一个Process类,表示的就是一个子进程,后续通过这个子进程来进行操作
    • 获取标准输入:process.getInputStream():该方法能把process这个子进程的标准输出给读取出来
    • 获取标准错误:process.getErrorStream():该方法能把process这个子进程的标准错误给读取出来
    • 进程等待: process.waitFor():该方法能能让主进程进行阻塞等待,等待子进程process执行完毕。

3.项目实现

题目API实现

相关实体类定义

题目实体类

public class Problem {private Integer id;private String title;private String levels;private String description;private String templateCode;private String testCode;private Date createTime;private Date updateTime;
}
新增/修改题目

新增修改题目通过判断url中的querystr里是否存在题目Id,来判断是修改题目还是新增题目

约定请求:

post
{"id" : "","title" : "题目标题","levels" : "题目难度","description" : "题干","templateCode" : "题目代码模板","testCode" :  "题目测试用例"
}

响应:

{code : 200,message : ""data: 
}
@PostMapping("/add")
public Response add(@RequestBody Problem problem) {if (problem == null || problem.getTitle() == null || "".equals(problem.getTitle().trim()) || problem.getLevels() == null ||"".equals(problem.getLevels().trim()) || problem.getTestCode() == null || "".equals(problem.getTestCode().trim()) ||problem.getTemplateCode() == null || "".equals(problem.getTemplateCode().trim())) {return Response.fail("题目参数不完整");}int ret = problemService.add(problem);if (ret == 1) {return Response.success(200,"添加成功");}return Response.fail("添加失败");
}
获取题目列表

请求:

post
{/problem/all
}

响应:

{code : 200,message:"",data:[{id : 1,title: "两数之和",levels: "简单",description: "题干",template: "题目模板"}]
}

编译运行

通过Answer表示编译运行结果,约定:

  • 错误码为0表示运行成功
  • 错误码为1表示编译错误
  • 错误码为2表示运行错误
  • 错误码为1表示提交了违规代码
public class Answer {// 错误码 0表示运行成功,1表示编译错误,2表示运行错误,-1表示违规代码private Integer errorCode;// 标准输出private String stdout;// 错误信息private String errorInfo;
}

Task类描述的是每一次代码的提交:

通过UUID生成唯一的目录,保证每个用户提交的代码相互隔离

public class Task {// 存放临时文件目录private String workDir;// 运行文件路径private String className;// 编译文件路径private String classFile;// 存放编译错误信息文件private String compileErrorFile;// 标准输出文件private String stdoutFile;// 标准错误文件private String stderrFile;public Task() {this.workDir = "./tmp/"+UUID.randomUUID().toString()+"/";this.className = "Solution";this.classFile = workDir+ "Solution.java";this.compileErrorFile = workDir+"compileErrInfo.txt";this.stdoutFile = workDir+"stdout.txt";this.stderrFile = workDir+"stderr.txt";}
}
编译运行流程

请求:

{problemId : "题目id",code : "提交的代码"
}

响应:

{code : 200,message : "信息",data:{errorCode : "错误码",stdout: "标准输出",derrorInfo, "出错信息"}
}

编译运行流程:

  1. 对用户提交代码进行判空
  2. 从数据库中查询出测试用例进和提交代码进行拼接,形成完整代码。
  3. 对用户提交代码进行安全校验,判断其是否提交操作系统命令、文件网络等危险操作代码
  4. 把拼接好的代码写入到对应文件
  5. 进行编译和运行。

如下方法表示一次编译或者运行:

  • 通过判断stdoutFile是否为空来判断是编译还是运行
  • 从子进程process中的标准错误流中读取数据写入到task类的唯一的编译错误信息文件中,再判断文件内容是否为空
  • 如果编译错误信息文件不为空,说明编译出错直接返回
  • 如果编译错误信息文件为空,说明编译正确,再对编译后的字节码进行运行
  • 运行后再进行判断标准错误信息文件是否为空,如果为空说明运行正常,读取到标准输入文件里的信息返回给用户
/*** 编译运行* @param cmd 执行的命令* @param stdoutFile* @param stderrFile* @return*/
public static int run(String cmd,String stdoutFile,String stderrFile) {Runtime runtime =  Runtime.getRuntime();int exitCode = -1;try {// 执行命令获得子进程Process process = runtime.exec(cmd);// 编译if (stdoutFile == null) {try (InputStream stderrInoutStream = process.getErrorStream();OutputStream stderrOutputSteam = new FileOutputStream(stderrFile);){int ch;// 将错误信息读入到错误日志文件while ((ch = stderrInoutStream.read()) != -1) {stderrOutputSteam.write(ch);}}}// 说明是运行if (stdoutFile != null) {try (InputStream stderrInoutStream = process.getErrorStream();OutputStream stderrOutputSteam = new FileOutputStream(stderrFile);InputStream stdoutInputStream = process.getInputStream();OutputStream stdOutputStream = new FileOutputStream(stdoutFile)){// 获取标准错误输入流int ch;// 将错误信息读入到错误日志文件while ((ch = stderrInoutStream.read()) != -1) {stderrOutputSteam.write(ch);}// 将子进程标准输出写入到指定文件while ((ch = stdoutInputStream.read()) != -1) {stdOutputStream.write(ch);}}}// 进程等待exitCode = process.waitFor();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}return exitCode;
}

拼接编译命令时通过 -d指定编译后的文件存放到指定位置,不然找不到字节码文件位置。

// 2.拼接编译命令
String compileCmd = String.format("javac -encoding utf8 %s -d %s",classFile,workDir);
//4.运行代码
String runCmd = String.format("java -classpath %s %s",workDir,className);

4.统一功能处理

统一登录拦截

定义拦截器:

  1. 创建自定义拦截器,实现Handlerlnterceptor接口的preHandle(执行具体方法之前的预处理)方法
  2. 将自定义拦截器加入WebMvcConfigureraddInterceptors

提供一个管理员页面来对题目进行添加和修改。管理员页面使用拦截器对普通用户进行拦截.

@Configuration
public class AppConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login").excludePathPatterns("/user/reg").excludePathPatterns("/user/verificationCode").excludePathPatterns("/login.html").excludePathPatterns("/reg.html").excludePathPatterns("/css/**").excludePathPatterns("/js/**").excludePathPatterns("/img/**");registry.addInterceptor(new AdminInterceptor()).addPathPatterns("/admin.html").addPathPatterns("/addProblem.html").addPathPatterns("/problem/update").addPathPatterns("/problem/add");}
}

统一格式返回

统一的数据返回格式使用@ControllerAdvice+ResponseBodyAdvice实现

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Resourceprivate ObjectMapper objectMapper;@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body instanceof Response) {return body;}if (body instanceof  String) {try {return objectMapper.writeValueAsString(body);} catch (JsonProcessingException e) {e.printStackTrace();}}return Response.success(body);}
}

统一异常处理

@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandler(Exception.class)@ResponseBodypublic Response exceptionAdvice(Exception e) {return Response.fail("服务器异常");}
}

相关文章:

在线OJ项目核心思路

文章目录 在线OJ项目核心思路1. 项目介绍2.预备知识理解多进程编程为啥采用多进程而不使用多线程?标准输入&标准输出&标准错误 3.项目实现题目API实现相关实体类定义新增/修改题目获取题目列表 编译运行编译运行流程 4.统一功能处理 在线OJ项目核心思路 1. 项目介绍 …...

Spring MVC:数据绑定

Spring MVC 数据绑定数据类型转换数据格式化数据校验 附 数据绑定 数据绑定,指 Web 页面上请求和响应的数据与 Controller 中对应处理方法上的对象绑定(即是将用户提交的表单数据绑定到 Java 对象中)。 过程如下: ServletRequest…...

STM32CubeMX学习笔记-USB接口使用(HID按键)

STM32CubeMX学习笔记-USB接口使用(HID按键) 一、USB简介1.1 USB HID简介 二、新建工程1. 打开 STM32CubeMX 软件,点击“新建工程”2. 选择 MCU 和封装3. 配置时钟4. 配置调试模式 三、USB3.1 参数配置3.2 引脚配置3.3 配置时钟3.4 USB Device…...

C#,数值计算——Ranq2的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Backup generator if Ranq1 has too short a period and Ran is too slow.The /// period is 8.5E37. Calling conventions same as Ran, above. /// </summary> …...

C/C++ 数据结构 - 链表

1.单链表 https://blog.csdn.net/qq_36806987/article/details/79858957 1 #include<stdio.h>2 #include<stdlib.h>3 4 /*结构体部分*/5 typedef struct Node6 {7 int data; //数值域8 struct Node *next; //指针域9 }N;10 11 N *Init() //初始化单…...

【算法基础】一文掌握十大排序算法,冒泡排序、插入排序、选择排序、归并排序、计数排序、基数排序、希尔排序和堆排序

目录 1 冒泡排序&#xff08;Bubble Sort&#xff09; 2 插入排序&#xff08;Insertion Sort&#xff09; 3 选择排序&#xff08;Selection Sort&#xff09; 4. 快速排序&#xff08;Quick Sort&#xff09; 5. 归并排序&#xff08;Merge Sort&#xff09; 6 堆排序 …...

javascript二维数组(3):指定数组元素的特定属性进行搜索

js中对数组&#xff0c; var data [{“name”: “《西游记》”, “author”: “吴承恩”, “cat”: “A级书刊”, “num”: 3},{“name”: “《三国演义》”, “author”: “罗贯中”, “cat”: “A级书刊”, “num”: 8},{“name”: “《红楼梦》”, “author”: “曹雪芹”,…...

使用Qt进行HTTP通信的方法

文章目录 1 HTTP协议简介1.1 HTTP协议的历史和发展1.2 HTTP协议的特点1.3 HTTP的工作过程1.4 请求报文1.5 响应报文 2 使用Qt进行HTTP通信2.1 Qt的HTTP通信类2.2 HTTP通信过程 3 JSON3.1 cJSON库简介3.2 cJSON库的设计思想和数据结构3.3 cJSON库的使用方法 1 HTTP协议简介 1.1…...

第45节——页面中修改redux里的数据

一、什么是action 在 Redux 中&#xff0c;Action 是一个简单的 JavaScript 对象&#xff0c;用于描述对应应用中的某个事件&#xff08;例如用户操作&#xff09;所发生的变化。它包含了一个 type 属性&#xff0c;用于表示事件的类型&#xff0c;以及其他一些可选的数据。 …...

软考 系统架构设计师系列知识点之软件架构风格(2)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之软件架构风格&#xff08;1&#xff09; 这个十一注定是一个不能放松、保持“紧”的十一。由于报名了全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff0c;11月4号就要考试&#xff0c;因此…...

【C++11】Lambda 表达式:基本使用 和 底层原理

文章目录 Lambda 表达式1. 不考虑捕捉列表1.1 简单使用介绍1.2 简单使用举例 2. 捕捉列表 [ ] 和 mutable 关键字2.1 使用方法传值捕捉传引用捕捉 2.2 捕捉方法一览2.3 使用举例 3. lambda 的底层分析 Lambda 表达式 书写格式&#xff1a; [capture_list](parameters) mutabl…...

【网络安全---ICMP报文分析】Wireshark教程----Wireshark 分析ICMP报文数据试验

一&#xff0c;试验环境搭建 1-1 试验环境示例图 1-2 环境准备 两台kali主机&#xff08;虚拟机&#xff09; kali2022 192.168.220.129/24 kali2022 192.168.220.3/27 1-2-1 网关配置&#xff1a; 编辑-------- 虚拟网路编辑器 更改设置进来以后 &#xff0c;先选择N…...

【Docker】Docker的应用包含Sandbox、PaaS、Open Solution以及IT运维概念的详细讲解

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…...

Java Applet基础

Java Applet基础 目录 Java Applet基础 Applet的生命周期 "Hello, World" Applet: Applet 类 Applet的调用 获得applet参数 指定applet参数 应用程序转换成Applet 事件处理 显示图片 播放音频 applet是一种Java程序。它一般运行在支持Java的Web浏览器内。因…...

【记录】IDA|IDA怎么查看当前二进制文件自动分析出来的内存分布情况(内存范围和读写性)

IDA版本&#xff1a;7.6 背景&#xff1a;我之前一直是直接看Text View里面的地址的首尾地址来判断内存分布情况的&#xff0c;似乎是有点不准确&#xff0c;然后才想到IDA肯定自带查看内存分布情况的功能&#xff0c;而且很简单。 可以通过View-Toolbars-Segments&#xff0c…...

LIMS实验室信息管理系统源码 基于计算机的数据处理技术、数据存储技术、网络传输技术、自动化仪器分析技术于一体

LIMS 是一个集现代化管理思想与基于计算机的数据处理技术、数据存储技术、网络传输技术、自动化仪器分析技术于一体&#xff0c;以实验室业务和管理工作为核心&#xff0c;遵循实验室管理国际规范&#xff0c;实现对实验室全方位管理的信息管理系统。 LIMS将样品管理、数据管理…...

有效括号相关

相关题目 20. 有效的括号 921. 使括号有效的最少添加 1541. 平衡括号字符串的最少插入次数 32. 最长有效括号 # 20. 有效的括号 class Solution:def isValid(self, s: str) -> bool:stack []for pare in s:if pare in ([{:stack.append(pare)if not stack or (pare ) and…...

浅谈泛型擦除

文章目录 泛型擦除(1)转换泛型表达式(2)转换泛型方法泛型擦除带来的问题 泛型擦除 在编码阶段使用泛型时加上的类型参数&#xff0c;会被编译器在编译阶段去掉&#xff0c;这个过程叫做泛型擦除。 泛型主要用于编译阶段。在编译后生成的Java字节码文件中不包含泛型中的类型信息…...

nodejs+vue校园跑腿系统elementui

购物车品结算,管理个人中心&#xff0c;订单管理&#xff0c;接单处理&#xff0c;商品维护&#xff0c;用户管理&#xff0c;系统管理等功育食5&#xff09;要求系统运行可靠、性能稳定、界面友好、使用方便。 第三章 系统分析 10 3.1需求分析 10 3.2可行性分析 10 3.2.1技术…...

Redis Cluster Cron调度

返回目录 说明 clusterCron 每秒执行10次clusterCron 内置了一个iteration计数器。每一次运行clusterCron&#xff0c;iteration都加1。当 iteration % 10 0的时候&#xff0c;就会随机选取一个节点&#xff0c;给它发送PING。而由于clusterCron每秒执行10次&#xff0c;所以…...

Redis Cluster Gossip Protocol: Message

返回目录 消息结构 消息头部消息数据&#xff08;可选&#xff09;extension&#xff08;可选&#xff09; 消息头部 字段定义 Signature: “RCmb” 这4个字符&#xff08;Redis Cluster message bus 的简称&#xff09;totalLen: 消息的总字节数version&#xff1a;当前为…...

【JVM】第四篇 垃圾收集器ParNewCMS底层三色标记算法详解

导航 一. 垃圾收集算法详解1. 分代收集算法2. 标记-复制算法3. 标记-清除算法4. 标记-整理算法二. 垃圾收集器详解1. Serial收集器2. Parallel Scavenge收集器3. ParNew收集器4. CMS收集器三. 垃圾收集底层三色标记算法实现原理1. 垃圾收集底层使用三色标记算法的原因?2. 垃圾…...

STM32复习笔记(四):独立看门狗IWDG

目录 &#xff08;一&#xff09;简介 &#xff08;二&#xff09;CUBEMX工程配置 &#xff08;三&#xff09;相关函数 总结&#xff1a; &#xff08;一&#xff09;简介 独立看门狗本质是一种定时器&#xff0c;其作用是监视系统的运行&#xff0c;当系统发生错误&…...

SpringBoot中常用注解的含义

一、方法参数注解 1. PathVariable 通过RequestMapping注解中的 { } 占位符来标识URL中的变量部分 在控制器中的处理方法的形参中使用PathVariable注解去获取RequestMapping中 { } 中传进来的值&#xff0c;并绑定到处理方法定一的形参上。 //请求路径&#xff1a;http://3333…...

学位论文的写作方法,较好的参考文章

摘要 结合2个文章&#xff1a; [1]程鑫. 网联环境下交通状态预测与诱导技术研究[D]. 长安大学, 2017. [2]吴昊. 关中平原水资源变化特征与干旱脆弱性研究[D]. 长安大学, 2018. 主要研究内容及技术路线 各章小结和引言的写作 [1]程鑫. 网联环境下交通状态预测与诱导技术…...

基于SpringBoot的科研工作量获奖项目管理平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

嵌入式Linux应用开发-驱动大全-第一章同步与互斥④

嵌入式Linux应用开发-驱动大全-第一章同步与互斥④ 第一章 同步与互斥④1.5 自旋锁spinlock的实现1.5.1 自旋锁的内核结构体1.5.2 spinlock在UP系统中的实现1.5.3 spinlock在SMP系统中的实现 1.6 信号量semaphore的实现1.6.1 semaphore的内核结构体1.6.2 down函数的实现1.6.3 u…...

算法-数学-斜率-直线上最多的点数

算法-数学-斜率-直线上最多的点数 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/max-points-on-a-line/ 1.2 题目描述 给你一个数组 points &#xff0c;其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。 2 暴力搜索斜率…...

项目进展(五)-修复PCB电路板,学习32位ADC芯片ADS1285

一、前言 上个月29号放假了&#xff0c;和朋友一起去了南京(人是真滴多)&#xff0c;师兄晚放假几天&#xff0c;结果在测试时不小心把12V和GND碰触到一起了&#xff0c;导致12V短路&#xff0c;电路板几乎瘫痪了。 今天下午到学校之后就开始着手寻找问题和修复&#xff0c;最…...

(三) Markdown插入互联网或本地视频解决方案

前言 不论博客系统是WordPress还是Typecho&#xff0c;绕不开的是两种书写语言&#xff0c;一种称之为富文本&#xff0c;一种叫做Markdown。 Markdown有很多好处&#xff0c;也有很多坏处&#xff0c;比如Markdown本身不具备段落居中的功能&#xff0c;以及Markdown也不具有…...

苏州做视频网站广告公司/网站平台怎么推广

Ecshop这款程序虽然目前已经开发的相当成熟了&#xff0c;可是后台的一些功能还是比较烂&#xff0c;原因只有一个那就是它属于开源程序&#xff0c;很多站长们使用这款程序搭建商城&#xff0c;可是由于自己的疏忽不小心忘记了账号密码&#xff0c;这时候再想登陆到后台去就需…...

企业网站相关案例/惠州seo排名外包

https://www.cnblogs.com/lantingg/p/9418307.html 转载于:https://www.cnblogs.com/tsql/p/11468145.html...

wordpress 小米商城主题/什么是seo是什么意思

目录 A、阶乘求和 Ⅰ、题目解读 Ⅱ、代码 B、幸运数字 Ⅰ、题目解读 Ⅱ、代码 C: 数组分割&#xff08;时间限制: 1.0s 内存限制: 512.0MB&#xff09; D、矩形总面积&#xff08;时间限制: 1.0s 内存限制: 512.0MB&#xff09; Ⅰ、题目解读 Ⅱ、代码 E、蜗牛&#xff…...

网站怎么做?/查询网站服务器

百分点是一个推荐服务的提供商&#xff0c;但是已经转型为大数据解决方案的提供商。 首先看一下大数据与应用画像的关系&#xff0c;现在大数据是炙手可热的&#xff0c;大数据的4个V都比较了解&#xff0c;大数据应该说是信息技术的自然延伸&#xff0c;意味的无所不在的数据…...

做pc端网站适配/网站运营主要做什么工作

分享一下我老师大神的人工智能教程&#xff01;零基础&#xff0c;通俗易懂&#xff01;http://blog.csdn.net/jiangjunshow也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01;1&#xff0e; Kafka整体结构图Kafka名词解释…...

扁平化设计网站欣赏/网络营销形式

C20(C 编程语言标准2020版)将是C 语言一次非常重大的更新&#xff0c;将为这门语言引入大量新特性。c20标准文档是官方目前最新文件&#xff0c;更新2020年。需要的朋友可下载试试&#xff01;此次更新看 C20 的 Big Four(四大新特性&#xff1a;概念、范围、协程和模块)以及核…...