大杂烩

1、用maven插件maven-assembly-plugin打包时,如果代码修改了,必须recompile主类or rebuild项目,才能再打包,否则修改不生效
2、打jar包部署到远程私服仓库

 - 修改maven的setting.xml文件:增加server,repositories等信息
 - 修改项目pom文件,增加repositories等信息
 - 运行mvn deploy

3、sqoop用于RDBMS和HDFS的数据迁移,但是不支持NoSql,比如说MongoDB
4、引用net.sf.json包:


	<dependency> 
		<groupId>net.sf.json-lib</groupId>
		<artifactId>json-lib</artifactId>
		<version>2.4</version> 
		<classifier>jdk15</classifier>
	</dependency>

6、Linux环境下非root用户安装Python及相关库
https://blog.csdn.net/dream_angel_z/article/details/51338546
7、少量数据去重:hash表去重
海量数据下去重:使用bitmap和布隆过滤器去重
8、三范式

  • 第一范式:要求有主键(不能重复),并且要求每一个字段原子性不可再分(如库表不能都放一个字段)
  • 第二范式:要求所有非主键字段完全依赖主键,不能产生部分依赖(保证一张表只描述一件事情)
    如学生信息和课程信息放到一个表里面,学生信息的学号为主键,如果没有人选课,那么课程信息也无法插入表。所以应该分成三个表:学生信息表,课程表,学生和课程关联表。保证每个表只描述一件事
  • 第三范式:所有非主键字段和主键字段之间不能产生传递依赖
    第三范式和第二范式很像,区别在于:第二范式是说一张表中包含了多种不同实体的属性,那么必须要分成多张表,第三范式是要求已经分好了多张表的话,一张表中只能有另一张表的ID(主键),而不能有其他任何信息(其他任何信息一律用主键在另一张表中查询)。

9、调度平台执行shell脚本,需要捕获脚本成功或失败状态,则需要加exit 状态码,而且exit状态码需要跟在最关键的执行代码后面,这个关键代码执行成功,表示整个任务执行成功
10、调度平台有依赖功能,即任务A依赖于任务B,那么只有B执行成功了,A才会执行,那么调度平台必须能捕获到任务真正的执行成功失败状态。
如20点10分执行A这个天任务,依赖于18点10分执行的B天任务,那么调度平台应该提供一个依赖时间范围,如当天18点到19点的依赖时间,表示当天这个时间B任务运行成功了,才会执行A任务
11、任务调度系统:https://blog.csdn.net/a331685690/article/details/81814000
12、在 2.5 亿个整数中找出不重复的整数,注,内存不足以容纳这 2.5 亿个整数 。

  • 方案 1:bitmap
  • 方案 2:也可采用与第 1题类似的方法,进行划分小文件的方法。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。

14、正则匹配手机号:^1[3578]\d{9}$
^1表示以1开头,[3578]表示第二位的数字为3578中的任意一个,\d{9}表示0~9范围内的数字匹配九次,$表示结束,12位以上的数字不匹配。
15、vim模式下查找:输入/,按下n查找下一个,按下N查找上一个
18、MQ-----ActiveMQ、RabbitMQ,Kafka,RocketMQ

  • RabbitMq比kafka成熟,在可用性上,稳定性上,可靠性上,RabbitMq超过kafka。但是吞吐量上远不及kafka,因为rabbitmq的架构跟zk很像,读写请求只能由master queue处理,如果连接到非master queue,则会路由到master queue处理。非master queue只是起到了同步备份功能

  • Kafka 定位是日志消息队列,可以看做是一个日志系统。吞吐量最大

  • KAFKA
    有丢数据的情况,做日志系统可以,做数据系统别用了,还是用rabbit。rabbitmq在金融场景中经常使用,具有较高的严谨性,数据丢失的可能性更小,同时具备更高的实时性,常用于金融场景交易数据传输

19、执行jar包的时候,如果要在命令里面添加依赖jar,则在后面加 :xxx.jar
java -cp xxx.jar:mysql-connector-java-5.1.8.jar
21、边缘计算方案–服务器端部署轻量级解析服务,边缘容器化部署,类似于Python里面的docker容器化部署。提高服务的鲁棒性。对于延时主要耗在网络传输的业务场景,尤其是在5G以后,数据爆发式增长,集中式的计算处理模式将面临难解的瓶颈和压力:因为大量的数据经过网络传输会受带宽,网络等影响。 此时,在靠近数据产生的网络边缘设备开始提供数据的一些处理的能力和服务,我们将这种数据网络边缘提供的处理能力叫做边缘计算。简单来说,是指在靠近物或数据源头的一侧,采用网络、计算、存储、应用核心能力为一体的开放平台,就近提供最近端服务。
23、多数情况下,一个汉字=2个英文字母=2字节=16个二进制位。但是不同的编码格式汉字占的字节其实是不一样的
24、递归和迭代的区别

//求n个连续正整数的和值
	//迭代
	int GetSum_1(int m) {
		int i = 1, sum = 0;
		while (i <= m) {
			sum = sum + i;
			i++;
		}
		return sum;
	}
	
	//递归
	int GetSum_2(int n) {
		if (n <= 0) {
			return 0;
		} else {
		  求n个连续正整数和=n +(求n-1个正整数的和)
			return n + GetSum_2(n - 1);
		}
小结
从写法上
        迭代:循环结构,例如for,while循环
        递归:选择结构,例如if else 调用自己,并在合适时机退出
从代码量上
        迭代:多
        递归:少
从性能上
        迭代:快
        递归:慢
推荐:能不用递归就不用递归,递归一般都可以用迭代来代替。

27、Metrics:让微服务的运行状态更透明
在应用程序中,通常会记录日志以便事后分析,在很多情况下是产生了问题之后,再去查看日志,是一种事后的静态分析。在很多时候,我们可能需要了解整个系统在当前,或者某一时刻运行的情况,比如一个系统后台服务,我们可能需要了解一些实时监控的数据。
例如,利用Metrics+ES/druid+grafana/kibana来构建监控平台。其中Metrics采集数据。ES/druid 存储数据。Grafana/kibana 显示数据。也可以用Metrics去监控go微服务接口,比如监控服务的请求数,内存,cpu的使用率等
28、大数据实时展示:用flink或者spark把数据写到es或者hbase,再通过kibana或者grafana去查询es数据进行展示
29、kibana想要制作一个x轴为时间的图表,那么index里面必须有一个字段是date类型。且flink写数据到es的时候,这个字段也必须是Date类型数据
30、实时数据服务,一般还要通过离线etl进行离线修正,补数
31、实时数仓在应用层,存储方案可选MySQL,es,druid等
32、spark写hdfs,orc格式不能像text格式一样,建表的时候指定分隔符,然后spark写hive的时候,直接写一个字符串,这样子orc表是不会根据分隔符拆分的,其实orc的表分隔符是没用的
33、bitmap原理
在java中:bits就表示一个二进制位,int型变量使用32bit存储数据,其中最高位是符号位,0表示正数,1表示负数,可通过Integer.toBinaryString()转换为bit字符串。比如9,在Java里面其实是1001这样二进制位存储的
byte -> 8 bits -->1字节
char -> 16 bit -->2字节
short -> 16 bits -->2字节
int -> 32 bits -->4字节
float -> 32 bits -->4字节
long -> 64 bits -->8字节
如果一共有1亿的数据:1、2、5、7、33、35……,那么具体的BitMap表示为:
array[0] 0000 0000 0000 0000 0000 0000 0101 0011
array[1] 0000 0000 0000 0000 0000 0000 0100 0101
Roaring bitmaps是一种超常规的压缩BitMap。它的速度比未压缩的BitMap快上百倍。
38、东八区时间:“2018-05-23T16:05:52+08:00”
utc时间:“2018-05-23T16:05:52.123Z”
39、布隆过滤器
本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构。
判断某个元素是否存在可以用HashMap,可以将值映射到 HashMap 的 Key,然后可以在 O(1) 的时间复杂度内返回结果,效率奇高。但是 HashMap 的实现也有缺点,例如存储容量占比高。
布隆过滤器是一个 bit 向量或者说 bit 数组,如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1。所以布隆过滤器整合了hash和bitmap技术
使用场景

  • 1.布隆过滤器的特性是:去重,多数去重场景都跟这个特性有关。比如爬虫的时候去掉相同的URL,推送消息去掉相同的消息等。
  • 2.解决缓存击穿的问题。
  • 3.反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱

41、如果一个类只有一个无参的构造函数,那么我们new这个类的时候,也只能new 类()
43、热部署,就是在应用正在运行的时候升级软件(修改代码,修改配置文件等等),却不需要重新启动应用而能立即生效。flume就属于一种热部署,当启动flume后,去修改配置文件,能立即生效
44、maven中provided作用: provided意味着打包的时候可以不用包进去,因为provided表明该包只在编译和测试的时候用
45、javascript, ajax, jquery的关系

JS是一门前端语言。
Ajax是一门技术,它提供了异步更新的机制,使用客户端与服务器间交换数据而非整个页面文档,实现页面的局部更新。
jQuery是一个框架,它对JS和Ajax进行了封装

46、Java中equals和 == 的区别
java中的数据类型,可分为两类:(不管是哪一类,我们做比较,是为了比较值,而不是为了比较它们在内存中的地址)

  • (1)基本数据类型:byte,short,char,int,long,float,double,boolean
    他们之间的比较,应用双等号,比较的是他们的值。
  • (2)复合数据类型(类)
    当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
    也就是string类型的值的比较比较用equals

47、HDFS架构:namenode,datanode,secondary namenode
mapreduce作业运行架构:yarn(RM,AM,NM…)
48、websocket

  • 1)websocket协议和http协议都是基于TCP协议的

  • 2)浏览器和服务器只需要做一个握手的动作,然后浏览器和服务器之间就形成了一条长连接快速通道, 两者之间就直接可以数据互相传送 。
    websocket 握手连接过程:
    客户端向服务器发送请求websocket的http报文,然后服务器来验证这个http报文是不是符合websocket的协议。如果符合,服务器返回握手报文,给客户端连接成功

  • 3)建立连接后,客户端就可以通过onmessage监控服务器端过来的数据,一有数据过来就执行onmessage对应的方法

49、取模运算(%),即取余数运算
50、在做分布式集群的负载均衡(一个请求进来了,是分配给A服务器还是B或者C)时,传统的取模方式以及hash方式在节点增加时,会产生大量数据搬迁。而用一致性hash就能保证在节点数量变化的时候影响尽可能小
54、两个栈实现一个队列:例如对于1,2,3,4 :先把数据push进栈1,再pop出数据,再把数据push进栈2,再pop出数据,最后结果就是1,2,3,4了
55、十进制整数转二进制:除2取余,逆序排列
十进制小数转二进制:乘2取整,顺序排列
56、简历查重:就是根据一定规则,提取出解析好的简历 json 中的特定字段组合,例如 姓名+邮箱+学校 就是一个组合,学校+公司+职位名 又是一个组合,一封简历可以有多个组合,每个组合的值转换成一个 md5 值,这样一封简历就对应多个 md5 值。两封简历只要有一个 md5 值相同,就认为这两封简历实际上是一个人的简历
57、simhash与传统hash的区别
传统hash描述两个内容是否一样,因为即使原始内容只相差一个字节,所产生的签名也很可能差别很大。
simhash描述两个内容是否相似。
做个测试,两个相差只有一个字符的文本串,“你妈妈喊你回家吃饭哦,回家罗回家罗” 和 “你妈妈叫你回家吃饭啦,回家罗回家罗”。
  通过simhash计算结果为:
1000010010101101111111100000101011010001001111100001001011001011
1000010010101101011111100000101011010001001111100001101010001011
  通过传统hash计算为:
  0001000001100110100111011011110
  1010010001111111110010110011101
  大家可以看得出来,相似的文本只有部分 01 串变化了,而普通的hash却不能做到,这个就是局部敏感哈希的魅力。
58、simhash原理:

1)分词(通过结巴,hanlp分词)
2)提取关键词(通过结巴,hanlp提取关键词,一般利用TF-IDF算法原理)
3)将每个关键词进行hash,加权,合并
4)降维

59、simhash在实际项目中的应用:根据短文本查找相似简历

  • 64位二进制的simhash值从高位到低位,划分成四个连续的16位二进制段, 存储在ES的simhash字段
  • 将海明距离设为3,那么相似的两段文本必有一个16位二进制段相同
  • 将要查询的文本的4个16位二进制段分别循环去ES的simhash字段中查找

60、知识图谱

  • 1)其实百度百科就可以看作是一个知识图谱,我们往ES里面加载的公司学校数据(公司的名字,行业,历史,懂事,英文名。。。)也类似于一个知识图谱
  • 2)构建知识图谱,首先要进行数据收集,预处理。比如不同的人对同一家公司可能有不同的写法,这时候就要对公司名进行实体对齐(normalize)

61、词性标注是做动词或名词这种词性标注的
命名实体识别是识别一个 token 是什么实体
比如:

#NLPTokenizer会进行实体识别
#首先分词,然后进行实体识别(将公司这个实体识别出来),最后还会进行词性标注
NLPTokenizer = JClass('com.hankcs.hanlp.tokenizer.NLPTokenizer')
print(NLPTokenizer.segment('李嘉诚创建了成都科技公司'))		输出:[李嘉诚/nr, 创建/v,/u, 成都科技公司/nt]
#HanLP不会进行实体识别:首先分词,然后进行词性标注
HanLP = JClass('com.hankcs.hanlp.HanLP')			
print(HanLP.segment('李嘉诚创建了成都科技公司'))				输出:[李嘉诚/nr, 创建/v,/ule, 成都/ns, 科技/n, 公司/nis]

62、JD解析逻辑

  • 1)人工整理多个词典:比如证书词典,主要包括词和词性(nerName: ncert),这其实也是词性标注的工作
  • 2)词典用于三个方面:
    • 绝大部分词典通过CustomDictionary.insert加入到hanlp的分词词典里面。对一个文本利用hanlp进行分词时,如果文本中某个词在词典里面有,就会将整个词以及它的词性匹配出来
    • 对于公司,学校等数据量较大的词典,为了避免hanlp的性能问题,这两个词典存在于mongo中,并将其构造为tries树,利用trie树结构,进行快速公司,学校实体匹配。trie树匹配方法输入的是一段文本中的一行,快速的遍历trie树,查找这一行里面有没有公司学校实体
    • 对于一些量较少的词典,也可以加载到内存(trie树)里面----flashtext,通过flashtext进行关键词快速查找
  • 3)通过hanlp(词典)以及trie树进行分词,实体识别后。根据短文识别的基于上下文的语意理解,还要将token组合成句子,句子再组合成段落,段落组合成section等等。再通过在前端配置需要寻找的词的词性,比如location:nsct,然后利用token_query工具从上述处理结果中查询出地点

63、秒杀系统
一个秒杀活动开启之前,首先会在数据库表goods_info插入一条要秒杀的商品及其数量
在这里插入图片描述
迷你版秒杀系统

每个用户请求(一个线程)过来,传来两个参数-商品编号和购买数量:code1和buy_count。然后执行数据库更新:
update good_info set amount=amount - buy_count where code=code1
由于秒杀系统都是高并发,所以执行数据库更新的Java代码必须加锁,否则线程不安全造成超卖。加锁有悲观锁syncronize和乐观锁,对于秒杀系统这种读多写少,需要高吞吐的场景,需要加乐观锁,乐观锁有以下几种实现:
1)基于MySQL加版本号实现:数据库表增加一个version字段,每个线程进来,首先将当前version1和amount1读出来,然后判断amount 1- buy_count是否大于0,如果大于0,再检查读出来的version与此时数据库里面的version是否一致,一致则更新数据库数据,并且version+1(其实就是CAS乐观锁的实现!)。粗体这几个步骤需要保证原子性,可通过一句sql保证原子性:
update good_info set amount=amount - buy_count, version=version + 1 where code=code1 and version=version1
ps:如果version不一致,那么将线程休眠5秒范围内的随机秒数,随机的目的是打散线程请求,尽量避免高并发,实现错峰。休眠完之后继续递归上述操作。
2)上述基于数据库实现的乐观锁,虽然简单易行,但是并发能力低,MySQL的并发能力不到1000,并且做不到分布式,即分布式下MySQL无法保证数据一致性。所以对于超大并发的场景,要用redis或者memcached等分布式缓存实现乐观锁,那么此时对应的,库存扣减是在缓存中完成的。主要有以下两种方式:
* 利用watch指令在redis的事务中实现cas
* memcached的gets方法(拿到当前version)和cas方法(检查读出来的version与此时数据库里面的version是否一致,一致则更新memcached里的库存数据,并且version+1)实现

生产上千万级秒杀系统
数据库的性能是瓶颈,所以在请求打到数据库之前,尽量拦截掉大部分流量。
在页面层,每次用户点击购买都要输入验证码,可以过滤掉很多请求。
在应用层,对于一些恶意脚本发送的大量请求,可以在用nginx进行限流:如一个ip在10秒内只能请求一次。
服务层的减库存操作也要做成分布式的,所以要用redis或者memcached。并且对于上面提到的如果version不一致的情况,此时不是在Java代码里面让线程休眠这么简单,而是将请求放到mq队列里面,分批执行,达到削峰的目的。当然了,将请求放到队列里面,也可以是在操作redis库存之前,即请求先放队列里面,按顺序取出,去操作redis库存。当遇到version不一致的情况,再将请求放到另外一个队列里面…
最终到达数据库层,也要进行读写分离,分库分表等等操作
在这里插入图片描述
64、nginx限流
Nginx官方版本限制IP的连接和并发分别有两个模块:
limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”。
limit_req_conn 用来限制同一时间连接数,即并发限制。
65、负载均衡设计
从大的方向上讲,负载均衡分为硬负载均衡,和软负载均衡。

  • 硬负载均衡: 也就是使用专用的负载均衡设备。主流的硬负载均衡器有如下几种:
    F5:最主流的硬负载均衡器。便宜的20万以上,贵的100多万。 深信服:乞丐版低配12万元起价。 A10:基本都在100万元以上。
  • 软负载均衡:不使用专用的负载均衡设备,而是通过软件来实现负载均衡。常用的有如下几种: DNS:最原始的负载均衡方式,名字就已经说明了一切,不用细说了。
    LVS:最常用的软件负载均衡。我见过的国内百万级用户的架构,基本都是靠它顶的。 Nginx:也是现在流行的、常用的负载均衡方案之一。

66、LVS
LVS(Linux Virtual Server)即Linux虚拟服务器
LVS负载均衡调度算法
静态调度算法:不考虑真实服务器上的当前负载情况

  • 轮询调度
    轮询调度(Round Robin简称’RR’)算法就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是实现简单。轮询算法假设所有的服务器处理请求的能力都一样的,调度器会将所有的请求平均分配给每个真实服务器
  • 加权轮询调度
    加权轮询(Weight Round Robin简称’WRR’)算法主要是对轮询算法的一种优化与补充,LVS会考虑每台服务器的性能,并给每台服务器添加一个权值,如果服务器A的权值为1,服务器B的权值为2,则调度器调度到服务器B的请求会是服务器A的两倍。权值越高的服务器,处理的请求越多
    由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,我们根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。
  • sh:source hashing Source
    Hash,源地址哈希;此算法根据请求服务的客户端的域名或IP地址,进行哈希计算,计算后的值对Real
    Server个数取模求余,从而保证可以将同一域名或IP的请求始终分发到后端的同一个Real
    Server上,常用于Session保持等场景;
  • Dh:Destination hashing Destination
    Hash,目标地址哈希;不同于SH是根据客户端的信息进行哈希计算,DH算法是根据请求的目标资源进行哈希计算,比如请求的URL,此方式的目的在于:能够保证对相同资源的请求始终分发到后端同样的Real
    Server上; 典型的应用场景在缓存服务器上,比如我们的LVS和Real
    Server之间增加了一层缓存服务器,缓存服务器缓存了一部分静态资源,那么LVS使用DH算法,可以将客户端请求的已存在缓存服务器的资源,始终分发给缓存服务器,而不必分发给Real
    Server,从而可以大大降低后端的压力,同时也提高了响应速度,两全其美的事情

动态算法,其会考虑后端服务器的实际负载情况,并选择负载小的进行请求分发

  • LC:Least Connection,最少连接数;此算法会根据后端每台RealServer的连接数多少来分发请求,对于连接数少的服务器,会多分发客户端请求,以尽可能利用资源占用较少的服务器
    连接数计算方法:active * 256 + inactive
    注解:active表示正处于HTTP正发送请求或处理请求过程中;inactive表示该连接非请求和处理过程中,只是长连接释放结算,或四次挥手阶段;

  • WLC:Weight Least Connection,加权最少连接数;后端Real
    Server可能性能差异较大,WLC算法可以动态的获取不同服务器的真实负载情况,并调整对应的加权值,从而始终保证将请求分发到性能优异且较空闲的机器,从而提高处理效率
    连接数计算方法:( active * 256 + inactive ) / weight

  • SED: Shortest Expect Delay,最短期望延迟;此算法是对WLC的一种改进,和WLC的不同在于其连接数计算方法的不同
    SED连接数计算方法:( active + 1 ) * 256 / weight
    和WLC不同在于两点:
    (1)、不将非活动连接数计算在内
    (2)、将active做+1处理

  • NQ: Never Queue,永不排队算法;此种算法,当客户端请求到达时,会首先根据SED算法进行选择一个RS,然后把请求分配给这个服务器,同时从算法列表中将此台服务器排除,下次请求到达时,只会在剩下的服务器列表中根据SED进行选择,等到每一台主机都分配到连接后,调度器此后每次都会根据SED算法在所有的服务器中进行计算选择;

  • LBLC:Locality-Based Least Connections,基于局部性的最少链接
    基于局部性的最少链接”调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。

    总结:LVS的负载均衡算法,不同的应用场景,应选择合适的负载均衡算法,只有在充分了解了每一种算法的思想之后,才能根据自己的业务需求结合应用场景来做选择;
    如果你实在不知道该如何选择,那么推荐选择WLC算法是一个不错的选择;WLC算法在实际的生产环境中,应用还是挺多的。

67、get和post的区别
get和post是HTTP协议中的两种发送请求的方法
最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。所以GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
68、数据异常监控
1)在传统的数据异常监控中,根据开发人员以及分析人员的经验进行阈值设置,是最简单的数据异常发现方法。但是当业务变化,数据变化,就要手动调节阈值。当任务多,数据量变化多的时候,一个个去配置阈值显然是不现实的
2)大多数的数据曲线可以归纳为三种类型:
* 稳定性(一条直线):3σ算法
标准正态分布下的曲线为钟型曲线,期望值μ决定了其位置,其标准差σ决定了分布的幅度。对于一组符合正态分布的数据,如果某个值距离μ值超过三个标准差σ则可以判断这个值属于异常数据。
* 有规律周期型(有规律的波浪线):同比历史数据。z-score算法
* 趋势型数据(如缓慢一直上升或者下降):环比附近数据。r-score算法
3)判断数据是哪一种类型,可以用决策树模型去判断

69、箱线图适用于大批量的数据波动监控。箱形图最大的优点就是不受异常值的影响,能够准确稳定地描绘出数据的离散分布情况,同时也利于数据的清洗。
在箱线图中,箱子的中间有一条线,代表了数据的中位数。箱子的上下底,分别是数据的上四分位数(Q3)和下四分位数(Q1),这意味着箱体包含了50%的数据。因此,箱子的高度在一定程度上反映了数据的波动程度。上下边缘则代表了该组数据的最大值和最小值。有时候箱子外部会有一些点,可以理解为数据中的“异常值”。
使用方法:将要监控的数据喂进箱线图模型,就会画出一个箱线图:表明数据的分布,数据的离群点。
箱形图的作用:识别数据异常值

70、io多路复用
多路:有多个客户端连接;复用:一个进程或线程处理上面所有的连接。
如果不复用又需要同时服务多个客户端,需要多线程或多进程,这个就不是复用了。
可以理解成多路io复用,即多个io数据流复用同一个线程。这就像是一个工作很高效的人,手上一个todo list,他高效的依次处理每个任务。这比每个任务单独安排一个人要节省。
IO多路复用 + 单进(线)程有个额外的好处:不会有并发编程的各种坑问题,比如在nginx里,redis里,编程实现都会很简单很多。编程中处理并发冲突和一致性,原子性问题真的是很难,极易出错。
select,poll,epoll都是io多路复用的实现。
当有多个io流即多个客户端连接,该怎么办?
1)方法一:多线程,一个线程负责处理一个io流。但是这样未必是最好的,因为线程创建,以及多个线程之间的协调维护都要消耗计算机资源
2)方法二:单线程忙轮询。我们只要不停的把所有流从头到尾问一遍当前有没有数据,有数据就用单线程去处理,然后又从头开始。这样就可以处理多个流了,但这样的做法显然不好,因为如果所有的流都没有数据,cpu就会空转
3)方法三:select版本io多路复用。为了避免CPU空转,可以引进了一个代理—select。这个代理比较厉害,可以同时观察许多流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中醒来,于是我们的程序就会轮询一遍所有的流。注意从select那里仅仅知道了,有I/O事件发生了,但却并不知道是那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。
4)方法四:epoll版多路复用。 epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll之会把哪个流发生了怎样的I/O事件通知我们。此时我们对这些流的操作都是有意义的。

71、CPU负载过高可能的原因
程序陷入死循环,不停地消耗CPU;
线程死锁,线程相互等待,导致假死状态,不停地消耗CPU

排查思路:
1)用top命令查看CPU负载过高的PID---进程
2)top -H -p PID 查看指定进程中CPU占用过高的线程ID(十进制)
3)jstack PID > ljy.log		将进程的堆栈信息输出到文件
4)cat ljy| grep 线程ID(转换为16进制后)		从堆栈文件中查找对应的线程信息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值