Install Docker Engine on CentOS

To get started with Docker Engine on CentOS, make sure you meet the prerequisites, then install Docker. Prerequisites OS requirements To install Docker Engine, you need a maintained version of CentOS 7 or 8. Archived versions aren’t supported or tested. The centos-extras repository must be enabled. This repository is enabled by default, but if you have disabled it, you need to re-enable it. The overlay2 storage driver is recommended. Uninstall old versions Older versions of Docker were called docker or docker-engine. If these are installed, uninstall them, along with associated dependencies.

  It’s OK if yum reports that none […]

龙生   25 May 2021
View Details

什么是雪花ID?

为什么使用雪花ID 在以前的项目中,最常见的两种主键类型是自增Id和UUID,在比较这两种ID之前首先要搞明白一个问题,就是为什么主键有序比无序查询效率要快,因为自增Id和UUID之间最大的不同点就在于有序性。 我们都知道,当我们定义了主键时,数据库会选择表的主键作为聚集索引(B+Tree),mysql 在底层是以数据页为单位来存储数据的。 也就是说如果主键为自增 id 的话,mysql 在写满一个数据页的时候,直接申请另一个新数据页接着写就可以了。如果一个数据页存满了,mysql 就会去申请一个新的数据页来存储数据。如果主键是UUID,为了确保索引有序,mysql 就需要将每次插入的数据都放到合适的位置上。这就造成了页分裂,这个大量移动数据的过程是会严重影响插入效率的。 一句话总结就是,InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的。 但是为什么很多情况又不用自增id作为主键呢? 容易导致主键重复。比如导入旧数据时,线上又有新的数据新增,这时就有可能在导入时发生主键重复的异常。为了避免导入数据时出现主键重复的情况,要选择在应用停业后导入旧数据,导入完成后再启动应用。显然这样会造成不必要的麻烦。而UUID作为主键就不用担心这种情况。 不利于数据库的扩展。当采用自增id时,分库分表也会有主键重复的问题。UUID则不用担心这种问题。 那么问题就来了,自增id会担心主键重复,UUID不能保证有序性,有没有一种ID既是有序的,又是唯一的呢? 当然有,就是雪花ID。 什么是雪花ID snowflake是Twitter开源的分布式ID生成算法,结果是64bit的Long类型的ID,有着全局唯一和有序递增的特点。 最高位是符号位,因为生成的 ID 总是正数,始终为0,不可用。 41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。 10位的机器标识,10位的长度最多支持部署1024个节点。 12位的计数序列号,序列号即一系列的自增ID,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。 缺点也是有的,就是强依赖机器时钟,如果机器上时钟回拨,有可能会导致主键重复的问题。 Java实现雪花ID 下面是用Java实现雪花ID的代码,供大家参考一下。

main方法,测试结果如下:

总结 在大部分公司的开发项目中里,雪花ID是主流的ID生成策略,除了自己实现之外,目前市场上也有很多开源的实现,比如: 美团开源的Leaf 百度开源的UidGenerator 有兴趣的可以自行观摩一下,那么这篇文章就写到这里了,感谢大家的阅读。 作者:java技术爱好者 链接:https://juejin.cn/post/6965510420387856398 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

龙生   25 May 2021
View Details

java 各种数据类型的互相转换

StringBuilder转化为String

整型数组转化为字符串

字符串转化为整形数组

字符串转化为字符数组

字符数组转化为字符串

字符数组转化为整型数组

整型数组转化为字符数组

整型数转化为字符串

字符串转化为整型数

  java类型转换 Integer String Long Float Double Date 1如何将字串 String 转换成整数 int? A. 有两个方法:

2 如何将整数 int 转换成字串 String ? A. 有叁种方法:

JAVA中常用数据类型转换函数 虽然都能在JAVA API中找到,整理一下做个备份。

数据类型 基本类型有以下四种:   int长度数据类型有:byte(8bits)、short(16bits)、int(32bits)、long(64bits)、 float长度数据类型有:单精度(32bits float)、双精度(64bits double) boolean类型变量的取值有:ture、false char数据类型有:unicode字符,16位 对应的类类型:Integer、Float、Boolean、Character、Double、Short、Byte、Long 转换原则 从低精度向高精度转换 byte 、short、int、long、float、double、char 注:两个char型运算时,自动转换为int型;当char与别的类型运算时,也会先自动转换为int型的,再做其它类型的自动转换 基本类型向类类型转换 正向转换:通过类包装器来new出一个新的类类型的变量 Integer a= new Integer(2); 反向转换:通过类包装器来转换 int b=a.intValue(); 类类型向字符串转换 正向转换:因为每个类都是object类的子类,而所有的object类都有一个toString()函数,所以通过toString()函数来转换即可 反向转换:通过类包装器new出一个新的类类型的变量 eg1: int i=Integer.valueOf(“123”).intValue() 说明:上例是将一个字符串转化成一个Integer对象,然后再调用这个对象的intValue()方法返回其对应的int数值。 eg2: float f=Float.valueOf(“123”).floatValue() 说明:上例是将一个字符串转化成一个Float对象,然后再调用这个对象的floatValue()方法返回其对应的float数值。 eg3: boolean b=Boolean.valueOf(“123”).booleanValue() 说明:上例是将一个字符串转化成一个Boolean对象,然后再调用这个对象的booleanValue()方法返回其对应的boolean数值。 eg4:double d=Double.valueOf(“123”).doublue() […]

龙生   25 May 2021
View Details

java类型转换常见的错误

类型转换虽然很简单,但是还是有些小细节要多注意。 String转化为int:

  String转化为Integer,可以如下所示。 也适用于int转化为Integer:

  注意:不管是使用Integer.parseInt(),还是使用Integer.valueOf()将字符串转换成数字, 如果是非数字的字符串,会报错:NumberFormatException: For input string: "" 另外,Integer类取值和 int 类型取值一致,取值范围是从-2147483648 至 2147483647(-231至 231-1) ,包括-2147483648 和 2147483647。 如果超过了这个范围,也会报错。比如Integer.valueOf("2147483648"),超过了Integer范围。因此会报错: For input string: "2147483648" 更安全的做法是,使用apache包的NumberUtils,如下: 注意:NumberUtils只处理整数,不能用来处理小数。

  String转BigDecimal:

  String转double :

  Double转化为int:

  其他类型转String:

  注意:当String.valueOf()的参数obj为null时,返回值是字符串"null"!!而不是null。 如果希望obj为null时,返回"",可以使用apache-commons-lang的包,如下所示:

  如果希望obj为null时,返回null,如下: ObjectUtils.toString(object,nullStr),第二参数nullStr表示,当object为null时,方法返回的值。

  Integer转double: 使用doubleValue()方法,或者 (double)强制转换。

  其他类型转Double:

  比较小数是否相等。 比较Double是否相等。比较BigDecimal是否相等。 如下所示:

  比较Double类型的大小:

  比较double类型的大小: 除了用BigDemical的compare()方法,可以直接用Double.doubleToLongBits()的结果值用==,>,<进行比较

  from:https://www.cnblogs.com/expiator/p/12602446.html

龙生   25 May 2021
View Details

一个Asp.Net项目,不能编辑并继续,总提示引用的其他项目版本不允许变更

如题,公司的一个项目。 原因:由于未知的原因,被引用项目的GUID和引用的GUID不一致引起的这个问题。 解决:重新引用也无效,那只有手动编辑项目文件了~

龙生   20 May 2021
View Details

MySQL 函数

MySQL 有很多内置的函数,以下列出了这些函数的说明。 MySQL 字符串函数 函数 实例 ASCII(s)  返回字符串 s 的第一个字符的 ASCII 码。 返回 CustomerName 字段第一个字母的 ASCII 码:

CHAR_LENGTH(s)  返回字符串 s 的字符数 返回字符串 RUNOOB 的字符数

CHARACTER_LENGTH(s) 返回字符串 s 的字符数 返回字符串 RUNOOB 的字符数

CONCAT(s1,s2…sn)  字符串 s1,s2 等多个字符串合并为一个字符串 合并多个字符串

CONCAT_WS(x, s1,s2…sn) 同 CONCAT(s1,s2,…) 函数,但是每个字符串之间要加上 x,x 可以是分隔符 合并多个字符串,并添加分隔符:

FIELD(s,s1,s2…)  返回第一个字符串 s 在字符串列表(s1,s2…)中的位置 返回字符串 c 在列表值中的位置:

FIND_IN_SET(s1,s2)  返回在字符串s2中与s1匹配的字符串的位置 返回字符串 c 在指定字符串中的位置:

FORMAT(x,n)  函数可以将数字 x 进行格式化 "#,###.##", 将 x 保留到小数点后 n 位,最后一位四舍五入。 格式化数字 "#,###.##" 形式:

INSERT(s1,x,len,s2)  字符串 s2 替换 s1 的 x 位置开始长度为 len 的字符串 从字符串第一个位置开始的 […]

龙生   19 May 2021
View Details

Java并发编程:volatile关键字解析

volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。 volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用volatile关键字的场景。 以下是本文的目录大纲: 一.内存模型的相关概念 二.并发编程中的三个概念 三.Java内存模型 四..深入剖析volatile关键字 五.使用volatile关键字的场景 若有不正之处请多多谅解,并欢迎批评指正。 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/dolphin0520/p/3920373.html 一.内存模型的相关概念 大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。 也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。举个简单的例子,比如下面的这段代码: 1 i = i + 1; 当线程执行这个语句时,会先从主存当中读取i的值,然后复制一份到高速缓存当中,然后CPU执行指令对i进行加1操作,然后将数据写入高速缓存,最后将高速缓存中i最新的值刷新到主存当中。 这个代码在单线程中运行是没有任何问题的,但是在多线程中运行就会有问题了。在多核CPU中,每条线程可能运行于不同的CPU中,因此每个线程运行时有自己的高速缓存(对单核CPU来说,其实也会出现这种问题,只不过是以线程调度的形式来分别执行的)。本文我们以多核CPU为例。 比如同时有2个线程执行这段代码,假如初始时i的值为0,那么我们希望两个线程执行完之后i的值变为2。但是事实会是这样吗? 可能存在下面一种情况:初始时,两个线程分别读取i的值存入各自所在的CPU的高速缓存当中,然后线程1进行加1操作,然后把i的最新值1写入到内存。此时线程2的高速缓存当中i的值还是0,进行加1操作之后,i的值为1,然后线程2把i的值写入内存。 最终结果i的值是1,而不是2。这就是著名的缓存一致性问题。通常称这种被多个线程访问的变量为共享变量。 也就是说,如果一个变量在多个CPU中都存在缓存(一般在多线程编程时才会出现),那么就可能存在缓存不一致的问题。 为了解决缓存不一致性问题,通常来说有以下2种解决方法: 1)通过在总线加LOCK#锁的方式 2)通过缓存一致性协议 这2种方式都是硬件层面上提供的方式。 在早期的CPU当中,是通过在总线上加LOCK#锁的形式来解决缓存不一致的问题。因为CPU和其他部件进行通信都是通过总线来进行的,如果对总线加LOCK#锁的话,也就是说阻塞了其他CPU对其他部件访问(如内存),从而使得只能有一个CPU能使用这个变量的内存。比如上面例子中 如果一个线程在执行 i = i +1,如果在执行这段代码的过程中,在总线上发出了LCOK#锁的信号,那么只有等待这段代码完全执行完毕之后,其他CPU才能从变量i所在的内存读取变量,然后进行相应的操作。这样就解决了缓存不一致的问题。 但是上面的方式会有一个问题,由于在锁住总线期间,其他CPU无法访问内存,导致效率低下。 所以就出现了缓存一致性协议。最出名的就是Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。 二.并发编程中的三个概念 在并发编程中,我们通常会遇到以下三个问题:原子性问题,可见性问题,有序性问题。我们先看具体看一下这三个概念: 1.原子性 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 一个很经典的例子就是银行账户转账问题: 比如从账户A向账户B转1000元,那么必然包括2个操作:从账户A减去1000元,往账户B加上1000元。 试想一下,如果这2个操作不具备原子性,会造成什么样的后果。假如从账户A减去1000元之后,操作突然中止。然后又从B取出了500元,取出500元之后,再执行 往账户B加上1000元 的操作。这样就会导致账户A虽然减去了1000元,但是账户B没有收到这个转过来的1000元。 所以这2个操作必须要具备原子性才能保证不出现一些意外的问题。 同样地反映到并发编程中会出现什么结果呢? 举个最简单的例子,大家想一下假如为一个32位的变量赋值过程不具备原子性的话,会发生什么后果? 1 i = 9; 假若一个线程执行到这个语句时,我暂且假设为一个32位的变量赋值包括两个过程:为低16位赋值,为高16位赋值。 那么就可能发生一种情况:当将低16位数值写入之后,突然被中断,而此时又有一个线程去读取i的值,那么读取到的就是错误的数据。 2.可见性 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 举个简单的例子,看下面这段代码: 1 2 3 4 5 6 //线程1执行的代码 int i = 0; i = 10; //线程2执行的代码 j = i; 假若执行线程1的是CPU1,执行线程2的是CPU2。由上面的分析可知,当线程1执行 i =10这句时,会先把i的初始值加载到CPU1的高速缓存中,然后赋值为10,那么在CPU1的高速缓存当中i的值变为10了,却没有立即写入到主存当中。 此时线程2执行 j = i,它会先去主存读取i的值并加载到CPU2的缓存当中,注意此时内存当中i的值还是0,那么就会使得j的值为0,而不是10. 这就是可见性问题,线程1对变量i修改了之后,线程2没有立即看到线程1修改的值。 3.有序性 有序性:即程序执行的顺序按照代码的先后顺序执行。举个简单的例子,看下面这段代码: 1 2 […]

龙生   19 May 2021
View Details

ps怎么抠头发丝,ps头发丝抠图技巧

在PS里打开要抠出头发丝的照片后,按下CTRl+J键复制一下该图像,再在该图像上按CTRL+L打开色阶,把对比度调明显些。 接着点击通道面板,点击一个黑白对比最分明的一个通道,拖动它到复制图层的图标上,复制出一个通道,再在该通道上进行反相。 反相后,再在该通道上打开色阶,把对比度再调明显点,调的时候,可适当拖动中间那个滑块,以让头发丝的边缘更清晰。 这时,图像的背景色基本上应为纯黑色,然后点击画笔选纯白色,把非边缘部位,全涂成纯白色。 接着,在按下CTRL键后,点击一下复制出的当前通道,以生成选区,再点击RGB那个通道层。 然后点击图层面板,回到最开始按CTRL+J复制出的那个图像图层上,如下图所示。 再在该图层上按一次CTRL+J键,这样就把整个要抠出的头发丝部位,复制出来了;如有需要,可点移去白色杂边把头发丝边缘的颜色再净化一下,然后就可以在下面加上任意底色的图层了。   https://jingyan.baidu.com/article/1876c8525a323c890b137618.html

龙生   19 May 2021
View Details

解决git bash here 启动慢的问题

在安装完git之后,每次通过右键启动git 命令行总是很慢 这个原因是因为用了 AMD显卡 !! 解决方法如下:

    from:https://blog.csdn.net/lxp_mocheng/article/details/106273392

龙生   18 May 2021
View Details

Web 开发者应该避免的 5 个 CSS 的做法

原文地址:5 CSS Practices To Avoid as a Web Developer 原文作者:Alexey Shepelev 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:霜羽 Hoarfroster 校对者:KimYang、Chorer 有人认为 CSS 很难学习,觉得 CSS 有很多的坑,甚至还有一点儿魔幻,难以理解,很容易会搬起石头砸自己的脚。对此我感到难过,毕竟,我可不这么认为。 在考虑了可以做什么之后,我提出了五个我挺讨厌的 CSS 的做法,希望帮助大家避免这些习惯。 1. 设置内外边距,然后将其重置 我经常看到人们为所有元素设置内外边距,然后为第一个元素或者最后一个元素清除刚刚写的边距。我不知道为什么你非要在一条规则就可以解决问题的情况下写两条规则。一次为所有必需的元素设置边距明显容易得多! 为简化 CSS,你可以选用以下几种选择器:nth-child 或 nth-of-type 选择器,还有 :not() 伪类或相邻元素组合器(即 +)。 不要这么写:

你可以这么写:

  或这样写:

或者用:

  2. 为 position 为 fixed 或 absolute 的元素添加 display:block 你知道吗?其实你无需为 position 为 fixed 或 absolute 的元素添加 display:block,因为这是默认发生的。 另外,如果你在这些元素上使用 inline-* 值,它们将按以下方式更改: inline、inline-block -> block inline-flex -> flex inline-grid -> grid inline-table -> table 因此,对于 position 为 fixed 或 absolute 的元素,你只需在要使用 flex 布局或者 grid 布局的时候设置 […]

龙生   18 May 2021
View Details
1 87 88 89 411