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

全方位揭秘!大数据从0到1的完美落地之运行流程和分片机制


 

一个完整的MapReduce程序在分布式运行时有三类实例进程:

  • MRAppMaster: 负责整个程序的过程调度及状态协调
  • MapTask: 负责Map阶段的整个数据处理流程
  • ReduceTask: 负责Reduce阶段的整个数据处理流程

当一个作业提交后(mr程序启动),大概流程如下:

  1. 一个mr程序启动的时候,会先启动一个进程Application Master,它的主类是MRAppMaster
  2. ApplicationMaster启动之后会根据本次job的描述信息,计算出inputSplit的数据,也就是MapTask的数量
  3. ApplicationMaster然后向ResourceManager来申请对应数量的Container来执行MapTask进程。
  4. MapTask进程启动之后,根据对应的inputSplit来进行数据处理,处理流程如下
    1. 利用客户指定的inputformat来获取recordReader读取数据,形成kv键值对。
    2. 将kv传递给客户定义的Mapper类的map方法,做逻辑运算,并将map方法的输出kv收集到缓存。
    3. 将缓存中的kv数据按照k分区排序后不断的溢出到磁盘文件
  5. ApplicationMaster监控mapTask进程完成之后,会根据用户指定的参数来启动相应的reduceTask进程,并告知reduceTask需要处理的数据范围
  6. ReduceTask启动之后,根据ApplicationMaster告知的待处理的数据位置,从若干的已经存到磁盘的数据中拿到数据,并在本地进行一个归并排序,然后,再按照相同的key的kv为一组,调用客户自定义的reduce方法,并收集输出结果kv,然后按照用户指定的outputFormat将结果存储到外部设备。

MapReduce分片机制

分片的概念

​ MapReduce在进行作业提交时,会预先对将要分析的原始数据进行划分处理,形成一个个等长的逻辑数据对象,称之为输入分片(inputSplit),简称“分片”。MapReduce为每一个分片构建一个单独的MapTask,并由该任务来运行用户自定义的map方法,从而处理分片中的每一条记录。

分片是一个逻辑概念,分块是一个物理概念。

HDFS上数据是按照块为单位进行存储的,我们是能够实实在在的看到每一个数据块的。而分片则不然,是一个逻辑概念,用来描述一个MapTask处理的数据是属于哪个文件的,从什么字节位置开始处理,处理多少个字节的数据等等信息。

分片的大小选择

​ 每一个MapTask处理一个分片的数据,因此分片的数量就决定了MapTask的数量。拥有多个分片,就意味着会有多个MapTask并发执行处理数据集。那么一个MapTask处理多大的数据呢?这也是由分片的大小来决定的。

​ 如果分片设置的太小,那么管理分片的时间和构建MapTask的总时间将在整个作业的时间占比较大,影响程序的执行效率。例如: 一个分片设置为1KB的大小,计算分片、构建MapTask耗时10ms的时间,处理数据耗时10ms的时间,那这样的程序的效率是非常低下的。我们更加乐意让一个任务初始化的时间在整个任务中的时间占比尽可能低。

​ 如果分片设置的太大,那么分片所描述的数据可能会在两个数据块中存储,那就有可能会造成网络IO的产生,需要将数据移动到一个节点上进行处理,效率更低。

​ 因此,最佳分片大小应该和HDFS的块大小一致。

分片源码解读

FileSplit

public class FileSplit extends InputSplit implements Writable {private Path file;				// 描述文件的路径信息private long start;				// 描述这个分片需要处理的数据起点private long length;			// 描述这个分片需要处理的数据长度private String[] hosts;			// 描述这个分片对应的数据块在哪些节点private SplitLocationInfo[] hostInfos;public FileSplit() {}public FileSplit(Path file, long start, long length, String[] hosts) {this.file = file;this.start = start;this.length = length;this.hosts = hosts;}...
}
复制代码

FileInputFormat

public abstract class FileInputFormat<K, V> extends InputFormat<K, V> {// ...// 定义了一个1.1倍的溢出值private static final double SPLIT_SLOP = 1.1D;// ...// 创建一个分片对象,设置这个分片需要处理的数据位置、起点、长度、hosts等信息protected FileSplit makeSplit(Path file, long start, long length, String[] hosts) {return new FileSplit(file, start, length, hosts);}// ...// 最重要的方法: 获取文件所有的分片信息public List<InputSplit> getSplits(JobContext job) throws IOException {StopWatch sw = (new StopWatch()).start();long minSize = Math.max(this.getFormatMinSplitSize(), getMinSplitSize(job));long maxSize = getMaxSplitSize(job);List<InputSplit> splits = new ArrayList();List<FileStatus> files = this.listStatus(job);boolean ignoreDirs = !getInputDirRecursive(job) && job.getConfiguration().getBoolean("mapreduce.input.fileinputformat.input.dir.nonrecursive.ignore.subdirs", false);Iterator var10 = files.iterator();while(true) {while(true) {while(true) {FileStatus file;do {if (!var10.hasNext()) {job.getConfiguration().setLong("mapreduce.input.fileinputformat.numinputfiles", (long)files.size());sw.stop();if (LOG.isDebugEnabled()) {LOG.debug("Total # of splits generated by getSplits: " + splits.size() + ", TimeTaken: " + sw.now(TimeUnit.MILLISECONDS));}return splits;}file = (FileStatus)var10.next();} while(ignoreDirs && file.isDirectory());// 重要逻辑在这里!!!// 获取到文件的路径描述信息Path path = file.getPath();// 获取到文件的大小long length = file.getLen();// 如果文件的大小不等于0if (length != 0L) {// 获取数据块的分布信息BlockLocation[] blkLocations;if (file instanceof LocatedFileStatus) {blkLocations = ((LocatedFileStatus)file).getBlockLocations();} else {FileSystem fs = path.getFileSystem(job.getConfiguration());blkLocations = fs.getFileBlockLocations(file, 0L, length);}// 如果文件可以分片(有些文件是不可以分片的)if (this.isSplitable(job, path)) {// 获取一个Block的大小long blockSize = file.getBlockSize();// 计算分片的大小(块大小, 配置文件中设置的最小分片大小,最大分片大小的中间值)long splitSize = this.computeSplitSize(blockSize, minSize, maxSize);// 用来记录来剩多少字节的数据没有分片long bytesRemaining;int blkIndex;// 循环分片开始了!// 注意: 循环的条件,并不是剩余数量不足分片大小! 有一个1.1倍的溢出的值的!for(bytesRemaining = length; (double)bytesRemaining / (double)splitSize > 1.1D; bytesRemaining -= splitSize) {blkIndex = this.getBlockIndex(blkLocations, length - bytesRemaining);// 创建一个分片!添加到分片集合中!splits.add(this.makeSplit(path, length - bytesRemaining, splitSize, blkLocations[blkIndex].getHosts(), blkLocations[blkIndex].getCachedHosts()));}// 循环走完后,创建一个分片来描述剩余的数据if (bytesRemaining != 0L) {blkIndex = this.getBlockIndex(blkLocations, length - bytesRemaining);splits.add(this.makeSplit(path, length - bytesRemaining, bytesRemaining, blkLocations[blkIndex].getHosts(), blkLocations[blkIndex].getCachedHosts()));}} else {if (LOG.isDebugEnabled() && length > Math.min(file.getBlockSize(), minSize)) {LOG.debug("File is not splittable so no parallelization is possible: " + file.getPath());}splits.add(this.makeSplit(path, 0L, length, blkLocations[0].getHosts(), blkLocations[0].getCachedHosts()));}} else {splits.add(this.makeSplit(path, 0L, length, new String[0]));}}}}}// 计算分片大小protected long computeSplitSize(long blockSize, long minSize, long maxSize) {return Math.max(minSize, Math.min(maxSize, blockSize));}
}
复制代码

分片总结

  1. 分片大小参数

    ​ 通过分析源码,在FileInputFormat中,计算分片大小的逻辑:Math.max(minSize, Math.min(maxSize, blockSize)); 分片主要由这几个值来运算决定

    参数默认值属性
    minSize1mapreduce.input.fileinputformat.split.minsize
    maxSizeLong.MAX_VALUEmapreduce.input.fileinputformat.split.maxsize
    blockSize128Mdfs.blocksize

    通过计算的逻辑分析可以得出,分片大小的计算,是取这三个值的中间值的,因此:

    • 如果需要增大分片的大小: 调整minSize大于blockSize即可
    • 如果需要减小分片的大小: 调整maxSize小于blockSize即可
  2. 分片创建过程总结

    1. 获取文件大小及位置
    2. 判断文件是否可以分片(压缩格式有的可以进行分片,有的不可以)
    3. 获取分片的大小
    4. 剩余文件的大小/分片大小>1.1时,循环执行封装分片信息的方法,具体如下:封装一个分片信息(包含文件的路径,分片的起始偏移量,要处理的大小,分片包含的块的信息,分片中包含的块存在哪儿些机器上)
    5. 剩余文件的大小/分片大小<=1.1且不等于0时,封装一个分片信息(包含文件的路径,分片的起始偏移量,要处理的大小,分片包含的块的信息,分片中包含的块存在哪儿些机器上)
    复制代码

    注意事项: 1.1倍的冗余

    一个260M的文件,分几块?分几片?

    • 分块是物理概念: 128M + 128M + 4M,因此一共有3个分块。
    • 分片是逻辑概念:
      • 第一个分片: 260M/128M > 1.1,因此第一个分片大小128M,剩余132M数据未分片。
      • 第二个分片: 132M/128M < 1.1,因此第二个分片大小132M
      • 因此这个文件有2个分片。
  3. 多分片文件读取

    ​ 数据文件被分了多个分片,那么我们不能保证分片是正好按照行分开的,极大的可能性是一行的数据被分到了两个分片中。因此,我们在进行多个分片的数据读取的时候:

    - 第一个分片读到末尾再多读一行
    - 既不是第一个分片也不是最后一个分片第一行数据舍弃,末尾多读一行
    - 最后一个分片舍弃第一行,末尾多读一行
    复制代码

运行流程之MapTask

1. maptask调用FileInputFormat的getRecordReader读取分片数据
2. 每行数据读取一次,返回一个(K,V)对,K是offset,V是一行数据
3. 将k-v对交给MapTask处理
4. 每对k-v调用一次map(K,V,context)方法,然后context.write(k,v)
5. 写出的数据交给收集器OutputCollector.collector()处理
6. 将数据写入环形缓冲区,并记录写入的起始偏移量,终止偏移量,环形缓冲区默认大小100M
7. 默认写到80%的时候要溢写到磁盘,溢写磁盘的过程中数据继续写入剩余20%
8. 溢写磁盘之前要先进行分区然后分区内进行排序
9. 默认的分区规则是hashpatitioner,即key的hash%reduceNum
10. 默认的排序规则是key的字典顺序,使用的是快速排序
11. 溢写会形成多个文件,在maptask读取完一个分片数据后,先将环形缓冲区数据刷写到磁盘
12. 将数据多个溢写文件进行合并,分区内排序(外部排序 => 归并排序)
复制代码

​ MapTask的并行度决定map阶段的任务处理并发度,进而影响到整个job的处理速度.那么,MapTask并行实例是否越多越好呢?其并行度又是如何决定呢?

1. 如果硬件配置为2*12core + 64G,恰当的map并行度是大约每个节点20-100个map,最好每个map的执行时间至少一分钟。2. 如果job的每个map或者 reduce task的运行时间都只有30-40秒钟,那么就减少该job的map或者reduce数,每一个task(map|reduce)的setup和加入到调度器中进行调度,这个中间的过程可能都要花费几秒钟,所以如果每个task都非常快就跑完了,就会在task的开始和结束的时候浪费太多的时间。3. 配置task的JVM重用可以改善该问题:(mapred.job.reuse.jvm.num.tasks,默认是1,表示一个JVM上最多可以顺序执行的task数目(属于同一个Job)是1。也就是说一个task启一个JVM)4. 如果input的文件非常的大,比如1TB,可以考虑将hdfs上的每个block size设大,比如设成256MB或者512MB
复制代码

运行流程之ReduceTask

1. 数据按照分区规则发送到reducetask
2. reducetask将来自多个maptask的数据进行合并,排序(外部排序===》归并排序)
3. 按照key相同分组()
4. 一组数据调用一次reduce(k,iterable<v>values,context)
5. 处理后的数据交由reducetask
6. reducetask调用FileOutputFormat组件
7. FileOutputFormat组件中的write方法将数据写出
复制代码

Reduce Task的并行度同样影响整个job的执行并发度和执行效率,但与Map Task的并发数由切片数决定不同,Reduc Task数量的决定是可以直接手动设置:默认值是1,手动设置为4

设置方法:job.setNumReduceTasks(4);
复制代码

如果数据分布不均匀,就有可能在reduce阶段产生数据倾斜

注意: Reduce Task数量并不是任意设置,还要考虑业务逻辑需求,有些情况下,需要计算全局汇总结果,就只能有1个Reduce Task。尽量不要运行太多的Reduce Task。对大多数job来说,最好reduce的个数最多和集群中的reduce持平,或者比集群的 reduce slots小。这个对于小集群而言,尤其重要。

 

相关文章:

全方位揭秘!大数据从0到1的完美落地之运行流程和分片机制

一个完整的MapReduce程序在分布式运行时有三类实例进程&#xff1a; MRAppMaster: 负责整个程序的过程调度及状态协调MapTask: 负责Map阶段的整个数据处理流程ReduceTask: 负责Reduce阶段的整个数据处理流程 当一个作业提交后(mr程序启动)&#xff0c;大概流程如下&#xff1…...

后端程序员的前端必备【Vue】 - 07 ES6新语法

ES6新语法 1 let定义变量2 const定义常量3 模板字符串4 方法默认值5 箭头函数6 解构6.1 对象解构6.2 数组解构6.2 使用解构实现变量交换 7 Spread Operator8 模块化编程 1 let定义变量 使用let定义变量能更加精准的确定变量的作用域 //for(var i 0 ; i < 10 ; i){} for(let…...

AI落地:程序员如何用AI?

对于程序员来说&#xff0c;真正能提高效率、可落地的AI应用场景都有哪些&#xff1f; 目前已经能切实落地&#xff0c;融入我日常工作生活的有以下几个场景&#xff1a; 开发工作&#xff1a;自然语言生成代码&#xff0c;自动补全代码 日常工作学习&#xff1a;写作、翻译、…...

掌握优化+创新模式,轻松提升APP广告eCPM

​无论是市场占有率高的综合性应用程序(App)&#xff0c;还是透过特定目的所设计的专业化应用程序(App)&#xff0c;内部嵌入广告已成为其主要的盈利方式。 而优化和创新作为提升广告收益的两大关键词。通过不断的数据分析和优化&#xff0c;结合对用户需求的深刻理解去优化和…...

在docker上安装运行Python文件

目录 一、在docker中安装python 1.1 输入镜像拉取命令 1.2 查看镜像 1.3 运行 1.4 查看是否成功 1.5 查看python版本 二、运行py文件 2.1准备运行所需文件 2.2 准备文件夹 2.3 大概是这幅模样 2.4 打包上传到服务器上 2.5 构建镜像示例 2.6 查看镜像 2.7 优化镜像的…...

RocketMQ第三节(生产者和消费者)

目录 1&#xff1a;生产者&#xff08;同步、异步、单向&#xff09; 1.1&#xff1a;同步发送消息&#xff08;每发送一条等待mq返回值&#xff09; 1.2&#xff1a;异步发送消息 1.3&#xff1a;单向发送消息&#xff08;不管成功失败&#xff0c;只管发送消息&#xff09…...

人大金仓亮相国际金融展,打造“金融+产业+生态”创新模式

4月27日&#xff0c;以“荟萃金融科技成果&#xff0c;展现数字金融力量&#xff0c;谱写金融服务中国式现代化新篇章”为主题的2023中国国际金融展圆满落幕。作为已经举办30年的行业盛会&#xff0c;人大金仓再一次重磅亮相&#xff0c;全方位展示国产数据库前沿应用和创新服务…...

Syslog-ng RHEL 的安装和配置

syslog-ng 作为 syslog 的替代工具&#xff0c;可以完全替代 syslog 的服务&#xff0c;并且通过定义规则&#xff0c;实现更好的过滤功能。 作为运维来说一个好的日志工具比什么都重要。 通常我们会管理不同的服务器&#xff0c;因此我们需要把日志集中一下以便于快速查找。…...

得物直播低延迟探索 | 得物技术

1.背景 直播的时效性保证了良好的用户体验&#xff0c;根据经验在交易环节&#xff0c;延迟越低转化效果也会越好。传统的直播延迟问题已经成为了一个不容忽视的问题&#xff0c;高延迟不仅破坏了用户的观看体验&#xff0c;也让主播难以实时获取到用户的反馈。为了进一步优化…...

【CVPR红外小目标检测】红外小目标检测中的非对称上下文调制(ACM)

论文题目&#xff1a; Asymmetric Contextual Modulation for Infrared Small Target Detection 红外小目标检测中的非对称上下文调制 红外小目标数据集 目标个数分布&#xff1a;约90%图片中只有一个目标&#xff0c;约10%图片有多个目标&#xff08;在稀疏/显著的方法中&am…...

Axios概述

一、Json-server 获得零编码的完整伪造 REST API zero coding 在不到 30 秒的时间内 &#xff08;认真&#xff09;。 使用 <3 创建&#xff0c;适用于需要快速后端进行原型设计和模拟的前端开发人员&#xff0c;模拟后端发送过来json数据。 1.安装 npm install -g jso…...

用右雅克比对旋转矩阵进行求导

考虑一个向量 a \bold{a} a对其进行旋转, 旋转用旋转矩阵 R \bold{R} R表示, 用朴素的倒数定义进行求导而不是用扰动模型, 我得到了这个过程与结果 和高博的新书结果 − R J r a ∧ -\bold{R}\bold{J}_{r}\bold{a}^{\wedge} −RJr​a∧结果不一样, 雅克比矩阵位置不同, 是不是…...

高性能HMI 走向扁平化

个人计算机作为图形用户界面&#xff08;GUI&#xff09;在自动化中已经使用了30多年。在那段时间里&#xff0c;从技术、术语、功能到用于创建接口的标准和指南&#xff0c;发生了许多变化。 PC 技术的飞速发展&#xff0c;特别是图形显示&#xff0c;用户界面的技术发展导致了…...

虚幻引擎配置物体水面浮力的简便方法

虚幻引擎配置物体水面浮力的简便方法 目录 虚幻引擎配置物体水面浮力的简便方法前言前期工作配置水面浮力针对一个立方体的水面浮力配置针对船3D模型的水面浮力配置 小结 前言 在使用虚幻引擎配置导入的3D模型时&#xff0c;如何快速地将水面浮力配置正确&#xff0c;从而使得…...

WatchGuard 防火墙策略、配置和日志分析器

获取 Internet 活动见解并及时了解安全事件是一项具有挑战性的任务&#xff0c;因为安全设备会生成大量的安全和流量日志。Firewall Analyzer 针对 WatchGuard 防火墙设备的报告功能具有一系列功能&#xff0c;使您能够增强网络安全。WatchGuard 日志分析器软件&#xff0c;可让…...

Web自动化测试——XAPTH高级定位

XAPTH高级定位 一、xpath 基本概念二、xpath 使用场景三、xpath 相对定位的优点四、xpath 定位的调试方法五、xpath 基础语法&#xff08;包含关系&#xff09;六、xpath 顺序关系&#xff08;索引&#xff09;七、xpath 高级用法1、[last()]: 选取最后一个2、[属性名属性值 an…...

CentOS 7 安装 Nginx

前言 最近&#xff0c;在公司经常会进行项目的部署&#xff0c;但是服务器环境都是导师已经搭建好了的&#xff0c;我就是将项目文件放到特定目录。于是&#xff0c;周末在家就进行了 Nginx 的安装学习。之前&#xff0c;在 Windows 上使用过 Nginx&#xff0c;但是在 Linux 环…...

Databend 开源周报第 91 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 新数据类型&…...

【Ubuntu18.04使用yolov5教程】

欢迎大家阅读2345VOR的博客【Ubuntu18.04使用yolov5教程】&#x1f973;&#x1f973;&#x1f973;2345VOR鹏鹏主页&#xff1a; 已获得CSDN《嵌入式领域优质创作者》称号&#x1f47b;&#x1f47b;&#x1f47b;&#xff0c;座右铭&#xff1a;脚踏实地&#xff0c;仰望星空…...

CocoaPods如何发布新版本的Pod Library

当我们修改了一个Pod Library中的代码时&#xff0c;如何让依赖该库的项目能更新到最新代码&#xff0c;步骤如下&#xff1a; 假设现在修改了SamplePod&#xff08;Pod名称&#xff09;的代码&#xff0c;希望将最新版本更新到1.0.1&#xff0c;目前版本是1.0.0 修改SamplePo…...

v4l2框架

v4l2框架 文章目录 v4l2框架框架1.硬件相关层uvc_probeuvc_register_chainsuvc_register_termsuvc_register_video 2.核心层__video_register_device 3.虚拟视频驱动vivid分析入口vivid_init注册vivid平台驱动vivid_probevivid_create_instance 框架 1.硬件相关层 driver/medi…...

vue项目中生成LICENSE文件

vue项目中生成LICENSE文件 简介 LICENSE 文件是一个文本文件&#xff0c;它包含了你的项目所使用的开源软件的许可证信息。 在开发过程中&#xff0c;我们经常会使用到各种各样的第三方开源软件&#xff0c;这些软件是有版权和许可证的&#xff0c;我们在使用时需要遵循它们的…...

NewBing最新更新使用体验(无需等待人人可用)

NewBing最新更新使用体验 微软Bing爆炸级更新&#xff01;无需等待人人可用&#xff01; 今天&#xff0c;微软突然官宣全面开放BingChat&#xff1a; 无需任何等待。只需注册一个账户&#xff0c;首页即可体验。 NewBing最新更新新特性官方文档 https://www.microsoft.com/en-…...

欧拉奔赴品牌2.0时代,女性汽车真实用户需求被定义?

每年的上海国际汽车工业展览会&#xff0c;不仅是各大汽车品牌的技术“秀场”&#xff0c;也是品牌的营销“修罗场”。今年上海车展出圈的营销事件特别多&#xff0c;热度甚至一再蔓延到汽车行业外&#xff0c;其中欧拉也贡献了不少流量。 据了解&#xff0c;在2023上海车展欧…...

机器视觉工程师,听我一句劝,别去外包,干了三年,废了....对女人没了兴趣

​外包三年,干了就废,最后只会安装软件。 对于年轻人来说,需要工作,更需要生活。 对于年轻人来说,需要努力,更需要“面包”。 对于年轻人来说,需要规划,更需要发展。 对于外包,虽说废的不是很彻底,但那三年几乎是出差了三年、玩了三年、荒废了三年,那三年,技术…...

PBDB Data Service:Special parameters(特殊参数)

Special parameters&#xff08;特殊参数&#xff09; 描述参数1&#xff1a;下列参数在大部分请求中可用2&#xff1a;以下参数只与文本格式(.csv&#xff0c; .tsv&#xff0c; .txt)相关 描述 本文将介绍一组特殊参数&#xff0c;它们几乎可以在此数据服务的任何请求中使用…...

腾讯云轻量应用服务器使用限制说明(十大限制)

腾讯云轻量应用服务器和云服务器CVM相比具有一些限制&#xff0c;比如轻量服务器不支持更换内网IP地址&#xff0c;轻量服务器只能套餐整体升级且不支持降配&#xff0c;轻量不支持用户自定义配置私有网络VPC&#xff0c;还有如实例配额、云硬盘配额、备案限制和内网连通性等限…...

Python每日一练(20230507) 丑数I\II\III、超级丑数

目录 1. 丑数 Ugly Number I 2. 丑数 Ugly Number II 3. 丑数 Ugly Number III 4. 超级丑数 Super Ugly Number &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 丑数 Ugly Number I …...

K8S常见异常事件与解决方案

集群相关 Coredns容器或local-dns容器重启 集群中的coredns组件发生重启(重新创建)&#xff0c;一般是由于coredns组件压力较大导致oom&#xff0c;请检查业务是否异常&#xff0c;是否存在应用容器无法解析域名的异常。 如果是local-dns重启&#xff0c;说明local-dns的性能…...

测试5年从中兴 15K 跳槽去腾讯 32K+16,啃完这份笔记你也可以

粉丝小王转行做测试已经是第5个年头&#xff0c;一直是一个不温不火的小职员&#xff0c;本本分分做着自己的事情&#xff0c;觉得自己的工作已经遇到了瓶颈&#xff0c;一个偶然的机会&#xff0c;获得了一份软件测试全栈知识点学习笔记&#xff0c;通过几个月的学习&#xff…...

宁波网络公司网站建设项目/做seo需要投入的成本

linux 设备驱动之 8250 串口驱动------------------------------------------本文系本站原创,欢迎转载!转载请注明出处:http://ericxiao.cublog.cn/------------------------------------------一&#xff1a;前言前一段时间自己实践了一下8250芯片串口驱动的编写。今天就在此基…...

网站设计公司 宁波/百度经验app

点击上方“河北经济日报”加关注今天下午&#xff0c;在广东东莞举行的华为2019年开发者大会上&#xff0c;华为正式发布全新分布式操作系统&#xff1a;鸿蒙&#xff01;据介绍&#xff0c;鸿蒙是基于微内核的全场景分布式OS&#xff0c;可支撑各种不同的设备&#xff0c;包括…...

信息化建设网站范本/那种网站怎么搜关键词

第一问&#xff1a;当时第一感觉换不换没什么区别 第二问&#xff1a;经过分析验证以后发现&#xff0c;改变选择以后获得汽车的概率更大一些。 如果不改变选择&#xff0c;获得汽车的概率为1/3&#xff0c;这个比较容易证得。 如果改变选择&#xff0c;有三种情况&#xff1a;…...

专门做女性产品的网站/windows7优化大师官方下载

用eclipse 开发了一个applet 应用&#xff0c;部署到网页上面&#xff0c;运行时&#xff0c;总出现一个错误&#xff1a;Error:access denied ("java.net.SocketPermission" "192.168.0.50:5500" "connect,resolve")其实出现这个错误的一个重要…...

南宁网站建设怎么样/跨境电商平台排行榜前十名

/* reference http://nehe.gamedev.net/article/using_gluunproject/16013/ */#include <windows.h> // windows系统要加这个。因为下面2个头文件的一些宏是在这个文件中定义的 #include <gl/Gl.h> #include <gl/glut.h> //这两个头文件在OpenGL程序中…...

wordpress 修改语言包/广州优化疫情防控举措

Bootstrap框架的表单控件的禁用状态和普通的表单禁用状态实现方法是一样的&#xff0c;在相应的表单控件上添加属性“disabled”。 在使用了“form-control”的表单控件中&#xff0c;样式设置了禁用表单背景色为灰色&#xff0c;而且手型变成了不准输入的形状。如果控件中不使…...