hive(七) -- 拉链表、数据存储及优化配置

拉链表

数据同步问题

Hive在实际工作中主要用于构建离线数据仓库,定期的从各种数据源中同步采集数据到Hive中,经过分层转换提供数据应用。比如每天需要从MySQL中同步最新的订单信息、用户信息、店铺信息等到数据仓库中,进行订单分析、用户分析。
image

例如:MySQL中有一张用户表:tb_user,每个用户注册完成以后,就会在用户表中新增该用户的信息.

image

由于每天都会有用户注册,产生新的用户信息,那么每天都需要将MySQL中的用户数据同步到Hive数据仓库中.

假如在1号已经在hive中创建了表并拉取了数据,但是在2号时MySQL中新增2条用户注册数据,并且有1条用户数据发生更新.

image

那么我们需要对2号的数据进行同步到hive中,新增的数据会直接加载到Hive表中,但是更新的数据如何存储在Hive表中?

方案一:直接覆盖

使用2号的数据 直接将1号的数据覆盖掉
优点:实现最简单,使用起来最方便
缺点:没有历史状态 想查询008之前的数据查看不到

方案二:根据日期构建一份全量的快照表

1号创建一张表拉取所有数据
2号再创建一张表拉取所有数据 
... 每天都创建一张表
优点:记录了所有数据在不同时间的状态
缺点:冗余存储了很多没有发生变化的数据,导致存储的数据量过大

方案三:构建拉链表,通过时间标记发生变化的数据的每种状态的时间周期

image

拉链表的设计是将更新的数据进行状态记录,没有发生更新的数据不进行状态存储,用于存储所有数据在不同时间上的所有状态,通过时间进行标记每个状态的生命周期,查询时,根据需求可以获取指定时间范围状态的数据,默认用9999-12-31等最大值来表示最新状态。

4.2 拉链表实现原理

原理

image

  1. 增量采集变化数据,放入增量表中

image

  1. 将Hive中的拉链表与临时表的数据进行合并,合并结果写入临时表

  2. 将临时表的数据覆盖写入拉链表中

4.3 拉链表实现演示

创建拉链表

-- 数据准备
vi zipper.txt
001	186xxxx1234	laoda	0	sh	2021-01-01	9999-12-31
002	186xxxx1235	laoer	1	bj	2021-01-01	9999-12-31
003	186xxxx1236	laosan	0	sz	2021-01-01	9999-12-31
004	186xxxx1237	laosi	1	gz	2021-01-01	9999-12-31
005	186xxxx1238	laowu	0	sh	2021-01-01	9999-12-31
006	186xxxx1239	laoliu	1	bj	2021-01-01	9999-12-31
007	186xxxx1240	laoqi	0	sz	2021-01-01	9999-12-31
008	186xxxx1241	laoba	1	gz	2021-01-01	9999-12-31
009	186xxxx1242	laojiu	0	sh	2021-01-01	9999-12-31
010	186xxxx1243	laoshi	1	bj	2021-01-01	9999-12-31
--创建拉链表
create table dw_zipper
(
    userid    string,
    phone     string,
    nick      string,
    gender    int,
    addr      string,
    starttime string,
    endtime   string
) row format delimited fields terminated by '\t';
load data local inpath '/root/zipper.txt' into table dw_zipper;
select * from dw_zipper;

创建增量表

vi update.txt
008	186xxxx1241	laoba	1	sh	2021-01-02	9999-12-31
011	186xxxx1244	laoshi	1	jx	2021-01-02	9999-12-31
012	186xxxx1245	laoshi	0	zj	2021-01-02	9999-12-31
create table ods_update
(
    userid    string,
    phone     string,
    nick      string,
    gender    int,
    addr      string,
    starttime string,
    endtime   string
) row format delimited fields terminated by '\t';

load data local inpath '/root/update.txt' overwrite into table ods_update;

select * from ods_update;

创建临时表

create table tmp_zipper
(
    userid    string,
    phone     string,
    nick      string,
    gender    int,
    addr      string,
    starttime string,
    endtime   string
) row format delimited fields terminated by '\t';

合并数据到临时表

insert overwrite table tmp_zipper
select
    userid,
    phone,
    nick,
    gender,
    addr,
    starttime,
    endtime
from ods_update
union all
--查询原来拉链表的所有数据,并将这次需要更新的数据的endTime更改为更新值的startTime
select
    a.userid,
    a.phone,
    a.nick,
    a.gender,
    a.addr,
    a.starttime,
    --如果这条数据没有更新或者这条数据不是要更改的数据,就保留原来的值,否则就改为新数据的开始时间-1
    if(b.userid is null or a.endtime < '9999-12-31', a.endtime , date_sub(b.starttime,1)) as endtime
from dw_zipper a  left join ods_update b
                            on a.userid = b.userid ;

覆盖拉链表数据

insert overwrite table dw_zipper
select * from tmp_zipper;

数据存储

Hive数据存储的本质还是HDFS,所有的数据读写都基于HDFS的文件来实现,为了提高对HDFS文件读写的性能,Hive中提供了多种文件存储格式:TextFile、SequenceFile、ORC、Parquet等。不同的文件存储格式具有不同的存储特点,有的可以降低存储空间,有的可以提高查询性能等,可以用来实现不同场景下的数据存储,以提高对于数据文件的读写效率。

5.1 列式存储和行式存储

要理解行式存储和列式存储以及他们之间的差异首先就得理解两种存储方式在结构上的差异.

举个例子,如下表所示为一张学生的学科表:

image

行式存储

image

列式存储

image

写操作差异

从他们的结构上可以看出,行存储在写入时比列存储要快〈eg:如果是机械硬盘,行存储时磁头在磁盘上只需要顺序写入,而列存储需要频繁的移动定位到下一个字段需要写入的地址,造成了时间上的开销)﹔同时由于行存储下表的数据是放在一起的,一次写入,所以数据的完整性可以确定;

读数据差异

1.查询某一列数据

假设我们查询sid列 
	行存储查询时会将课程名和年级一起查询出来,这样会造成数据冗余,如果列数比较多,影响比较大.
	列存储是按照列来存储到一起的,每一列单独存放,查询起来方便很多,直接查询即可

2.查询所有数据

 行存储查询所有数据直接查询就可以了
 列存储,由于每列单独存放,先查询出来一列,然后在通过聚集运算,把列上每个数据拼接成行,没有行存储方便.

使用场景总结

image

5.2 主流文件格式特点

TextFile格式

TextFile是Hive中默认的文件格式,存储形式为按行存储。工作中最常见的数据文件格式就是TextFile文件,几乎所有的原始数据生成都是TextFile格式.
建表时不指定存储格式即为textfile,导入数据时把数据文件拷贝至hdfs不进行处理。
优点 
    1.最简单的数据格式,不需要经过处理,可以直接cat查看
    2.可以使用任意的分隔符进行分割
    3.便于和其他工具(Pig, grep, sed, awk)共享数据
    4.可以搭配Gzip、Bzip2、Snappy等压缩一起使用
缺点 
	1.耗费存储空间,I/O性能较低
	2.结合压缩时Hive不进行数据切分合并,不能进行并行操作,查询效率低
	3.按行存储,读取列的性能差
应用场景
	1.适合于小量数据的存储查询
	2.一般用于做第一层数据加载和测试使用

Parquet格式

Parquet是一种支持嵌套结构的列式存储文件格式.是一种支持嵌套数据模型对的列式存储系统,作为大数据系统中OLAP查询的优化方案,它已经被多种查询引擎原生支持,并且部分高性能引擎将其作为默认的文件存储格式。通过数据编码和压缩,以及映射下推和谓词下推功能,Parquet的性能也较之其它文件格式有所提升。
优点 
	1.更高效的压缩和编码可压缩、可分割,优化磁盘利用率和I/O
	2.可用于多种数据处理框架
缺点
	1.不支持update, insert, delete, ACID
应用场景
	1.适用于字段数非常多,无更新,只取部分列的查询

Orc格式

ORC(OptimizedRC File)文件格式也是一种Hadoop生态圈中的列式存储格式.它并不是一个单纯的列式存储格式,是首先根据行组分割整个表,在每一个行组内进行按列存储。.

image

Index Data
Index Data 包括每一列的最小值和最大值,以及每一列中的行位置。(也可以包含bit field or bloom filter ) 行索引项提供了偏移量,使您能够在解压缩块中查找正确的压缩块和字节。
注意,ORC索引仅用于选择stripes 和 row groups.
拥有相对频繁的行索引项可以在stripe 内跳过行,以便快速读取,尽管stripe 很大。默认情况下,可以跳过每10,000行。

Row Data
存的是具体的数据,先取部分行,然后对这些行按列进行存储。对每个列进行了编码,分成多个Stream来存储。

Stripe Footer
存的是各个Stream的类型,长度等信息。

File Footer
每个文件有一个File Footer,这里面存的是每个Stripe的行数,每个Column的数据类型信息等;

PostScript
每个文件的尾部是一个PostScript,这里面记录了整个文件的压缩类型以及FileFooter的长度信息等。

在读取文件时,会seek到文件尾部读PostScript,从里面解析到File Footer长度,再读FileFooter,从里面解析到各个Stripe信息,再读各个Stripe,即从后往前读。
优点
	1.列式存储,存储效率非常高
	2.可压缩,高效的列存取
	3.查询效率较高,支持索引
	4.支持各种复杂的数据类型
	5.支持矢量化查询
缺点
	1.加载时性能消耗较大
	2.需要通过text文件转化生成
	3.读取全量数据时性能较差
应用场景
	适用于Hive中大型的存储、查询

矢量化查询(了解)

Hive的默认查询执行引擎一次处理一行,而矢量化查询执行是一种Hive针对ORC文件操作的特性,目的是按照每批1024行读取数据,并且一次性对整个记录整合(而不是对单条记录)应用操作,提升了像过滤, 联合, 聚合等等操作的性能。
注意:要使用矢量化查询执行,就必须以ORC格式存储数据。
-- 开启矢量化查询
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;

5.3 主流文件格式对比

**TextFile **

create table test_textfile
(
    stime      string,
    userid     string,
    keyword    string,
    clickorder string,
    url        string
)row format delimited fields terminated by '\t';
load data local inpath '/root/sogou.txt' into table test_textfile;

select * from test_textfile limit 10;

desc formatted  test_textfile;

image

**ORC 列式存储 **

create table test_orc
(
    stime      string,
    userid     string,
    keyword    string,
    clickorder string,
    url        string
)
stored as ORC ;
-- 不能使用load加载数据 
insert into table test_orc select * from test_textfile ;

select * from test_orc limit 10;

image

parquet 列式存储

create table test_parquet
(
    stime      string,
    userid     string,
    keyword    string,
    clickorder string,
    url        string
)
    stored as parquet  ;
-- 不能使用load加载数据 
insert into table test_parquet select * from test_textfile ;

select * from test_parquet limit 10;

desc formatted test_parquet;

image

  • 文本文件是默认格式 行式存储 不压缩 效率最低 18.1M

  • ORC 列式存储 压缩比高 效率高 2.7M

  • parquet 列式存储 压缩比比ORC低 效率和ORC相当 , 兼容性比ORC好 13.1M

执行效率ORC和parquet格式类似 , 但是ORC的压缩比更好 ,parquet 兼容性好 ,

5.4 数据压缩(了解)

Hive底层运行MapReduce程序时,磁盘I/O操作、网络数据传输、shuffle和merge要花大量的时间,尤其是数据规模很大和工作负载密集的情况下。鉴于磁盘I/O和网络带宽是Hadoop的宝贵资源,数据压缩对于节省资源、最小化磁盘I/O和网络传输非常有帮助。Hive压缩实际上说的就是MapReduce的压缩。

image

压缩的优点
	减小文件存储所占空间
	加快文件传输效率,从而提高系统的处理速度
	降低IO读写的次数
压缩的缺点
	使用数据时需要先对文件解压,加重CPU负荷,压缩算法越复杂,解压时间越长

Hive中的压缩就是使用了Hadoop中的压缩实现的,所以Hadoop中支持的压缩在Hive中都可以直接使用。

image

要想在Hive中使用压缩,需要对MapReduce和Hive进行相应的配置

临时配置

--配置MapReduce开启输出压缩及配置压缩类型
--开启输出压缩
set mapreduce.output.fileoutputformat.compress=true;
--配置压缩类型为Snappy
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

--配置Hive开启中间结果压缩和输出压缩及配置压缩类型
-- 中间结果压缩
set hive.exec.compress.intermediate=true;
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
-- 输出结果压缩
set hive.exec.compress.output=true;

永久配置
将以上MapReduce的配置写入mapred-site.xml中,重启Hadoop
将以上Hive的配置写入hive-site.xml中,重启Hive

压缩测试

TextFile压缩

create table t_textfile_snappy
    stored as textfile
as select * from test_textfile;

Orc压缩

create table t_orc_snappy
    stored as orc tblproperties ("orc.compress"="SNAPPY")
as select * from test_textfile;

select * from t_orc_snappy limit 10;

Hive优化配置

Explain查询计划

explain命令可以帮助用户了解一条HQL语句在底层的实现过程。通俗来说就是Hive打算如何去做这件事。explain会解析HQL语句,将整个HQL语句的实现步骤、依赖关系、实现过程都会进行解析返回,可以了解一条HQL语句在底层是如何实现数据的查询及处理的过程,辅助用户对Hive进行优化。

官网:http://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain

explain  select * from test_textfile limit 10;

每个查询计划由以下几个部分组成

  • 抽象语法树(AST):Hive使用Antlr解析生成器,可以自动地将HQL生成为抽象语法树
  • Stage依赖关系:会列出运行查询划分的stage阶段以及之间的依赖关系
  • Stage内容:包含了每个stage非常重要的信息,比如运行时的operator和sort orders等具体的信息

image

explain  select stime,count(*) from test_textfile where stime > '00:00:00' group by  stime order by  stime limit  5;

image

image

Join优化

Hive Join的底层是通过MapReduce来实现的,Hive实现Join时,为了提高MapReduce的性能,提供了多种Join方案来实现;

例如适合小表Join大表的Map Join,大表Join大表的Reduce Join,以及大表Join的优化方案Bucket Join等。

Map Join

适用场景 : 小表join大表

原理

将小表的那份数据放到分布式缓存中,给每个MapTask的内存都放一份完整的数据,大的数据每个部分都可以与小数据的完整数据进行join,底层不需要经过shuffle,需要占用内存空间存放小的数据文件.

image

image

explain  select * from t_category left join t_product tp on t_category.cid = tp.cid;

使用

尽量使用Map Join来实现Join过程,Hive中默认自动开启了Map Join:
hive.auto.convert.join=true
-- 如果大小表连接时小表数据小于该值,则自动开启mapjoin优化
-- 2.0以前
hive.smalltable.filesize or hive.mapjoin.smalltable.filesize: 默认值是25m
-- 2.0以后
hive.auto.convert.join.noconditionaltask.size :默认值10m
和
hive.auto.convert.join.noconditionaltask: 默认值是true

Reduce Join

应用场景:适合于大表Join大表

原理:将两张表的数据在shuffle阶段利用shuffle的分组,将数据按照关联字段进行合并,必须经过shuffle,利用Shuffle过程中的分组来实现关联.

image

使用:Hive会自动判断是否满足Map Join,如果不满足Map Join,则自动执行Reduce Join

Bucket Join

应用场景:适合于大表Join大表

原理:将两张表按照相同的规则将数据划分,根据对应的规则的数据进行join,减少了比较次数,提高了性能

image

使用

使用Bucket Join
语法:clustered by colName
参数:set hive.optimize.bucketmapjoin = true;
要求:分桶字段 = Join字段 ,桶的个数相等或者成倍数
使用Sort Merge Bucket Join(SMB)
基于有序的数据Join
语法:clustered by colName sorted by (colName)
参数
set hive.optimize.bucketmapjoin = true;
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;
要求:分桶字段 = Join字段 = 排序字段 ,桶的个数相等或者成倍数

6.3 数据倾斜

分布式计算中最常见的,最容易遇到的问题就是数据倾斜;

现象:当提交运行一个程序时,这个程序的大多数的Task都已经运行结束了,只有某一个Task一直在运行,迟迟不能结束,导致整体的进度卡在99%或者100%,这时候就可以判定程序出现了数据倾斜的问题。

原因:数据分配不均衡

image

Group by、Count(distinct)造成数据倾斜

当程序中出现group by或者count(distinct)等分组聚合的场景时,如果数据本身是倾斜的,根据MapReduce的Hash分区规则,肯定会出现数据倾斜的现象。

根本原因是因为分区规则导致的,所以可以通过以下几种方案来解决group by导致的数据倾斜的问题

方案一:开启Map端聚合

hive.map.aggr=true;
通过减少shuffle数据量和Reducer阶段的执行时间,避免每个Task数据差异过大导致数据倾斜

需要注意:求平均值不能使用  combiner

方案二:数据倾斜时自动负载均衡

hive.groupby.skewindata=true;
开启该参数以后,当前程序会自动通过两个MapReduce来运行
第一个MapReduce自动进行随机分布到Reducer中,每个Reducer做部分聚合操作,输出结果
第二个MapReduce将上一步聚合的结果再按照业务(group by key)进行处理,保证相同的分布到一起,最终聚合得到结果

键随机数打散

Join造成数据倾斜

Join操作时,如果两张表比较大,无法实现Map Join,只能走Reduce Join,那么当关联字段中某一种值过多的时候依旧会导致数据倾斜的问题;

面对Join产生的数据倾斜,核心的思想是尽量避免Reduce Join的产生,优先使用Map Join来实现

但往往很多的Join场景不满足Map Join的需求,那么可以以下几种方案来解决Join产生的数据倾斜问题:

方案一:提前过滤,将大数据变成小数据,实现Map Join

select a.id,a.value1,b.value2 from table1
		a join (select b.* from table2 b where b.ds>='20181201' and b.ds<'20190101') c
        on (a.id=c.id)

方案二:使用Bucket Join

方案二:使用Bucket Join
如果使用方案一,过滤后的数据依旧是一张大表,那么最后的Join依旧是一个Reduce Join
这种场景下,可以将两张表的数据构建为桶表,实现Bucket Map Join,避免数据倾斜.

方案三:使用Skew Join

Skew Join是Hive中一种专门为了避免数据倾斜而设计的特殊的Join过程
这种Join的原理是将Map Join和Reduce Join进行合并,如果某个值出现了数据倾斜,就会将产生数据倾斜的数据单独使用Map Join来实现
其他没有产生数据倾斜的数据由Reduce Join来实现,这样就避免了Reduce Join中产生数据倾斜的问题
最终将Map Join的结果和Reduce Join的结果进行Union合并

hive.optimize.skewjoin = true,

原理
image

本文转载于网络 如有侵权请联系删除

相关文章

  • Java简易小题练手~

    今天给大家带来三道题,题目并不是很难,加上我们之前的语言基础和对Java的简单入门,我想这些题大家也能很简单的写出来。 To:题解不一定是最完美的,也欢迎大家在公众号后台和小编讨论。 1、使用for、while、do…while分别实现在n!,并在n=10的情况下测试建议编写三个独立的方法。To:这里小编是将三个用法分成了三个类,并用一个TestDemo类来分别调用这三个方法。总共四个类如下: Test1类方法:packageExperience1.Test; publicclassTest1{ publicvoidtest(intk){ inti=0,sum=0; while(i<=k){ sum=i*(i+1); i++; } System.out.println(sum); } }复制while方法Test2类方法: packageExperience1.Test; publicclassTest2{ publicvoidtets2(intk){ inti=0,sum=0; do{ sum=i*(i+1); i++; }while(i<=k); System.ou

  • windows权限维持大结局

    文章来源|MS08067红队攻防实战班作业本文作者:苏杰波、李布杰(红队攻防实战班2期学员) 1.通过组策略运行指定脚本添加隐藏用户2.在注册表中添加启动自动运行后门下图所示为注册表中启动自动运行的目标目录:通过regadd"HKEY_CURRENT_USER\software\microsoft\windows\CurrentVersion\Run"/vmyPersist/treg_sz/d"C:\Users\Administrator\Desktop\persist.exe"命令,可将启动自动运行的程序添加到注册表中的相应项:3.通过计划任务添加后门添加计划任务,每隔1分钟执行一次:4.services.mscWindows权限维持隐藏技巧"真正"的隐藏文件命令:Attrib+s+a+h+r[文件]+s:系统+h:隐藏+r:只读加上s属性后,文件会进一步被隐藏(打开查看隐藏文件都看不见),只有使用dir-h(ls-h)等才能看见。当文件被加上s属性后,后续操作可能没有足够的权限取操作,需要先去掉s属性才能进行后续的操作。改

  • Pandas学习笔记03-数据清洗(通过索引选择数据)

    今天我们就在jupyterlab里进行操作演示,本次推文内容主要以截图为主了。 有兴趣的可以公众号回复"索引"获取演示原数据及ipynb文件。 数据清洗中,我们经常需要从原始数据中通行列索引规则选择需要用于后续处理分析的数据,这便是本次的主要内容。 数据清洗(通过索引选择数据)1.索引设置我们在使用pandas读取文件数据时,可以设定初始的索引。 这里我用之前爬取过的拉勾网产品经理岗位数据进行演示如下: 读取数据时指定索引1.1.reindexreindex方法可以重新进行索引排序,如果某个索引值之前不存在则会引入缺失值。 reindex重新进行索引排序1.2.set_indexset_index就是将某列设置为索引 set_index设置索引列1.3.reset_indexreset_index就是重置索引(变为默认的索引0到len()-1),比如可以把上面set_index设置的索引取消,,经常用在对数据进行处理(分组或透视处理)后 reset_index重置索引1.4.renamerename可以将行列索引标签名进行替换,用字典的形式 在这里插入图片描述2.索

  • 把字符串转换成整数(java) 剑指offer

    参考链接:Java中整数到字符串转换的不同方法将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。数值为0或者字符串不是一个合法的数值则返回0. packageTree;publicclassstrToInt{  //边界条件判断条件  //数据上下溢出空字符串只有正负号,错误标志输出;   publicintStringToInt(Stringstr){     //if(str.equals("")||str.length()==0)    if(str==null||str.length()==0){       return0;     }     intfuhao=0;     //     charchars[]=str.toCharArray();     if(chars[0]=='-')fuhao=1;     intsum=0;     for(inti=fuhao;i<chars.length;i++){  

  • CIFAR-10/CIFAR-100数据集解析

    CIFAR-10数据集CIFAR-10数据集由10个类的60000个32x32彩色图像组成,每个类有6000个图像。有50000个训练图像和10000个测试图像。 数据集分为五个训练批次和一个测试批次,每个批次有10000个图像。测试批次包含来自每个类别的恰好1000个随机选择的图像。训练批次以随机顺序包含剩余图像,但一些训练批次可能包含来自一个类别的图像比另一个更多。总体来说,五个训练集之和包含来自每个类的正好5000张图像。 以下是数据集中的类,以及来自每个类的10个随机图像: 这些类完全相互排斥。汽车和卡车之间没有重叠。“汽车”包括轿车,SUV,这类东西。“卡车”只包括大卡车。都不包括皮卡车。 airplane/automobile/bird/cat/deer/dog/frog/horse/ship/truckCIFAR-10下载CIFAR-10python版本 CIFAR-10Matlab版本 CIFAR-10二进制版本(适用于C程序)数据集布局Python/Matlab版本我将描述数据集的Python版本的布局。Matlab版本的布局是相同的。 该存档包含文件data_bat

  • 数据结构与算法-二维数组中的查找

    题目:二维数组中的查找在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true;如果查找数字5,由于数组不含有该数字,则返回false。 解决思路用具体的问题入手本题以7为查找对象,其步骤如下: 先取右上角的数字9,由于9大于要查找的7,故7肯定不在此列,删除此列,如(a)所示;再取新的数字8,同理8大于7,不在此列,删去,此时只剩下两列,如(b)所示。在剩余的两列中,右上角的2比7小,故7应该在2的下方,删除此行,如(c)所示;再取新的右上角的数4,同理,7只可能在4的下方,故删除此行。如(d)所示; 在剩余的两行两列中,再取右上角的数7,此时和查找的数相同,结束,如不相同,则继续。可以选取右上角或者左下角作为初始值,但是不能选择左上角和右下角,因为我们没办法是拿出某一行或者某一列,这样就不能缩小范围代码实现测试用例:要查找的数在数组中要查找的数字不在数组中(大于数组中所有的值,小于数组中

  • TypeScript枚举

    枚举(Enum)类型用于取值被限定在一定范围内的场景定义一个枚举如下所示enumDays{ Sun, Mon, Tue, Wed, Thu, Fri, Sat }复制console.log(Days.Sun) console.log(Days.Sat)复制执行如上代码我们可以看到控制台会输出0 6复制打开js文件我们可以看到相对应的字符串,通过如下内容我们可以看到枚举类型可以被编译成一个双向类型的映射console.log(Days[0])复制通过如上代码我们可以打印出”Sun“同样我们也可以给定一个数字常量enumDays{ Sun=3, Mon, Tue, Wed, Thu, Fri, Sat }复制通过上述代码那我们后面的累加也变了,是从3开始一直到9进行累加

  • 快速学习-Zookeeper入门

    第1章Zookeeper入门1.1概述Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目。 1.2特点1.3数据结构1.4应用场景提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。统一命名服务统一配置管理统一集群管理服务器动态上下线软负载均衡1.5下载地址1.官网首页:https://zookeeper.apache.org/复制2.下载截图,如图5-5,5-6,5-7所示

  • 【机器学习】隐马尔可夫模型

    本文介绍了隐马尔可夫模型,首先介绍了隐马尔科夫模型定义,核心思想是引入了隐状态序列(引入隐状态是所有隐因子模型最巧妙的地方,如:隐因子分解,LDA),然后介绍了隐马尔科夫模型要解决的三个问题,1)在参数已知的情况下计算可观测序列的总概率,2)在给出观测序列数据时学习模型的参数,3)在参数已知的情况下通过维特比解码预测出所有产生可观测序列中概率最大的一条不可观测序列,即序列标注问题。作者|文杰编辑|yuquanle隐马尔可夫模型A、隐马尔科夫模型定义隐马尔科夫模型是一种时序的概率模型,描述由一个隐的马尔科夫链随机生成的不可观察的隐状态序列,在每一个隐状态下随机产生观察值构成一个可观测的随机序列。其中关键是状态序列是满足马尔科夫性质的,且可观测序列是由隐藏的状态序列以一定的概率随机生成。在自然语言中文分词中,由于自然语言是有明显的上下文关系的,即当前字与其前后出现的字都是有关系的。为了表示前一个字对当前字的影响,我们用一个隐状态来表示前的语义状态,用在前一个状态下转移到发射出当前字的隐状态的概率表示前一个字对当前字的影响。整个来说就是把上下文字对字的影响转化成状态对状态的影响。而用发射概率

  • 深度学习不work?这有一份超全的Debug检查清单

    前言:本笔记是对近日阅读keynote“TroubleshootingDeepNeuralNetworks”的总结。 keynote来源: http://josh-tobin.com/troubleshooting-deep-neural-networks为什么需要论DLTroubleshooting?80%-90%时间用于debug和tune,10%-20%时间用于推导数学或者实现。 模型为什么会表现糟糕?实现时的bug,很多深度学习bug不可见,比如模型label顺序错误超参数选择,因为模型对超参数比较敏感数据/模型拟合数据集创建,常见问题如下:没有足够数据类别不平衡噪声标签训练和测试的分布不同 DLTroubleshooting策略 Startsimple:尽可能使用最简单的模型和数据,比如在数据的一个子集上使用LeNet选择简单结构使用sensible配置对输入归一化简化问题使用更小的训练数据使用更小的图像尺寸创建一个更简单的合成训练集 Implement&debug:使得模型在一个batch上过拟合或者复现已知结果最常见的5种深度学习bug:Getyourmodelt

  • 前端项目如何管理

    前端项目的管理分为两个维度:项目内的管理与多项目之间的管理。1.项目内的管理在一个项目内,当有多个开发者一起协作开发时,或者功能越来越多、项目越来越庞大时,保证项目井然有序的进行是相当重要的。一般会从下面几点来考证一个项目是否管理得很好:可扩展性:能够很方便、清晰的扩展一个页面、组件、模块组件化:多个页面之间共用的大块代码可以独立成组件,多个页面、组件之间共用的小块代码可以独立成公共模块可阅读性:阅读性良好(包括目录文件结构、代码结构),能够很快捷的找到某个页面、组件的文件,也能快捷的看出项目有哪些页面、组件可移植性:能够轻松的对项目架构进行升级,或移植某些页面、组件、模块到其他项目可重构性:对某个页面、组件、模块进行重构时,能够保证在重构之后功能不会改变、不会产生新bug开发友好:开发者在开发某一个功能时,能够有比较好的体验(不好的体验比如:多个文件相隔很远)协作性:多人协作时,很少产生代码冲突、文件覆盖等问题可交接性:当有人要离开项目时,交接给其他人是很方便的1.1可扩展性对于前端项目而言,可扩展性是并不难的,因为很多时候前端的代码、文件分块都是按照页面来的,所以天然就是一块一块的

  • 面试题9(包含抽象方法的一定是抽象类吗)

    编译并运行下面代码: classBase{abstractpublicvoidmyfunc();publicvoidanother(){System.out.println("Anothermethod!");}publicstaticclassCodeextendsBase{publicstaticvoidmain(String[]args)throwsException{Codecode=newCode();code.another();}publicvoidmyfunc(){System.out.println("myfunc");}publicvoidametgod(){myfunc();}}}请选择描述正确的项。 (a)程序正确编译并运行,输出“myfunc” (b)编译错误,提示类Base必须声明为abstract (c)编译正常,但是在运行时提示Base类没有定义abstract方法 (d)编译错误,因为Base类的myfunc()后面缺少{} 考点:该面试题考察求职者对Java修饰符的掌握。 出现频率:★★★★ 【面试题解析】面试

  • 直播+:欢愉与规制

    杨阳 腾讯公司高级法律顾问徐凯 西南政法大学经济法硕士研究 2016年直播行业爆发,各类直播APP席卷各大内容领域,甚至一些传统行业也纷纷拥抱“直播+”,直播正在成为标配。在互联网特别是移动互联网爆发式发展的过程中,视频直播这个新的风口来的迅猛,却也是必然。 在直播1.0时代,阵地主要在PC端,直播内容主要集中在唱歌、跳舞、聊天等草根主播的个人才艺展示上。自2005年专注于陌生人视频社交的9158异军突起,到YY从语音软件进军秀场直播领域,经过多年发展最终形成“六间房+YY+9158”为代表的直播格局,自六间房首倡“秀场直播”概念至PC秀场直播发展成熟并最终形成了签约直播模式和虚拟打赏的盈利体系。 2014年,虎牙直播成立,斗鱼亦于同年独立,以游戏直播为主要内容的直播2.0时代正式开启,以YY、虎牙和斗鱼为代表的直播平台通过游戏直播进一步增强了用户的粘性。得益于国内游戏市场规模的快速扩张,电竞产业赛事频繁,游戏直播开辟了传统秀场以外的第二个独立战场。但至此直播阵地仍主要囿于PC端,其蛮荒之力尚未完全释放。 智能手机的普及、带宽成本和流量价格的下降为2016年“直播+”的爆发扫除了最后障

  • 物联网产品设计中的设备升级功能

    物联网产品设计中的设备升级功能 目录物联网产品设计中的设备升级功能一、背景二、固件升级对设备的重要性三、远程固件升级整体框架图四、TFTP变种协议及远程固件升级流程1.TFTP协议1.1协议简介1.2传输模式1.3协议格式1.4TFTP通信流程1.5TFTP协议的缺陷1.6TFTP客户端/服务器设计注意事项2.远程固件升级流程五、IBMS端程序设计流程图1.webApi程序设计2.升级消息通知定时任务程序设计2.1Redis消息结构2.2平台与设备之间的Modbus定制升级命令及其响应格式3.升级日志回写Mysql定时任务程序设计六、几个重要模型1.UpgradeCluster2.UpgradeTask3.UpgradeResult4.升级设备表七、升级功能测试八、网页原型图设计1.集群管理1.1在设备基础上点选或者多选添加集群1.2根据硬件版本或者软件版本或者区域编码(区域中文名称)来创建集群2.升级任务管理2.1上传升级文件2.2选择升级集群2.3选择升级时间段2.4输入升级策略2.5输入管理员密码以确认升级任务2.6确认之后的升级任务3.升级日志管理 一、背景 在迅速变化和发展的

  • [Cocos2d-x For WP8]Progress 进度条

       Cocos2d-x可以有多种进度条的展示方式,进度条的种类是根据进度条运动的方向来区分,包括顺时针,逆时针,从左到右,从右到左,从下到上和从上到下6种方式,这和WP8的进度条是由很大的区别的。那么Cocos2d-x的进度条是需要用图片来进行展示,然后从不同的方向来渐渐把图片显示出来实现进度条的效果。    第一步需要创建一个CCProgressTo对象和CCProgressTimer对象,我们可以通过CCProgressTo::create(2,100)方法创建CCProgressTo定义了进度条的时间和图片的百分比,第一个参数是时间是一个CCTime对象,第二个参数是结果显示图片的百分比。通过CCProgressTimer::progressWithFile("cat.png")方法创建CCProgressTimer定义了进度条的图片文件。   CCProgressTo*to1=CCProgressTo::create(2,100);  CCProgressTimer*left=

  • leetcode.86. 分隔链表

    给你一个链表的头节点head和一个特定值x,请你对链表进行分隔,使得所有小于x的节点都出现在大于或等于x的节点之前。 你应当保留两个分区中每个节点的初始相对位置。   示例1:     输入:head=[1,4,3,2,5,2],x=3输出:[1,2,2,4,3,5]示例2: 输入:head=[2,1],x=2输出:[1,2]  提示: 链表中节点的数目在范围[0,200]内-100<=Node.val<=100-200<=x<=200 来源:力扣(LeetCode)链接:https://leetcode.cn/problems/partition-list著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。         /**  * Definition for singly-linked list.  * public class ListNode { &

  • 【起航计划ObjC 002】印第安老斑鸠ObjC的幻想 ---- Ubuntu下安装并使用MAC虚拟机

    本文介绍如何在Ubuntu下安装MacOSXMavericks系统。具体如下: 1)安装前准备工作 下载MacOSXMavericks系统,地址:http://pan.baidu.com/s/1dDDzXbb 。 需要下载的文件有:HackBoot_Mav.iso、OSXMavericks2.part1.rar、OSXMavericks2.part2.rar、OSXMavericks2.part3.rar。然后将压缩包解压备用。解压后的结果如下: 然后还需要下载去Virtualbox官网下载:Virtualbox、Oracle_VM_VirtualBox_Extension_Pack-4.3.14-95030.vbox-extpack。地址:https://www.virtualbox.org/wiki/Downloads 找linux系统中对应的发行版,对应的系统位数(32位或64位)的安装包下载安装即可。比如下载了virtualbox-4.3_4.3.14-95030~Ubuntu~raring_amd64.deb文件包。可以使用如下命令安装: $ sudo

  • centos 7——LNMP环境编译安装zabbix-5.0.8

    服务器环境 服务器IP 安装软件 10.0.0.20 zabbix-server、Nginx-1.22、PHP-7.3.29 10.0.0.21 zabbix-agent 10.0.0.22 zabbix-agent 10.0.0.23 MySQL   二进制安装mysql8.0 获取软件包 #wgethttps://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz复制 安装依赖 #yuminstall-ylibaio复制 卸载mariadb的库 #yumremove-ymariadb-libs复制 解压并创建数据目录 #tar-xfmysql-8.0.20-linux-glibc2.12-x86_64.tar.xz-C/usr/local/ #mv/usr/local/mysql-8.0.20-linux-glibc2.12-x86_64//usr/local/mysql8.0 #mkdir/data/mysql8.0

  • JMeter多接口顺序执行方法——添加逻辑控制器Critical Section Controller

    最近公司项目需要做压力测试,所以初步研究了一下JMeter的使用。 项目要求对单接口进行并发操作,但是由于该接口需要先获取token等其他值后,才能够正常执行。所以会存在一个测试计划下,有多个http请求,我原以为jmeter会按照我调整的次序顺序执行,后面脚本完成以后多并发执行,开发告诉我部分接口调用的数据有误,我才反应过来jmeter同一个测试计划下的所有接口,都是同时并发执行的,如果需要顺序执行,需要添加一个逻辑控制器,也就是CriticalSectionController 这个是通过右键点击线程组,依次选择Add-LogicController-CriticalSectionController,而后将你需要顺序执行的多个接口按照你想要的次序,放到这个控制器下,重新执行后,查看“察看结果树”就可以发现这个时候执行的次序就是你排列的顺序。 但是这个有一个情况,就是我这个控制器下,一共放了三个http请求,多并发,但是执行完毕后,察看结果树列表展示,第1个请求会在所有线程依次执行完以后继续重复执行;查看聚合报告,发现第一个请求的样本数总是与第2、3个不一致,而第2、3个请求的样

  • for循环控制

    for(循环变量初始化;循环判断条件;循环变量迭代){循环操作} 1、循环判断条件是返回一个布尔值的表达式 2、循环变量的初始化和变量迭代可以写到其他地方,但是两边的分号不能省略 3、循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开  

  • 遍历技巧

    遍历技巧 在字典中遍历时,关键字和对应的值可以使用items()方法同时解读出来: >>> knights = {'gallahad': 'thepure', 'robin': 'thebrave'}>>> for k, v in knights.items():...   print(k, v)...gallahad thepurerobinthebrave 在序列中遍历时,索引位置和对应值可以使用enumerate()函数同时得到: >>> for i, v in enumerate(['tic', 'tac', 'toe']):...   print(i, v)...0 tic1 tac2 toe 同时遍历两个或更多的序

相关推荐

推荐阅读