PS:本文已收录到1.4K+ Star 数的开源项目《大厂面试指北》,如果想要了解更多,可以访问Github项目主页 : https://github.com/NotFound9/interviewGuide
建了一个技术交流群,欢迎大家进群一起玩耍,一起学习进步!进群还获取我自己原创的《大厂面试指北》PDF版 在日常的业务开发中,通常需要对一些数据做唯一标识,例如为大量抓取的文章入库时分配一个唯一的id,为用户下的订单分配订单号等等。并发量小的时候,通常会使用数据库自增的主键id作为唯一id。并发量大的时候就会考虑使用一些分布式ID的生成方案来生成id。由于一些特殊的业务需求,我们的业务中也使用到了分布式ID的生成,对分布式ID的各种方案进行了调研。所以这里给大家分享一些我们在实践过程中进行的调研和实践优化经验,因为篇幅比较长,我们主要分为三篇:
【分布式系列01期】常见的分布式ID生成方案浅析及大厂方案调研
【分布式系列02期】开源分布式ID生成框架Leaf和uid-generator的原理分析
【分布式系列03期】开源分布式ID生成框架Leaf和uid-generator存在的问题及优化改进
摘要
本文是【分布式系列01期】中的第一篇,主要包含分布式ID生成方案简介 和当前大公司的ID生成方案研究 两部分
一、分布式ID生成方案简介
目前常用的分布式ID生成方案主要由以下几种:
1.使用UUID算法生成唯一id。
2.利用单机数据库主键自增来生成唯一id。
3.多数据库主键自增生成唯一id。(设置步长区分不同数据库)
4.数据库分段发号生成唯一id。(例如美团的Leaf框架中的segement模式)
5.基于snowflake算法生成唯一id(例如美团的Leaf框架中的snowflake模式,百度的uid-generator)
这是我做的总结表:
方案
优点
缺点
适用场景
使用UUID算法生成唯一id
无任何依赖
ID太长,且不是数字类型
生成seesion_id
利用单机数据库主键自增来生成唯一id
方便接入,单调递增
生成效率低,强依赖于数据库,id是连续的
适用于并发量不高的业务。
多数据库主键自增生成唯一id
方便接入,单调递增,生成效率比单机数据库高
不方便扩容,强依赖于数据库,id是连续的
适合分库分表的架构生成id
数据库分段发号生成唯一id
效率高
强依赖于数据库,id是连续的
适合id生成并发量高的业务,并且id连续 不会破坏信息安全的业务。
基于snowflake算法生成唯一id
效率高,运行期间可以不依赖其他组件
id分布不均,对有些业务会造成数据倾斜的问题
适合id生成并发量高的业务
1.UUID
简单的来说,UUID是服务器在不需要任何外界依赖(像类Snowflake算法的方案都需要注册中心)的情况下,基于当前时间、计数器(counter)和硬件标识等等信息生成的唯一ID。
优点
无任何依赖
其他的技术方案都是有依赖的,比如单机数据库主键自增生成ID 强依赖数据库,类Snowflake算法的方案 至少启动时都需要注册中心,Leaf框架Snowflake模式需要定时上传时间戳到注册中心,的UUID生成不需要任何外界依赖,
缺点
ID太长,且不是数字类型
当然为了唯一性,带来的牺牲就是生成的结果一般是32位的字符串。由于字符串太长,并且不是数字类型,所以不适合作为数据库的主键。
(字符串作为主键id,插入数据时会是在聚集索引中是随机插入,容易造成页分离。而且字符串的比较比数字类型的开销更大,字符串作为主键id查询效率会低于数字类型的主键。)
适用场景
通常可以作为一些临时性唯一标识,例如用户登陆后,生成一个UUID作为登录的会话ID,作为key存储在Redis中,Value是用户相关的信息。
2.单机数据库主键自增
业务量不大时普遍采用这种方案来生成id。
优点
方便接入
因为一般的项目不一定会用到Zookeeper等这些组件,但是基本都会用到数据库,所以项目接入会比较简单,也没有增加额外的维护成本。
单调递增
是绝对的单调递增的,就是从时间线上看,后面生成的id肯定比前面生成的id要大。
缺点
生成id效率有限
因为id生成依赖于单机数据库的主键自增,所以无法满足id并发量很大的业务需求。
强依赖于数据库
一旦单机数据库发生宕机,就没法生成id,导致整个系统不可用。如果数据库是主从架构的,主库发生故障,切换成从库,如果从库还没来得及收到主库最新的插入id的更新,就有可能导致从库当前的自增id不是最新的,从而生成出重复的id。
id是连续的
id是连续的有可能会成为缺点,竞争对手在当天12点下一个订单,然后在第二天12点下一个订单,可能根据订单id的差就可以推测出每天的订单量。像猫眼电影就使用了这种方法来生成电影的id。一般我们日常使用时,其实为了让我们生成id的方式更难被竞争对手猜测出,一般是不会从1开始的,但是猫眼电影这里是从1开始的,而且是连续的,所以我们使用二分法很快就确定了8875是最大的值,也就是总共有8875部电影,而且由于是连续的,爬取也会比较方便。 猫眼电影的id——也是使用单机数据库生成的,连续自增的
https://maoyan.com/films/1
https://maoyan.com/films/2
https://maoyan.com/films/8874
https://maoyan.com/films/8875
https://maoyan.com/films/8876
(1到8875可以请求到数据,8876及后面的id
请求不到数据,没有这些id对应的电影,说明总共有8875部电影)
除非去做额外的处理(例如定时去获取当前的自增起始值a,然后生成一个随机数b,使用alter table users AUTO_INCREMENT=a+b;
命令对自增起始值修改,也就是跳过一些id。)
适用场景
适用于并发量不高的业务。
3.多数据库主键自增生成唯一id。(设置步长区分不同数据库)
可以使用以下命令设置MySQL中表每次自增时的步长,通过将不同数据库的步长设置为一样,可以让不同数据库生成的id进行区分。
CREATE TABLE table (...) AUTO_INCREMENT = n;
alter table auto_increment=2;
例如,步长是等于数据库的数量,例如有N台数据库, 第一台数据库的起始值是0,那么生成的id就是0,N,2N,3N等等。
第一台数据库的起始值是1,那么生成的id就是1,N+1,2N+1,3N+1等等。 这样各个数据库生成的id就不会冲突,并且每个数据库可以单独生成id。
优点
生成id的效率比单台数据库要高,因为可以多台数据库同时发号。
缺点
是解决了每次自增是1的问题,缺点是一旦设置了步长,就不方便扩容了,因为分库分表的表的数量已经定下来了。
使用场景
在没有分库分表的框架以前,那些分库分表就是使用这种方案来实现的。
4.数据库分段发号生成唯一id。(例如美团的Leaf框架中的segement模式)
简单来说,就是想下图一样,用一个数据库表来充当发号器, 表中字段介绍如下:
biz_tag字段用于区分每种id应用的业务,
max_id字段记录了当前已生成的最大的id,
step字段代表每次可以获取id的数量
id生成项目每次使用下面这条语句从数据库获取step数量的id,并且更新max_id的值,将step数量的id存储在内存中,供业务方通过HTTP,RPC,Client等方式来获取。
UPDATE leaf_alloc SET max_id = max_id + step WHERE biz_tag = #{tag}
优点
效率高
生成id的效率取决于step的大小,不会像主键自增生成id那样再受限于数据库的数量。
缺点
强依赖于数据库
还是强依赖于数据库,数据库宕机后,虽然id生成系统靠内存中还未使用完id,可以维持系统正常运行一段时间,但是数据库不可用还是会导致整个系统不可用。
id是连续的
容易造成被爬取,以及被竞争对手猜测出一天的订单量
5.基于snowflake算法生成唯一id
snowflake是推特开源分布式ID生成算法,一共有64位,
第一位是0,是标志位 ,因为在二进制数中,第一位是0,代表是正数。
接下来41位是13位的毫秒时间戳 ,最大可以到2039年9月。
再接下来10个二进制位是workID ,也就是服务器的id。
最后面12位是业务序列号
意味着每毫秒最大可以生成2的12次方个id,4096个,支持每个机器每毫秒生成4096个id,每秒可以生成400多万的id
优点
效率高
生成id的效率比较快,最高在1ms内可以生成2的12次方,也就是4096个id。
不依赖其他组件
生成id的过程中,主要是根据时间戳,workID,序列号来进行生成,可以做到不额外依赖其他组件,只依赖于本地系统时间独立地生成id。
缺点
易造成数据倾斜的问题
举例:一个数据库中总共有10个id,分别是
0,25,26,27,28,29,30,31,32,100
id的最小值是0,最大值是100,按照id最大值减去最小值,进行范围切分,分成四段的话,范围是以下四个范围:
[0,25), 存在1个id,值分别是0
[25,50) 存在8个id,值分别是25,26,27,28,29,30,31,32
[50,75),存在0个id
[75,100] 存在1个100,值是100
这样明显就会存在数据倾斜的问题,就是[25,50) 这个区间存在的id数量特别多,而其他区间存在的id数量特别少。如果我们用Sqoop将MySQL中的数据导入到Hive中去时,就是按照这种id最大值减去最小值,进行范围切分
实现方法进行数据分片,然后多线程进行数据导入,每个线程负责一个分片的数据,数据不均匀的话,导入的时间就会变长,有些线程分配的数据量少,导入很快,有些线程分配的数据量大导入很慢。总导入时间取决于最慢的那个线程的时间。
使用Snowflake生成的id,id值的大小因为取决于生成id时的时间戳,如果某一个时间段爬取了大量文章进行入库,在很短的时候内生成了很多id,而其他时间段生成id数量很少,在使用Sqoop导入数据时就会有数据倾斜的问题,需要单独自己进行数据切分,让数据变均匀,然后进行导入。
二、当前大公司的ID生成方案研究
头条
头条的内容主要分为文章,图集,视频,这三种内容的数据来源主要由编辑发布,及从其他网站抓取。
调研方法
这是一篇头条的一篇文章https://www.toutiao.com/a6841...
id是19位,因为19位的id其实从数量级是上看已经是2的9次方 亿级别了,所以不太可能有这么多文章入库,然后通过数据库主键id递增生成的,所以有很大的可能性是通过snowflake算法生成的,
我们将6841306705796530700转换为二进制数后是
10111 10111 10001 00110 10000 11001 11011 11101 00000 00000 00010 00001 100
一共是63位,因为原始的snowflake算法是1标志位+41位毫秒时间戳+10位机器位+12位序列号,所以我们取前41位
10111 10111 10001 00110 10000 11001 11011 11101 0
去转换成10进制数,得到
1631094623994
转换为毫秒时间戳,是
2021-09-08 17:50:23
这是未来的时间,所以不太可能是这种方案,因为其实1ms的ID并发量其实根本不需要2的12次方,也就是4096那么大,1s内的QPS能有几百都是量特别大了,
原理:每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间
公式:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)
机器:峰值时间每秒QPS / 单台机器的QPS = 需要的机器
问:每天300w PV 的在单台机器上,这台机器需要多少QPS?
答:( 3000000 * 0.8 ) / (86400 * 0.2 ) = 139 (QPS)
根据这个原理来算的话,假设每天有300万个请求,摊到峰值时间,每秒的QPS峰值也就是139。而且每天也很难有300万篇文章入库,导致需要300万个id,所以QPS其实是很小的。头条有可能是使用的是1标志位+31位秒级时间戳+32为自己定义的机器位和序列位,所以我们取了前31位
10111 10111 10001 00110 10000 11001 1
转换为10进制数是
1592865843
按照秒级时间戳换算也就是
2020-06-23 06:44:03
跟文章的发文时间2020-06-23 06:44:52
是很相近。有一定的时间差可能是因为id里面的时间戳是入库的创建时间(编辑点击新建文章按钮进入编辑页面),而界面显示的是文章的发布时间。
详细的调研结果
我们通过抽取了一些id转换为二进制后,猜测id二进制位组成是31位秒级时间戳+10位的序列位+18位的预留位+4位的机器位 ,其实看表里面发现18位的预留位都是000000000000100000
。最多支持32台ID生成机器同时运行,单台机器QPS最高可达到1024,总QPS最高可以达到32768。(目前不知道18位预留位的作用)
美团
猫眼电影
才猜测是单机数据库连续自增实现的,id范围是1到8875,一共8875部电影。
榛果民宿——不连续自增
发现id是从2500000后才有数据的,而且很多id都不是连续的,猜测是使用Leaf-Segement模式来生成的id,每次从数据库取一个id号段,将可用id存储到内存中,然后等业务系统请求进行发放。并且自己额外做了id抛弃策略,让id不连续保证信息安全性及提高抓取难度。
美团外卖订单号
肯定是使用snowflake算法来生成的,但是由于它们的时间位使用的是时间差(就是时间戳减去一个指定的时间点),而且位数分配可能做了额外的处理,所以不太好推断。
外卖
下单时间
5026 0271 7642 2612 7
2018-09-02 17:46:03
6233 7340 1594 0462
2018-07-17 18:34:11
3962 9431 3190 0632 1
2018-07-15 11:52:55
2273 5322 6921 7033 5
2017-06-30 11:39:01
汽车之家
使用的就是自增id,现有数据从4位到6位,目前最大320w+,实现原理应该就是数据库主键自增,由于他们的量比较大,应该是采用的多数据库设置步长,来多数据库生成id的。
下面是统计表
总结
感觉目前大公司还是使用Snowflake作为分布式ID生成方案的比较多,一方面可以满足并发量很高的id获取需求,一方面id连续性很低,可以保证信息安全,提高爬虫难度。除此以外,可能有一些业务刚起步时并发量小直接采用单机数据库主键自增生成id,使用4.数据库分段发号生成唯一id
这种方案也能满足高并发量,但主要还是id是连续的,即便是额外开发id丢弃逻辑,也容易被竞争对手一个一个id请求来推测出订单量信息。
精彩回顾:
你可能感兴趣的:(java,后端,mysql,数据库,redis)
【LeetCode】215.数组中的第K个最大元素(三种方法,九个思路的代码实现,java格式)
Hi丶ImViper
LeetCode 算法与数据结构 算法 数据结构 java 快速排序
题目题目链接解析这道题据说是面试的高频考题,同时也是基础算法的应用。方法一:暴力解法题目要求我们找到“数组排序后的第k个最大的元素,而不是第k个不同的元素”,语义是从右边往左边数第k个元素(从11开始),那么从左向右数是第几个呢,我们列出几个找找规律就好了。一共6个元素,找第2大,索引是4;一共6个元素,找第4大,索引是2。因此,升序排序以后,目标元素的索引是len-k。这是最简单的思路,如果只答
LeetCode215.数组中的第K个最大元素 java使用小顶堆求解
patientany
java 开发语言
JAVA实现小顶堆手撕小顶堆定义堆中的成员变量提供构造方法建堆下潜交换堆的尾部添加元素上浮获取堆顶元素替换堆顶元素删除指定元素删除堆顶元素回到题目具体步骤上代码手撕小顶堆在java中实现小顶堆定义堆中的成员变量这里首先先定义堆中的数据,在这里我使用了整数数组表示整个堆。size表示堆的大小,默认也就是数组的长度。int[]array;intsize;提供构造方法对于堆的初始化,由传进来的数组实现对
莫名锁表? --- mysql的事务隔离级别
程序员小软
mysql 数据库 java
前言系统响应超时系统访问数据库特别慢莫名提示锁等待超时数据库锁表事务长时间等锁,直到超时以上问题都可能是事务锁表导致的问题今天测试反馈系统批量处理莫名提示锁等待超时,再次操作查看数据库事务确实存在等锁情况,甚至死锁。刚开始是偶尔出现,后来一直就是死锁,导致其他操作也操作不了。刚开始发现数据库中操作插入的时候会进入锁等待怀疑是这张表中主键自增导致的锁表,于是将表改为指定主键,问题依然存在。后来想起来
Dockerfile及Docker-compose Yaml
Darklord.W
docker docker dockerfile docker-compose yaml
Dockerfile一、结构:基础镜像信息维护者信息镜像操作指令容器启动时执行指令FROM指明构建的新镜像是来自于哪个基础镜像,例如:FROMcentos:6MAINTAINER指明镜像维护着及其联系方式(一般是邮箱地址),例如:MAINTAINEREdisonZhou不过,MAINTAINER并不推荐使用,更推荐使用LABEL来指定镜像作者,例如:LABELmaintainer="xxxxx.c
MySQL数据库架构设计:分片与分区策略实战
墨瑾轩
一起学学数据库【一】 mysql 数据库架构 adb
关注墨瑾轩,带你探索编程的奥秘!超萌技术攻略,轻松晋级编程高手技术宝库已备好,就等你来挖掘订阅墨瑾轩,智趣学习不孤单即刻启航,编程之旅更有趣在数据库的魔法森林中,MySQL就像是一位智慧的老树精,而分片(Sharding)与分区(Partitioning)则是它手中的两把神秘钥匙,能够打开数据高效存储与快速检索的大门。今天,我们就一起踏上一场奇幻之旅,探索如何运用这两把钥匙,打造一个既强大又灵活的
JAVA有哪些主要用途
By北阳
java
Java是一种广泛使用的编程语言,非常流行,并经常用于构建各种类型的应用程序。在本篇博客中,我将为你详细介绍Java可以干什么,以及它在现代软件开发中的重要性。1.Web应用程序开发Java是一种非常流行的编程语言,可用于构建Web应用程序。Java提供了一系列开发工具和框架,例如Spring,SpringBoot和JavaServerPages(JSPs),可用于快速构建Web应用程序。使用Ja
【Java基础19】异常,异常处理,自定义异常,受检与非受检异常
摘星观月
Java基础 java jvm 开发语言
一、异常1、概念异常是阻止当前方法或作用域继续执行的问题,在程序中导致程序中断运行的一些指令。Throwable是异常的基类,分为Error和Exception。Exception分为编译期异常(受检)和运行期异常(非受检)。异常会导致程序中断,无法继续执行。在开发中,我们要把可能出现异常的代码使用try语句包裹起来。处理异常可以保证程序继续执行。2、案例publicclassTest02{pub
Java—异常体系
且将&
Java基础 java
文章目录异常和错误java异常的分类:非运行时异常运行时异常受检异常(非运行时异常)如何处理?1、trycatchfinally为什么要用trycatchfinally2、throwsThrow和Throws的区别JVM是如何处理异常的try-catch-finally中哪个部分可以省略————————————————————————————————异常和错误下面这就是异常(exception)错
L2-023 图着色问题 - java
谢谢 啊sir
pta java 开发语言 算法
L2-023图着色问题时间限制300ms内存限制64MB题目描述:图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。输入格式:输入在第一行给出3个整数V(00){TreeSettr=newTreeSet()
图着色 java_L2-023 图着色问题 (25分)(java)
weixin_39928099
图着色问题是一个著名的NP完全问题。给定无向图,,问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。输入格式:输入在第一行给出3个整数V(0)、E(≥)和K(0),分别是无向图的顶点数、边数、以及颜色数。顶点和颜色都从1到V编号。随后E行,每行给出一条边的两个端点的编
Java中的受检异常
weixin_34132768
java runtime
Java中的受检异常Java提供了三种异常类型,受检异常(checkedexception)、运行时异常(runtimeexception)、错误(error)。那么这受检异常在实际开发中又有什么最佳实践呢?受检异常如果抛出的异常是可恢复的,同时我们也期望API的调用者捕获异常进行恢复处理,那么我们应该使用受检异常。受检异常会强迫API的使用者截获异常并恢复处理,或者进行声明继续抛出。图1.IDE
Java- 受检的异常(checked Exception)
七印miss
JAVA学习之旅 exception 异常 class java
受检的异常Exception分为两种RuntimeException及其子类,可以不明确处理,例如边界异常,解析整型时格式异常。否则,称为受检的异常(checkedException),更好的保护安全性受检的异常,要求明确进行语法处理要么捕获(catch)要么抛出(throw):在方法的签名后面用throwsxxx来声明在子类中,如果要覆盖父类的一个方法,若父类中的方法声明了throws异常,则子
Java受检异常和非受检异常
tiepiche
Effective Java Java基础
1.异常分类Java中所有异常都是java.lang.Throwable的子类,其两个直接子类为Error和Exception。Error错误,JVM内部的严重问题,比如资源不足等。无法恢复。它属于非受检异常(uncheckedexception)。如java.lang.StackOverflowError、java.lang.OutOfMemoryError、java.lang.NoSuchMe
数据库语句
lrydnh
数据库
//双击数据库useworld;//显示数据库里有多少张表showtables;一个大的项目就是数据库。SQL语句createschemaDataDefinitionLanguage:数据定义语言(DDL)查看创建和删除数据库:showdatabases;createdatabaseWorker;dropdatabaseWorker;增删改表tableshowtables;createtablet
提高你的Java代码质量吧:受检异常尽可能转化为非受检异常
iteye_7514
java
一、分析“把所有受检查异常(CheckedException)都转化为非受检查异常(UnCheckedException)”这一想法是不现实的。受检查异常是正常逻辑的一种补偿处理手段,特别是对可靠性要求比较高的系统来说,在某些条件下必须抛出首检异常以便由程序进行补偿处理,也就说受检异常又合理的存在理由,那为什么需要把受检异常转化为非受检异常?受检异常确实有不足的地方:1.受检异常使接口声明脆弱例如
Java中的异常处理机制是什么?
奔赴架构师的小白
java python 开发语言
引言在软件开发中,异常处理是确保程序健壮性和用户友好性的关键组成部分。Java作为一种广泛使用的编程语言,提供了丰富且强大的异常处理机制,使得开发者能够有效地处理程序运行时可能出现的各种错误情况。本文将深入探讨Java中的异常处理机制,包括其基本概念、使用方法、最佳实践以及高级主题,帮助读者全面掌握Java异常处理的核心知识。什么是异常处理?异常处理是一种编程技术,用于检测和处理程序运行期间发生的
受检异常(Checked Exception)
SAFE20242034
服务器
2.受检异常(CheckedException)(续)(1)IOException描述:IOException是Java中常见的受检异常,表示在进行输入/输出操作(例如文件操作、网络通信)时发生了错误。常见子类:FileNotFoundException:文件未找到。EOFException:文件意外结束。示例代码:importjava.io.*;publicclassIOExceptionExa
MySQL探秘之旅:总体架构介绍
互联网全栈架构
mysql 架构 数据库
欢迎关注微信公众号:互联网全栈架构自从《吃透Redis系列》阅读量屡创新高之后,更加坚定了创作技术系列文章的决心,从而让朋友们获得更加体系化的知识。当然,这是一件非常不容易的事情,让每篇文章都能单独成篇且质量上乘,同时,把它们连起来以后又能构成一个体系,着实困难。但不管如何,我觉得这样的方向和做法没有问题,应该会受到大家的欢迎,那就迎难而上。上次做了一个统计,相对来说,大家对于MySQL的文章比较
Go语言 vs Java语言:核心差异与适用场景解析
By北阳
golang java 开发语言
在当今的软件开发领域,Go(Golang)和Java都是备受关注的后端开发语言。尽管二者都能构建高性能服务,但它们在设计哲学、语法特性和应用场景上存在显著差异。本文将从多个维度对比这两种语言,帮助开发者更好地理解它们的优缺点,并为技术选型提供参考。一、设计哲学与语言定位1.Go语言定位:专为高并发、分布式系统设计,强调简洁性和高效性。特点:语法简单,学习曲线平缓。静态编译为单一二进制文件,部署便捷
超详细:数据库的基本架构
m0_74824661
面试 学习路线 阿里巴巴 数据库 架构
MySQL基础架构下面这个图是我给出的一个MySQL基础架构图,可以清楚的了解到SQL语句在MySQL的各个模块进行执行过程。然后MySQL可以分为两个部分,一个是server层,另一个是存储引擎。server层Server层涵盖了MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等)。所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。Server层主
L2-023 图着色问题(Java)
Loongnoy
Java题解 算法
题目链接:PTA|程序设计类实验辅助教学平台图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。输入格式:输入在第一行给出3个整数V(0set=newHashSet0){int[]arr=newint[v+1
Java 异常架构受检异常与非受检异常
Flying_Fish_Xuan
java 架构 开发语言
一、Java异常处理机制概述Java的异常处理机制是通过Throwable类及其子类实现的。Throwable是Java中所有异常和错误的超类,它有两个直接子类:Error:表示应用程序无法处理的严重错误,通常与JVM本身的状态相关,如内存溢出、栈溢出等。Error通常不应由应用程序捕获或处理。Exception:表示应用程序可以处理的异常情况,包括由程序错误或外部条件引发的问题。Exceptio
Java语言前言
始终奔跑在路上
软件开发 Java java 开发语言
字节计算机中存储数据最小计量单位,用byte或者B表示计算机最小的存储单元是二进制,因为计算机上能看到的任何东西都是CPU通过二进制转换而来的,二进制用bit表示1byte=8bit取值范围:-128-127存储数据的计量单位换算8bit=1B1024B=1KB1024KB=1MB1024MB=1GB1024GB=1TB常用DOS命令打开dos窗口win+R输入cmd切换磁D:查看目录dir创建目
MYSQL8.0数据库误删除记录恢复 MYSQL8.0数据库崩溃恢复 MYSQL8.0数据库删除表恢复
caihuayuan5
面试题汇总与解析 大数据 spring boot java 后端 课程设计
数据类型MYSQL8.0数据大小242MB故障检测主机断电导致数据库崩溃,无法启动.修复结果收到文件后,修正不一致的地方,成功启动MYSQL8.0完成恢复客户验收数据成功。完成恢复。最新数据得以恢复.客户非常满意。友情提醒:重要数据一定要勤备份,遇到数据丢失数据损坏等问题,要第一时间联系专业人士。对于各类主流数据库,我们可以做最底层的数据恢复及数据修复,对于数据库的某些特定故障我们保证数据库100
线程池相关面试题
玛丽莲萌
java
一、什么是线程池?线程池是用来管理和复用线程的工具,他可以减少线程的创建和销毁开销。在java中,ThreadPoolExecutor是线程池的核心实现,它通过核心线程数、最大线程数、任务队列和拒绝策略来控制线程的创建和执行。举个例子:就像你开了一家餐厅,线程池就相当于固定数量的服务员,顾客(任务)来了就安排空闲的服务员(线程)处理,避免了频繁招人和解雇的成本。二、线程池的工作原理任务提交----
Maven的继承和聚合
百香果果ccc
Maven maven hive java
Maven继承指的是,子项目继承父级Maven项目的配置信息(pom.xml)在父级pom.xml中,使用标签包裹的依赖,将会无条件传递给子级,与依赖范围无关com.alibabadruid1.2.8org.junit.jupiterjunit-jupiter-api5.10.2testjavax.servletjavax.servlet-api3.1.0provided在父级pom.xml中,使
SpringBoot工程——自定义方法参数解析器(对带有自定义注解的参数进行处理)
阿饼240
spring boot java spring
1、首先自定义注解(Target指定注解的使用范围,只能用在方法参数上,Retention指定注解的生命周期,Documented表示该注解应该包含在Java文档中)@Target({ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceTokenToUser{}2.自定义方法参数解
JavaScript基础-创建对象的三种方式
難釋懷
javascript 开发语言
在JavaScript编程中,对象(Object)是构建复杂数据结构和实现面向对象编程的基础。了解如何有效地创建对象对于编写高效、可维护的代码至关重要。本文将介绍三种主要的创建对象的方式:对象字面量、构造函数模式以及Object.create()方法,并讨论它们的特点及适用场景。一、使用对象字面量1.简介对象字面量是最简单直接的创建对象的方法。它允许你以一种非常直观的方式定义属性和方法。示例:le
Python, Java 开发鱼类养殖大全APP
Geeker-2025
python java
开发一个“鱼类养殖大全APP”是一个非常有意义的项目,特别是对于水产养殖从业者、鱼类爱好者和研究人员来说。该APP可以帮助用户了解鱼类的养殖知识、疾病防治、饲料管理、水质监测等内容,并提供个性化的养殖建议。以下是开发该APP的详细思路和技术实现方案,分别针对Python和Java。---###**功能需求分析**1.**鱼类信息展示**:-提供常见鱼类的基本信息(如名称、图片、生活习性、适宜水温、
一篇文章让你实现前端JS 、 Golang 、 Python如何接入DeepSeek大模型实现自己的AI
一只理智恩
AI 前端 后端 python golang javascript
本文将通过三种技术栈实现与DeepSeek大模型的对话交互,提供可直接运行的代码示例及详细注释。一、通用准备步骤1.获取API密钥登录DeepSeek开发者平台创建应用获取DEEPSEEK_API_KEY2.创建测试环境#项目结构deepseek-demo/├──frontend/#前端代码│└──index.html├──go-backend/#Golang后端│└──main.go├──py-
LeetCode[位运算] - #137 Single Number II
Cwind
java Algorithm LeetCode 题解 位运算
原题链接:#137 Single Number II
要求:
给定一个整型数组,其中除了一个元素之外,每个元素都出现三次。找出这个元素
注意:算法的时间复杂度应为O(n),最好不使用额外的内存空间
难度:中等
分析:
与#136类似,都是考察位运算。不过出现两次的可以使用异或运算的特性 n XOR n = 0, n XOR 0 = n,即某一
《JavaScript语言精粹》笔记
aijuans
JavaScript
0、JavaScript的简单数据类型包括数字、字符创、布尔值(true/false)、null和undefined值,其它值都是对象。
1、JavaScript只有一个数字类型,它在内部被表示为64位的浮点数。没有分离出整数,所以1和1.0的值相同。
2、NaN是一个数值,表示一个不能产生正常结果的运算结果。NaN不等于任何值,包括它本身。可以用函数isNaN(number)检测NaN,但是
你应该更新的Java知识之常用程序库
Kai_Ge
java
在很多人眼中,Java 已经是一门垂垂老矣的语言,但并不妨碍 Java 世界依然在前进。如果你曾离开 Java,云游于其它世界,或是每日只在遗留代码中挣扎,或许是时候抬起头,看看老 Java 中的新东西。
Guava
Guava[gwɑ:və],一句话,只要你做Java项目,就应该用Guava(Github)。
guava 是 Google 出品的一套 Java 核心库,在我看来,它甚至应该
HttpClient
120153216
httpclient
/**
* 可以传对象的请求转发,对象已流形式放入HTTP中
*/
public static Object doPost(Map<String,Object> parmMap,String url)
{
Object object = null;
HttpClient hc = new HttpClient();
String fullURL
Django model字段类型清单
2002wmj
django
Django 通过 models 实现数据库的创建、修改、删除等操作,本文为模型中一般常用的类型的清单,便于查询和使用: AutoField:一个自动递增的整型字段,添加记录时它会自动增长。你通常不需要直接使用这个字段;如果你不指定主键的话,系统会自动添加一个主键字段到你的model。(参阅自动主键字段) BooleanField:布尔字段,管理工具里会自动将其描述为checkbox。 Cha
在SQLSERVER中查找消耗CPU最多的SQL
357029540
SQL Server
返回消耗CPU数目最多的10条语句
SELECT TOP 10
total_worker_time/execution_count AS avg_cpu_cost, plan_handle,
execution_count,
(SELECT SUBSTRING(text, statement_start_of
Myeclipse项目无法部署,Undefined exploded archive location
7454103
eclipse MyEclipse
做个备忘!
错误信息为:
Undefined exploded archive location
原因:
在工程转移过程中,导致工程的配置文件出错;
解决方法:
 
GMT时间格式转换
adminjun
GMT 时间转换
普通的时间转换问题我这里就不再罗嗦了,我想大家应该都会那种低级的转换问题吧,现在我向大家总结一下如何转换GMT时间格式,这种格式的转换方法网上还不是很多,所以有必要总结一下,也算给有需要的朋友一个小小的帮助啦。
1、可以使用
SimpleDateFormat SimpleDateFormat
EEE-三位星期
d-天
MMM-月
yyyy-四位年
Oracle数据库新装连接串问题
aijuans
oracle数据库
割接新装了数据库,客户端登陆无问题,apache/cgi-bin程序有问题,sqlnet.log日志如下:
Fatal NI connect error 12170.
VERSION INFORMATION: TNS for Linux: Version 10.2.0.4.0 - Product
回顾java数组复制
ayaoxinchao
java 数组
在写这篇文章之前,也看了一些别人写的,基本上都是大同小异。文章是对java数组复制基础知识的回顾,算是作为学习笔记,供以后自己翻阅。首先,简单想一下这个问题:为什么要复制数组?我的个人理解:在我们在利用一个数组时,在每一次使用,我们都希望它的值是初始值。这时我们就要对数组进行复制,以达到原始数组值的安全性。java数组复制大致分为3种方式:①for循环方式 ②clone方式 ③arrayCopy方
java web会话监听并使用spring注入
bewithme
Java Web
在java web应用中,当你想在建立会话或移除会话时,让系统做某些事情,比如说,统计在线用户,每当有用户登录时,或退出时,那么可以用下面这个监听器来监听。
import java.util.ArrayList;
import java.ut
NoSQL数据库之Redis数据库管理(Redis的常用命令及高级应用)
bijian1013
redis 数据库 NoSQL
一 .Redis常用命令
Redis提供了丰富的命令对数据库和各种数据库类型进行操作,这些命令可以在Linux终端使用。
a.键值相关命令
b.服务器相关命令
1.键值相关命令
&
java枚举序列化问题
bingyingao
java 枚举 序列化
对象在网络中传输离不开序列化和反序列化。而如果序列化的对象中有枚举值就要特别注意一些发布兼容问题:
1.加一个枚举值
新机器代码读分布式缓存中老对象,没有问题,不会抛异常。
老机器代码读分布式缓存中新对像,反序列化会中断,所以在所有机器发布完成之前要避免出现新对象,或者提前让老机器拥有新增枚举的jar。
2.删一个枚举值
新机器代码读分布式缓存中老对象,反序列
【Spark七十八】Spark Kyro序列化
bit1129
spark
当使用SparkContext的saveAsObjectFile方法将对象序列化到文件,以及通过objectFile方法将对象从文件反序列出来的时候,Spark默认使用Java的序列化以及反序列化机制,通常情况下,这种序列化机制是很低效的,Spark支持使用Kyro作为对象的序列化和反序列化机制,序列化的速度比java更快,但是使用Kyro时要注意,Kyro目前还是有些bug。
Spark
Hybridizing OO and Functional Design
bookjovi
erlang haskell
推荐博文:
Tell Above, and Ask Below - Hybridizing OO and Functional Design
文章中把OO和FP讲的深入透彻,里面把smalltalk和haskell作为典型的两种编程范式代表语言,此点本人极为同意,smalltalk可以说是最能体现OO设计的面向对象语言,smalltalk的作者Alan kay也是OO的最早先驱,
Java-Collections Framework学习与总结-HashMap
BrokenDreams
Collections
开发中常常会用到这样一种数据结构,根据一个关键字,找到所需的信息。这个过程有点像查字典,拿到一个key,去字典表中查找对应的value。Java1.0版本提供了这样的类java.util.Dictionary(抽象类),基本上支持字典表的操作。后来引入了Map接口,更好的描述的这种数据结构。
&nb
读《研磨设计模式》-代码笔记-职责链模式-Chain Of Responsibility
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
/**
* 业务逻辑:项目经理只能处理500以下的费用申请,部门经理是1000,总经理不设限。简单起见,只同意“Tom”的申请
* bylijinnan
*/
abstract class Handler {
/*
Android中启动外部程序
cherishLC
android
1、启动外部程序
引用自:
http://blog.csdn.net/linxcool/article/details/7692374
//方法一
Intent intent=new Intent();
//包名 包名+类名(全路径)
intent.setClassName("com.linxcool", "com.linxcool.PlaneActi
summary_keep_rate
coollyj
SUM
BEGIN
/*DECLARE minDate varchar(20) ;
DECLARE maxDate varchar(20) ;*/
DECLARE stkDate varchar(20) ;
DECLARE done int default -1;
/* 游标中 注册服务器地址 */
DE
hadoop hdfs 添加数据目录出错
daizj
hadoop hdfs 扩容
由于原来配置的hadoop data目录快要用满了,故准备修改配置文件增加数据目录,以便扩容,但由于疏忽,把core-site.xml, hdfs-site.xml配置文件dfs.datanode.data.dir 配置项增加了配置目录,但未创建实际目录,重启datanode服务时,报如下错误:
2014-11-18 08:51:39,128 WARN org.apache.hadoop.h
grep 目录级联查找
dongwei_6688
grep
在Mac或者Linux下使用grep进行文件内容查找时,如果给定的目标搜索路径是当前目录,那么它默认只搜索当前目录下的文件,而不会搜索其下面子目录中的文件内容,如果想级联搜索下级目录,需要使用一个“-r”参数:
grep -n -r "GET" .
上面的命令将会找出当前目录“.”及当前目录中所有下级目录
yii 修改模块使用的布局文件
dcj3sjt126com
yii layouts
方法一:yii模块默认使用系统当前的主题布局文件,如果在主配置文件中配置了主题比如: 'theme'=>'mythm', 那么yii的模块就使用 protected/themes/mythm/views/layouts 下的布局文件; 如果未配置主题,那么 yii的模块就使用 protected/views/layouts 下的布局文件, 总之默认不是使用自身目录 pr
设计模式之单例模式
come_for_dream
设计模式 单例模式 懒汉式饿汉式 双重检验锁失败 无序写入
今天该来的面试还没来,这个店估计不会来电话了,安静下来写写博客也不错,没事翻了翻小易哥的博客甚至与大牛们之间的差距,基础知识不扎实建起来的楼再高也只能是危楼罢了,陈下心回归基础把以前学过的东西总结一下。
*********************************
8、数组
豆豆咖啡
二维数组 数组 一维数组
一、概念
数组是同一种类型数据的集合。其实数组就是一个容器。
二、好处
可以自动给数组中的元素从0开始编号,方便操作这些元素
三、格式
//一维数组
1,元素类型[] 变量名 = new 元素类型[元素的个数]
int[] arr =
Decode Ways
hcx2013
decode
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given an encoded message containing digits, det
Spring4.1新特性——异步调度和事件机制的异常处理
jinnianshilongnian
spring 4.1
目录
Spring4.1新特性——综述
Spring4.1新特性——Spring核心部分及其他
Spring4.1新特性——Spring缓存框架增强
Spring4.1新特性——异步调用和事件机制的异常处理
Spring4.1新特性——数据库集成测试脚本初始化
Spring4.1新特性——Spring MVC增强
Spring4.1新特性——页面自动化测试框架Spring MVC T
squid3(高命中率)缓存服务器配置
liyonghui160com
系统:centos 5.x
需要的软件:squid-3.0.STABLE25.tar.gz
1.下载squid
wget http://www.squid-cache.org/Versions/v3/3.0/squid-3.0.STABLE25.tar.gz
tar zxf squid-3.0.STABLE25.tar.gz &&
避免Java应用中NullPointerException的技巧和最佳实践
pda158
java
1) 从已知的String对象中调用equals()和equalsIgnoreCase()方法,而非未知对象。 总是从已知的非空String对象中调用equals()方法。因为equals()方法是对称的,调用a.equals(b)和调用b.equals(a)是完全相同的,这也是为什么程序员对于对象a和b这么不上心。如果调用者是空指针,这种调用可能导致一个空指针异常
Object unk
如何在Swift语言中创建http请求
shoothao
http swift
概述:本文通过实例从同步和异步两种方式上回答了”如何在Swift语言中创建http请求“的问题。
如果你对Objective-C比较了解的话,对于如何创建http请求你一定驾轻就熟了,而新语言Swift与其相比只有语法上的区别。但是,对才接触到这个崭新平台的初学者来说,他们仍然想知道“如何在Swift语言中创建http请求?”。
在这里,我将作出一些建议来回答上述问题。常见的
Spring事务的传播方式
uule
spring事务
传播方式:
新建事务
required
required_new - 挂起当前
非事务方式运行
supports
&nbs