Hive

Hive

概览

Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。

本质是将SQL转换为MapReduce程序。

主要用途:用来做离线数据分析,比直接用MapReduce开发效率更高。

架构

Hive架构

数据模型

**db:**在hdfs中表现为hive.metastore.warehouse.dir目录下一个文件夹

**table:**在hdfs中表现所属db目录下一个文件夹

**external table:**数据存放位置可以在HDFS任意指定路径

**partition:**在hdfs中表现为table目录下的子目录

**bucket:**在hdfs中表现为同一个表目录下根据hash散列之后的多个文件

保存元数据

内嵌式元存储服务器、本地元存储服务器、远程元存储服务器

Hive和RDBMS有什么异同

Hive 更适合数据仓库的统计分析。

Hive不支持实时查询。

SQLHiveQL
事务支持不完全支持
模式写模式读模式
数据保存块设备、本地文件系统HDFS
延时
数据规模
视图UpdatabaleRead-only

两张表关联的MapReduce过程

  • 如果其中有一张表为小表

    直接使用map端join的方式(map端加载小表)进行聚合。

  • 如果两张都是大表

    那么采用联合key,联合key的第一个组成部分是join on中的公共字段,第二部分是一个flag,0代表表A,1代表表B,由此让Reduce区分客户信息和订单信息;在Mapper中同时处理两张表的信息,将join on公共字段相同的数据划分到同一个分区中,进而传递到一个Reduce中,然后在Reduce中实现聚合。

常用操作

数据库相关

Hive配置单元包含一个名为 default 默认的数据库.

  • 创建数据库
create database [if not exists] <database name>;
  • 显示所有数据库
show databases;  
  • 删除数据库
drop database if exists <database name> [restrict|cascade]; 

默认情况下,hive不允许删除含有表的数据库,要先将数据库中的表清空才能drop,否则会报错

加入cascade关键字,可以强制删除一个数据库

drop database if exists users cascade;
  • 切换数据库
use <database name>; 

内部表外部表

--建内部表
create table 
student(Sno int,Sname string,Sex string,Sage int,Sdept string) 
row format delimited fields terminated by ',';
--建外部表
create external table 
student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) 
row format delimited fields terminated by ',' location '/stu';
--内部表加载数据
load data local inpath '/root/hivedata/students.txt' overwrite into table student;
--外部表加载数据
load data inpath '/stu' into table student_ext;

分区表

建表

分区建表分为2种:
一种是单分区,也就是说在表文件夹目录下只有一级文件夹目录。
另外一种是多分区,表文件夹下出现多文件夹嵌套模式。

--单分区建表语句
create table day_table (id int, content string) partitioned by (dt string);
--单分区表,按天分区,在表结构中存在id,content,dt三列。

--双分区建表语句
create table day_hour_table (id int, content string) partitioned by (dt string, hour string);
--双分区表,按天和小时分区,在表结构中新增加了dt和hour两列。

--单分区表导入数据
load data local inpath '/root/hivedata/dat_table.txt' into table day_table partition(dt='2017-07-07');

--双分区表导入数据
load data local inpath '/root/hivedata/dat_table.txt' into table day_hour_table partition(dt='2017-07-07', hour='08');
 
--基于分区的查询:
SELECT day_table.* FROM day_table WHERE day_table.dt = '2017-07-07';

--查看分区
show partitions day_hour_table;  

--总的说来partition就是辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的规格和条件进行管理。

指定分隔符

--指定分隔符创建分区表
create table day_table (id int, content string) partitioned by (dt string) row format delimited fields terminated by ',';

--复杂类型的数据表指定分隔符
--数据如下:
--zhangsan	beijing,shanghai,tianjin,hangzhou
--wangwu	shanghai,chengdu,wuhan,haerbin
--建表语句
create table
complex_array(name string,work_locations array<string>) 
row format delimited fields terminated by '\t' 
collection items terminated by ',';

增加分区

alter table t_partition add partition (dt='2008-08-08') location 'hdfs://node-21:9000/t_parti/';

--执行添加分区  /t_parti文件夹下的数据不会被移动。并且没有分区目录dt=2008-08-08 

删除分区

alter table t_partition drop partition (dt='2008-08-08');

--执行删除分区时/t_parti下的数据会被删除并且连同/t_parti文件夹也会被删除
--注意区别于load data时候添加分区:会移动数据 会创建分区目录

join

--准备数据
--1,a
--2,b
--3,c
--4,d
--7,y
--8,u

--2,bb
--3,cc
--7,yy
--9,pp



--建表:
create table a(id int,name string)
row format delimited fields terminated by ',';

create table b(id int,name string)
row format delimited fields terminated by ',';

--导入数据:
load data local inpath '/root/hivedata/a.txt' into table a;
load data local inpath '/root/hivedata/b.txt' into table b;


--实验:
--inner join
select * from a inner join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 7     | y       | 7     | yy      |
+-------+---------+-------+---------+--+





--left join   
select * from a left join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 1     | a       | NULL  | NULL    |
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 4     | d       | NULL  | NULL    |
| 7     | y       | 7     | yy      |
| 8     | u       | NULL  | NULL    |
+-------+---------+-------+---------+--+





--right join
select * from a right join b on a.id=b.id;
select * from b right join a on b.id=a.id;
+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 7     | y       | 7     | yy      |
| NULL  | NULL    | 9     | pp      |
+-------+---------+-------+---------+--+




--outer join
select * from a full outer join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 1     | a       | NULL  | NULL    |
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 4     | d       | NULL  | NULL    |
| 7     | y       | 7     | yy      |
| 8     | u       | NULL  | NULL    |
| NULL  | NULL    | 9     | pp      |
+-------+---------+-------+---------+--+


--hive中的特别join
select * from a left semi join b on a.id = b.id;
select a.* from a inner join b on a.id=b.id;
+-------+---------
| a.id  | a.name  
+-------+---------
| 2     | b       
| 3     | c       
| 7     | y       
+-------+---------
--相当于
select a.id,a.name from a where a.id in (select b.id from b); --在hive中效率极低
select a.id,a.name from a join b on (a.id = b.id);
select * from a inner join b on a.id=b.id;


--cross join(##慎用)
--返回两个表的笛卡尔积结果,不需要指定关联键。
select a.*,b.* from a cross join b;

by

Sort By:分区内有序

Order By:全局排序,只有一个 Reducer;

Distrbute By:类似 MR 中 Partition,进行分区,结合 sort by 使用。

Cluster By:当 Distribute by 和 Sorts by 字段相同时,可以使用 Cluster by 方式。Cluster by 除了具有 Distribute by 的功能外还兼具 Sort by 的功能。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC。

UDF、UDAF、UDTF

UDF:单行进入,单行输出
UDAF:多行进入,单行输出
UDTF:单行输入,多行输出

json解析

  1. 先加载rating.json文件到hive的一个原始表 rat_json
<!--数据-->
{"movie":"1193","rate":"5","timeStamp":"978300760","uid":"1"}
create table rat_json(line string) row format delimited;
load data local inpath '/root/hivedata/rating.json' into table rat_json;
  1. 需要解析json数据成四个字段,插入一张新的表 t_rating
drop table if exists t_rating;
create table t_rating(movieid string,rate int,timestring string,uid string)
row format delimited fields terminated by '\t';
  1. json表数据解析到rating表中
insert overwrite table t_rating
select 
get_json_object(line,'$.movie') as moive,
get_json_object(line,'$.rate') as rate,
get_json_object(line,'$.timeStamp') as timestring, get_json_object(line,'$.uid') as uid 
from rat_json limit 10;

常用函数

数值函数

--指定精度取整
select round(3.1415926,4) from dual;
--3.1416

--向下取整
select floor(3.1415926) from dual;
--3
select floor(25) from dual;
--25

--向上取整
select ceil(3.1415926) from dual;
4
select ceil(46) from dual;
46

--取随机数
select rand() from dual;
0.5577432776034763

--取绝对值
select abs(-3.9) from dual;
3.9
select abs(10.9) from dual;
10.9

日期函数

--返回时间字符串中的日期部分
--to_date(string timestamp)
to_date('1970-01-01 00:00:00')='1970-01-01'

--返回当前日期
current_date

--返回日期date的年,类型为int
--year(date)
year('2019-01-01')=2019

--返回日期date的月,类型为int
--month(date)
month('2019-01-01')=1

--回日期date的天,类型为int
--day(date)
day('2019-01-01')=1

--返回日期date1位于该年第几周
--weekofyear(date1)
weekofyear('2019-03-06')=10

--返回日期date1与date2相差的天数
--datediff(date1,date2)
datediff('2019-03-06','2019-03-05')=1

--返回日期date1加上int1的日期
--date_add(date1,int1)
date_add('2019-03-06',1)='2019-03-07'

--返回日期date1减去int1的日期
--date_sub(date1,int1)
date_sub('2019-03-06',1)='2019-03-05'

--返回date1与date2相差月份
--months_between(date1,date2)
months_between('2019-03-06','2019-01-01')=2

--返回date1加上int1个月的日期,int1可为负数
--add_months(date1,int1)
add_months('2019-02-11',-1)='2019-01-11'

--返回date1所在月份最后一天
--last_day(date1)
last_day('2019-02-01')='2019-02-28'

--返回日期date1的下个星期day1的日期。day1为星期X的英文前两字母
--next_day(date1,day1)
next_day('2019-03-06','MO') 返回'2019-03-11'

--返回日期最开始年份或月份。string1可为年(YYYY/YY/YEAR)或月(MONTH/MON/MM)
--trunc(date1,string1)
trunc('2019-03-06','MM')='2019-03-01'
trunc('2019-03-06','YYYY')='2019-01-01'

--返回当前时间的unix时间戳,可指定日期格式
--unix_timestamp()
unix_timestamp('2019-03-06','yyyy-mm-dd')=1546704180

--返回unix时间戳的日期,可指定格式
--from_unixtime()
select from_unixtime(unix_timestamp('2019-03-06','yyyy-mm-dd'),'yyyymmdd')='20190306'

条件函数

--如if(1>2,100,200)返回200
if(boolean,t1,t2)

--若布尔值成立,则t1,否则t2,可加多重判断
case when boolean then t1 else t2 end

--返回参数中的第一个非空值,若所有值均为null,则返回null
--coalesce(null,1,2)返回1
coalesce(v0,v1,v2)

--若a为null则返回true,否则返回false
isnull(a

字符串函数

--返回字符串长度
length(string1)

--返回拼接string1及string2后的字符串
concat(string1,string2)

--返回按指定分隔符拼接的字符串
concat_ws(sep,string1,string2)

--返回小写字符串
lower(string1)
lcase(string1)

--返回大写字符串
upper(string1)
ucase(string1)

--去字符串左右空格
trim(string1)
--去字符串左空格
ltrim(string1)
--去字符串右空
rtrim(string1)

--返回重复string1字符串int1次后的字符串
repeat(string1,int1)

--返回string1反转后的字符串
reverse(string1)

--返回'cba'
reverse('abc')

--以pad1字符右填充string1字符串,至len1长度
rpad(string1,len1,pad1)

--返回'abc11'
rpad('abc',5,'1')
--左填充
lpad('abc',5,'1')

--以pat1正则分隔字符串string1,返回数组
split(string1,pat1)

--返回["a","b","c"]
split('a,b,c',',')

--以index位置起截取int1个字符
substr(string1,index1,int1)

--返回'ab'
substr('abcde',1,2)

类型转换

--cast(value AS TYPE)
select cast('1' as DOUBLE)
--1.0

常用优化

Fetch 抓取

Hive中对某些情况的查询可以不必使用MapReduce计算。

例如:SELECT * FROM employees;

在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台。

在hive-default.xml.template文件中hive.fetch.task.conversion默认是more(老版本hive默认是minimal)

该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

走MR

hive (default)> set hive.fetch.task.conversion=none;

hive (default)> select * from score;

hive (default)> select s_score from score;

hive (default)> select s_score from score limit 3;

不走MR

hive (default)> set hive.fetch.task.conversion=more;

hive (default)> select * from score;

hive (default)> select s_score from score;

hive (default)> select s_score from score limit 3;

本地模式

大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。

不过,有时Hive的输入数据量是非常小的。

在这种情况下,为查询触发执行任务时消耗可能会比实际job的执行时间要多的多。

对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。

用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化。

--开启本地mr
set hive.exec.mode.local.auto=true;  

--设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max=51234560;

--设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max=10;

案例实操:

--开启本地模式,并执行查询语句
hive (default)> set hive.exec.mode.local.auto=true; 
hive (default)> select * from score cluster by s_id;
18 rows selected (1.568 seconds)

--关闭本地模式,并执行查询语句
hive (default)> set hive.exec.mode.local.auto=false; 
hive (default)> select * from score cluster by s_id;
18 rows selected (11.865 seconds)

分区、分桶表

分区表有利于sql过滤查询

分桶表有利于join操作

join优化

小表、大表之间join

(新版中已默认优化过)

  • 将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用Group让小的维度表(1000条以下的记录条数)先进内存。在map端完成reduce。
  • 多个表关联时,最好分拆成小段,避免大sql(无法控制中间Job)。

大表、大表之间join

空KEY过滤

有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤。例如key对应的字段为空。

对比如下:

不过滤

INSERT OVERWRITE TABLE jointable
SELECT a.* FROM nullidtable a JOIN ori b ON a.id = b.id;
-- 结果:
No rows affected (152.135 seconds)

过滤

INSERT OVERWRITE TABLE jointable
SELECT a.* FROM (SELECT * FROM nullidtable WHERE id IS NOT NULL ) a JOIN ori b ON a.id = b.id;
-- 结果:
No rows affected (141.585 seconds)
空key转换

有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的reducer上。

mapjoin

如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。

开启MapJoin参数设置(默认为true):

--设置自动选择Mapjoin
set hive.auto.convert.join = true;

--大表小表的阈值设置(默认25M以下认为是小表
set hive.mapjoin.smalltable.filesize=25123456;

group by

默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了。

并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果。

--开启Map端聚合参数设置:

--是否在Map端进行聚合,默认为True
set hive.map.aggr = true;

--在Map端进行聚合操作的条目数目
set hive.groupby.mapaggr.checkinterval = 100000;

--有数据倾斜的时候进行负载均衡(默认是false)
set hive.groupby.skewindata = true;

当选项设定为 true,生成的查询计划会有两个MR Job。

第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;

第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。

map数

  • 通常情况下,作业会通过input的目录产生一个或者多个map任务。

    主要的决定因素有:

    input的文件总个数、

    input的文件大小、

    集群设置的文件块大小(目前为128M,可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改)

  • 是不是map数越多越好?

    不是。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

    (应该减少map数)

  • 是不是保证每个map处理接近128m的文件块,就高枕无忧了?

    不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

    (应该增加map数)

  • 如何增加map数

    如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的,这种情况下,我们要考虑将这一个文件合理的拆分成多个,这样就可以用多个map任务去完成。

    set mapreduce.job.reduces =10;
    create table a_1 as
    select * from a
    distribute by rand(123);
    

    这样会将a表的记录,随机的分散到包含10个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。

reduce数

reduce个数并不是越多越好

  1. 过多的启动和初始化reduce也会消耗时间和资源;

  2. 另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

在设置reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的reduce数;使单个reduce任务处理数据量大小要合适;

--调整reduce个数方法一
--每个Reduce处理的数据量默认是256MB
hive.exec.reducers.bytes.per.reducer=256123456
--每个任务最大的reduce数,默认为1009
hive.exec.reducers.max=1009

--调整reduce个数方法二
--在hadoop的mapred-default.xml文件中修改
--设置每个job的Reduce个数
set mapreduce.job.reduces = 15;

jvm重用

JVM重用是Hadoop调优参数的内容,其对Hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或task特别多的场景,这类场景大多数执行时间都很短。

JVM重用可以使得JVM实例在同一个job中重新使用N次。N通常在10-20之间,具体多少需要根据具体业务场景测试得出。

  • 在Hadoop的mapred-site.xml文件中进行配置。

    <property>
      <name>mapreduce.job.jvm.numtasks</name>
      <value>10</value>
      <description>How many tasks to run per jvm. If set to -1, there is
      no limit. 
      </description>
    </property>
    
  • 在hive中

    set  mapred.job.reuse.jvm.num.tasks=10;
    

缺点:

开启JVM重用将一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡的”job中有某几个reduce task执行的时间要比其他Reduce task消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放。

数据压缩和存储格式

一般选择orcfile/parquet + snappy 的方式

create table tablename (
 xxx,string
 xxx, bigint
)
ROW FORMAT DELTMITED FIELDS TERMINATED BY '\t'
STORED AS orc tblproperties("orc.compress" = "SNAPPY")

压缩格式 :TextFile、SequenceFile、RCfile 、ORCfile

TextFile:存储方式为行存储,数据不做压缩,磁盘开销大,数据解析开销大。

SequenceFile:存储方式为行存储,其具有使用方便、可分割、可压缩的特点。

RCFile:数据按行分块,每块按列存储。

ORCFile:是rcfile的改良版本。

Parquet:行式存储,同时具有很好的压缩性能;同时可以减少大量的表扫描和反序列化的时间。

自定义格式:可以自定义文件格式,用户可通过实现InputFormatOutputFormat来自定义输入输出格式。

并行执行

一个sql中有多个job时候,且这多个job之间没有依赖,则可以让顺序执行变为并行执行(一般为用到union all )

--开启任务并行执行
set hive.exec.parallel=true;
--同一个sql允许并行任务的最大线程数 
set hive.exec.parallel.thread.number=8;

合并小文件

小文件的产生有三个地方,map输入,map输出,reduce输出,小文件过多也会影响hive的分析效率:

设置map输入的小文件合并:

set mapred.max.split.size=256000000;  

--一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;

--一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000;

--执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

设置map输出和reduce输出进行合并的相关参数:

--设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true

--设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true

--设置合并文件的大小
set hive.merge.size.per.task = 256*1000*1000

--当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000

数据倾斜

即上面优化的mapjoin、group by、map数、reduce数、合并小文件、

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/26231.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器视觉怎么对陶瓷板外观尺寸进行自动检测?

随着陶瓷行业的发展&#xff0c;陶瓷板的生产和质量控制面临越来越高的要求。而机器视觉技术作为一种高精度、高效率、无损、可靠性高的自动化检测手段&#xff0c;已经成为陶瓷板外观尺寸自动化检测的首选方案。本文就如何利用机器视觉对陶瓷板外观尺寸进行自动检测进行分析和…

常用模拟低通滤波器的设计——巴特沃斯滤波器

常用模拟低通滤波器的设计——巴特沃斯(Butterworth)滤波器 滤波器是一种具有频率选择作用的电路或运算处理系统&#xff0c;它具有区分区分输入信号的各种不同频率成分的功能&#xff0c;具有滤除噪声和分离各种不同信号的功能。综合一个滤波器的基本步骤分为逼近和实现。逼近…

设计模式之~享元模式

定义&#xff1a; 享元模式英文称为“Flyweight Pattern”&#xff0c;又译为羽量级模式或者蝇量级模式。 享元模式&#xff08;Flyweight Pattern&#xff09;主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。这种类型的设计模式属于结构型模式&#xff0c…

【每日挠头算法题(1)】——旋转字符串|亲密字符串

文章目录 一、旋转字符串思路1思路2 二、亲密字符串思路 总结 一、旋转字符串 点我直达终点~ 思路1 前提&#xff1a;如果s串和goal串长度不等&#xff0c;则goal串不可能是s串旋转得来&#xff0c;直接返回false&#xff1b; 通过观察&#xff0c;可以发现每旋转一次&#…

多线程屏障CyclicBarrier

文章目录 前言一、CyclicBarrier可以做什么&#xff1f;二、使用步骤1 单参数CyclicBarrier2 多参数 CyclicBarrier3 与CyclicBarrier类似的Exchanger 总结 前言 多线程中的CyclicBarrier,同样也是juc包下的一个工具类; 一、CyclicBarrier可以做什么&#xff1f; CyclicBarri…

一款开源的无线CMSIS DAP ARM芯片下载调试器详细说明

文章目录 概要1. 一般概念1.1 CMSIS—DAP的一般概念1.2 支持的芯片1.3 典型应用场景 2. 原理图与尺寸图2.1 Host端&#xff08;发送端&#xff09;原理图2.2 Target&#xff08;目标&#xff09;端原理图2.3 Host尺寸图2.4 Target尺寸图2.5 实物图 3. 使用方法3.1 连接方法3.1.…

4-5.配置信息和路由信息

一、配置信息 app.run()的参数 参数1&#xff1a;host&#xff0c;如果我们不指定&#xff0c;默认值是127.0.0.1。参数2&#xff1a;port&#xff0c;如果我们不指定&#xff0c;默认值是5000。参数3&#xff1a;debug&#xff0c;调试模式&#xff0c;如果不指定&#xff0…

电力系统直流潮流计算研究【IEEE9节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

皮卡丘反射型XSS

1.反射型xss(get) 进入反射型xss(get)的关卡&#xff0c;我们可以看到如下页面 先输入合法数据查看情况&#xff0c;例如输入“kobe” 再随便输入一个&#xff0c;比如我舍友的外号“xunlei”&#xff0c;“666”&#xff0c;嘿嘿嘿 F12查看源代码&#xff0c;发现你输入的数…

什么是SOME/IP?

SOME/IP 是"Scalable service-Oriented MiddlewarE over IP"的缩写&#xff0c;即可扩展的面向服务的IP中间件&#xff0c;由AUTOSAR发布。它是一种自动/嵌入式通信协议&#xff0c;它支持远程过程调用、事件通知和底层序列化/线格式。唯一有效的缩写是SOME/IP&#…

软件测试想要高薪资,不仅要卷还要学会跳槽

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了…

正在破坏您的协程(Coroutines)的无声杀手(Silent Killer)

正在破坏您的协程的无声杀手 处理 Kotlin 中的取消异常的唯一安全方法是不重新抛出它们。 今天生产服务器再次停止响应流量。 上个星期&#xff0c;你刚重新启动它们并将其视为故障。但是你总觉得有些奇怪&#xff0c;因为日志中没有任何错误的痕迹&#xff0c;甚至没有警告。…

求图的最短路径长度的弗洛伊德(Floyd)算法

弗洛伊德算法的适用情况&#xff1a;弗洛伊德算法既可以用来求解有向网的最短路径长度&#xff0c;也可以用来求无向网的最短路径长度&#xff0c;但是对于图中出现负权环的情况&#xff0c;弗洛伊德无法的得到正确的答案 弗洛伊德的算法思想&#xff1a; 以此图为例讲解弗洛…

从git上拉取项目

目录 一、前期准备&#xff0c;获取git下载链接 二、idea下载 2.1.打开git下载界面 2.2.进入下载界面 2.3.下载前期配置 2.4.输入账号密码 2.5.下载完成后idea打开 2.6.下载完成后文件目录展示 三、命令行下载 3.1.打开所需要下载的项目路径 3.2.进入黑窗口 …

c#快速入门(下)

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb;Inline和lambda委托和lambda &#x1f449;&#x1f…

操作系统(2.8)--线程的实现

目录 线程的实现方式 1.内核支持线程(KST) 2.用户级线程(ULT) 3.组合方式 线程的实现 1.内核支持线程的实现 2.用户级线程的实现 线程的创建和终止 线程的实现方式 1.内核支持线程(KST) 内核支持线程&#xff0c;与进程相同&#xff0c;是在内核的支持下运行的&#x…

前端使用tailwindcss 快速实现主题切换方案

使用Tailwind CSS在黑暗模式下为你的网站设计样式。 现在&#xff0c;黑暗模式是许多操作系统的第一流功能&#xff0c;为你的网站设计一个黑暗版本以配合默认设计&#xff0c;变得越来越普遍。 为了使这一点尽可能简单&#xff0c;Tailwind包括一个暗色变体&#xff0c;让你…

JVM之类的初始化与类加载机制

类的初始化 clinit 初始化阶段就是执行类构造器方法clinit的过程。此方法不需定义&#xff0c;是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。构造器方法中指令按语句在源文件中出现的顺序执行。clinit不同于类的构造器。(关联&#xff1a;…

连锁药店系统:如何提高效率和客户满意度?

连锁药店系统是一种用于提高效率和客户满意度的软件系统&#xff0c;它能够管理多个药店的日常营运。通过这种系统&#xff0c;药店可以更好地管理库存、员工、销售和客户信息等方面&#xff0c;从而提高整体的经营效率。 首先&#xff0c;连锁药店系统能够帮助药店管理库存。系…

算法刷题总结 (十一) 二叉树

算法总结11 二叉树 一、二叉树的概念1.1、什么是二叉树&#xff1f;1.2、二叉树的常见类型1.2.1、无数值&#xff08;1&#xff09;、满二叉树&#xff08;2&#xff09;、完全二叉树 1.2.2、有数值&#xff08;3&#xff09;、二叉搜索树&#xff08;4&#xff09;、平衡二叉搜…