自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

保暖透气大裤衩LeoLee的博客

一个最底层java开发的博客

  • 博客(197)
  • 收藏
  • 关注

转载 Golang:线程模型,CSP,MPG

并发和并行并发和并行都是为了充分利用 CPU 多核计算资源所提出来的概念,相信我们或多或少都对二者的概念有所了解: 并发指的是在同一时间段内,多条指令在 CPU 上同时执行; 并行指的是在同一时刻内,多条指令在 CPU 上同时执行。 并发程序并不要求 CPU 具备多核计算的能力。在同一时间段内,多个线程会被分配一定的执行时间片,在 CPU 上被快速轮换执行。线程执行的时间片时间耗尽或者任务完成了,会被 CPU 调度换下,执行其他的线程任务。通过这样的方式,可以在宏观上模拟出多

2022-01-24 15:48:09 693

原创 Golang:struct定义与试用以及内存分析

概述Golang虽然具有OOP的特性,但是并没有类的概念,也没有继承关键字。提供了一个类似于类功能,但是又截然不同的概念:结构体struct。定义有四种定义方式:package mainimport "fmt"//struct定义type Person struct { Id int64 Name string Age int8}type Student struct { baseInfo Person ptr *int //指针 array

2021-10-16 15:26:48 775

原创 Golang:map的定义、操作、排序以及map切片

map概述golang中的引用类型。与其他语言中的map类型基本相似,都是k-v形式的,k不可重复,元素是无序的,并且支持扩容。基本语法var 变量名 map[keytype]valuetypekey可以是很多类型bool、数字、string、指针、channel,还可以是只包含前面几种类型的 接口、结构体、数组。但是!!!slice、map、function是不可以作为map的key,因为无法使用 == 判断key是否相等。value的类型就没有特别的要求声明m

2021-09-23 12:09:44 1271

原创 Golang:数组定义、初始化

概述golang中的数组与其他一些语言中的数组,不同点在于:golang中的数组是值类型,并非是基础数据类型,这一点很重要。 可以使用指针来对数组进行引用传递。 数组初始化之后,长度确定,每个元素的值为数组类型的默认值。 数组的地址与数组的第一个元素的地址一致。 除数组第一个元素外的其他元素的地址=前一个元素的地址+数组类型所占用的字节数,即数组中的元素地址是连续的。所以当我们使用print打印数组的时候,数组的第一个元素地址即可代表该数组的地址,根据第一个元素的地址,可以得出之后每一个

2021-09-15 16:33:34 5095

原创 Golang:切片的声明、初始化以及操作示例,详解、概括

Golang基础学习项目地址:https://github.com/LeoLeeWithWarmPants/golangStudyhttps://github.com/LeoLeeWithWarmPants/golangStudy概述slice本质上是一个数据结构(struct结构体)。 切片是数组的一个引用,即切片的底层是一个数组,所以切片是一个引用类型。 切片的长度是可以变化,由于其支持扩容(类似于Java的List),可以理解切片为一个“长度动态变化的数组”。 需要注

2021-09-15 13:03:35 1367

原创 Golang:错误的捕获、抛出错误、自定义错误

概述Golang中,程序的执行异常被称作为error,Java中称为exception。相应的,Golang中也会出现运行时error,也会需要捕捉错误、处理错误,乃至自定义错误满足开发的需求。运行时错误运行时错误,就是代码运行时无法预见的错误,类似于Java的RuntimeException及其子异常。简单的除以0的demo://产生运行时异常n1 := 1n2 := 0fmt.Printf("result=%d\n", n1/n2)捕捉错误使用defer+recove

2021-09-07 01:30:25 1655

原创 Golang:一个示例讲明白defer怎么用

package mainimport "fmt"func sum(n1 int, n2 int) int { defer fmt.Printf("defer: n1=%d\n", n1) defer fmt.Printf("defer: n2=%d\n", n2) n1 += 2 n2 += 2 res := n1 + n2 fmt.Printf("func sum res=%d\n", res) return res}func main() { res := sum(1, .

2021-09-04 00:48:25 124

原创 Golang:init函数与匿名函数介绍

Init函数init函数总是在main函数之前执行,通常在init函数中执行一些初始化操作。package mainimport "fmt"func init() { fmt.Println("func init executing...")}func main() { fmt.Println("func main executing...")}如果一个文件同时包含了全局变量、init函数、main函数,那么执行的顺序是:全局变量的定义 init函数 main函

2021-09-01 01:46:35 246

原创 Golang:函数定义、使用超详细总结

代码地址:https://github.com/LeoLeeWithWarmPants/golangStudy/tree/main/project9func测试类:package mainimport ( "fmt" u "golangStudyProject/project9func/utils" //如果包名过长,可以设置包的别名,如别名u代替utils)//需要注意的是,在golang中,基本数据类型和数组都是值传递,即函数内改变形参不影响函数外的基本数据类型和数组的值//g

2021-08-29 18:01:42 527

原创 Golang:代码执行流程控制

顺序控制与其他语言一样,都是从上到下执行的代码。分支控制if-else基本语法:var age int8age = 18//if的语法可以省略if age > 18 { fmt.Println("成年人")} else if age == 18 { fmt.Println("刚刚成年")} else { fmt.Println("未成年")}在条件判断语句中声明变量:if age2 := 20; age2 > 18 { fmt.Println(

2021-08-28 19:48:13 149

原创 Golang:基础知识

值类型和引用类型 值类型:基本数据类型(int、uint、float、bool、string)、数组以及结构体struct 变量直接存储值,内存通常在栈中分配(也有例外的情况,姑且先这么理解) 引用类型:指针pointer、切片slice、map、管道chan、interface等都是引用类型 变量存储的是一个地址,这个地址对应的内存空间才真正存储数据,内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间便成为了一个垃圾,需要由GC回收。 如下代码和图片为基本数据

2021-08-28 17:29:18 148

原创 Golang:指针以及内存布局

任何值类型,都有对应的指针类型,形式为 *[数据类型],比如int对应的指针类型为 *int,float64对应的指针类型为 *float64。值类型包括:基本数据类型、string、数组、结构体struct。都有对应的指针类型。直接看示例代码://基本数据类型的内存布局var i8 int8 = 10//i的内存地址fmt.Printf("i8的内存地址:%v,&i8的类型:%T\n", &i8, &i8)var ptr *int8 = &i8fmt

2021-08-22 20:26:39 274

原创 Golang:基本数据类型的转换

Golang与Java、C等其他语言不同,在不同的数据类型的变量之间赋值的时候,需要显式的转换,也就是说Golang中数据类型不能自动转换。不管是低精度到高精度,还是高精度到低精度,都需要显式的转换。基本语法表达式:T(v),T为数据类型,v是需要转换的为V类型的变量。示例var i8 int8 = 100var f32 float32 = float32(i8)fmt.Printf("f32=%f\n", f32)var i32 int32 = int32(i8)fmt.Prin

2021-08-22 00:56:56 289

原创 Golang:基本数据类型

如何查看数据类型以及数据占用字节大小查看数据类型a := 2 // 或者 var a = 2fmt.Printf("a data type:%T", a)查看数据占用字节数b := 2 // 或者 var b = 2fmt.Printf("a need %d bytes\n", unsafe.Sizeof(b))在实际编程中,如果能确定变量的取值范围,尽量的明确指定具体的类型,减小字节占用。整数类型有符号整数类型 有无符号 占用储存空间 取值范围.

2021-08-21 17:08:54 110

原创 Golang:变量的声明

Go的变量声明还是很灵活的,相比于Java来说有两个特点:玩法更多 能省则省package mainimport "fmt"//全局变量var n1 int = 1var n2 = 2//全局变量不可以使用n3 := 3方式省略var关键字//批量声明var ( n3 = 100 n4 = 200 str1 = "Leo Lee")//变量的使用func main() { //1.指定变量类型,声明变量后不赋值,变量将会使用默认值 var i int

2021-08-20 01:47:15 305

原创 我又开始学习Golang了

前言关于Golang,对我来说真的是一个很尴尬的事情,其实早些年就已经听说了Golang这个被大家称为“天然支持高并发”的新语言了,Golang的专栏我19就创建好了,再买了本书,买了一节网课,写了四五篇博客之后就不了了之了,就进入了两年职业生涯起伏不定的阶段。这个阶段发生了太多的事情,不管是生活还是工作哪个方面来看,回过头来看真的是一言难尽。之后就围绕老本行Java一直在学习,直到上个月初从上一家公司提出离职,上个月中无缝跳槽到现在的公司之后,我又规划了之后的学习内容(大数据、Golang),而Gol

2021-08-19 01:52:35 164

原创 Hadoop——基本概述,初步认识

参考资料:hadoop:hdfs架构及原理深入理解HDFS:Hadoop分布式文件系统Hadoop基本组成个版本hadoop组成 组件 1.X 2.X 3.X Common(辅助工具) √ √ √ HDFS(数据存储、分布式文件系统) √ √ √ Yarn(资源调度) √ √ MapReduce(数据计算处理) √ √ √ 可以看到2.X与3.X版本的Hadoop从组成上没有太大

2021-08-11 13:33:05 184

原创 分库分表的方式

垂直切分垂直分表将某张表中的字段,按照某种业务特征划分,将不同业务特征的字段放入同一张表中,将该表拆分为若干张表,就是垂直分表。从某种层面来看,这就是数据库表设计层面上的逻辑拆分。垂直分库将不同业务特征的表,按照业务特征进行划分,不同业务特征的表放入不同的数据库中。简单的来讲就是订单相关的表放入订单数据库,产品相关的表放入产品数据库中。水平切分水平切分是为了解决单表数据量过大的问题,将单表数据量过大的查询压力分散。水平分表将一张表中数据拆分为若干段,分别存入相同表结构

2021-06-23 15:15:31 146

原创 ElasticSearch Java客户端常用API使用(es的增查删改&聚合)附带项目git地址

项目构建随便创建一个Java工程即可

2021-06-08 22:13:55 606

原创 ElasticSearch条件查询、聚合、分页、mapping

get请求条件查询

2021-06-03 22:44:35 241

原创 ElasticSearch index&document基本操作,附带postman导出文件

创建index

2021-06-02 22:10:54 675 4

原创 zookeeper——监控命令详解

前言zookeeper的监控命令需要通过telnet或者nc工具向zookeeper服务进行提交如使用telnet工具:telnet 127.0.0.1 2181之后telnet工具连接zookeeper成功可以使用四字监控命令进行操作。在连接建立之后输入对应的命令后回车。在使用监控命令之前,需要修改zookeeper的配置文件,开启四字监控命令,否则会报错如下:nc命令使用方法自行搜索,使用什么工具与本文关系不大。开启监控命令修改zoo.cfg文件,在配置文件中加入如

2021-05-26 22:11:45 1820 7

原创 zookeeper——分布式锁的基本原理与基本实现(基于zookeeper自带Java客户端)

实现思路实现的分布式锁的最常见方式是使用redis分布式锁(redis分布式锁参考我的专栏——分布式锁),基本原理是在各个服务执行到临界区(造作共享资源的代码块)之前,去redis中尝试添加一个带有当前贡献资源标识的redis数据,如果redis中没有该键值,添加成功,代表加锁成功,如果redis中已经存在该键值,添加失败,则加锁失败。而zookeeper的原理就完全不一样了:首先,每个客户端会去某个指定的znode(一般情况,一类分布式锁都创建在某一个node path下)下创建临时有序节点,

2021-04-14 23:54:19 353 2

原创 zookeeper——权限控制ACL

概述ACL,全称:access control list,与linux系统对文件的权限控制类似,主要涵盖三个方面:权限模式(scheme):授权的策略 授权对象(id):anyone、ip地址 权限(permission)特点如下:zookeeper的权限控制是基于每个znode节点的,对每个节点设置权限 每个znode支持设置多种权限控制方案核多个权限 子节点不会继承父节点的权限,客户端无权访问某节点,但是可以访问它的子节点。授权模式world:默认授权模式,代表登录zooke

2021-04-10 14:47:32 409

原创 zookeeper——监听器watch

监听器watch注册的监听器能够在某个节点发生变化后,向客户端发出通知,需要注意的是该监听器是一次性的,即触发一次后失效。3.7版本get [-s] [-w] path3.6版本之前get path watchzookeeper监听器的常见使用场景就是作为配置中心,当zookeeper中的某个数据节点发生变化之后,马上通知客户端读取最新的配置。get命令示例打开一个会话,向某个节点添加监听器开启另一个会话,修改此节点修改之后,设置监听器的会话将会收到一条节点变化的

2021-04-07 22:48:06 190

原创 zookeeper——节点操作

概述zookeeper的数据节点可以视为是树状结构,树中的各个节点被称之为znode,一个znode可以拥有多个节点,使用节点的路径来定位某个znode。znode兼具文件和目录两种身份,既能像文件一样维护着数据、元信息、ACL、时间戳等数据,又可以像目录已经作为路径的标识的一部分。znode的组成部分节点的数据:节点path,以及对应的节点数据。 节点的子节点children 节点的状态state:用来描述当前节点的创建、修改记录、包括cZxid、ctime等 cZxid:数据节

2021-04-06 22:14:42 1016

原创 Java多线程——BlockingQueue特点总结

概述最初接触BlockingQueue肯定是通过Java的线程池ThreadPoolExecutor的,在使用Executors创建四种线程池的时候,默认帮我制定了使用的BlockingQueue,如下: public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

2021-03-31 17:42:22 392

原创 Mybatis原理——执行原理详解

概述JDBC的执行流程可以大致分为:获得连接 预编译sql 设置参数 执行sqlMybatis执行原理大致分为:动态代理MapperProxy sql会话Sqlsession 执行器Executor JDBC处理器StatementHandler图中JDBC圈起来的部分就对应了sql具体的执行过程,属于Mybatis执行器范围内。本文主要针对sql会话与执行器来展开讨论。Mybatis的执行过程Mybatis使用门面模式提供了统一的门面接口API:基本的AP.

2021-03-24 18:05:11 1982 2

原创 Java自带线程池ThreadPoolExecutor

概述

2021-03-22 17:41:12 298

原创 JDK8HashMap原理分析&源码保姆式详解

基本概念HashMap是一个数组+链表的散列表,数组的每个元素存储了链表的第一个头节点 当链表存储节点长度超过8并且整个结构中的元素超过64个之后,链表开始树化,变成红黑树 红黑树的引入是为了解决链表过程造成的查找以及插入性能损失,红黑树是一个自平衡的二叉查找树,效率较高 数组的长度是2的次方 数组的扩容可以缓解链表查找纵深过高造成性能损失HashMap插入元素基本过程获取key的hash值 hash值经过扰动算法使存放的数据更为散列 构造出承载key和value的Node节点

2021-03-14 21:49:20 142 1

原创 JDK8中ConCurrentHashMap源码详解,以及原理

初始化ConcurrentHashMap<String, Object> cMap = new ConcurrentHashMap<>();默认的构造方法中是空方法,数组的长度默认是16,在第一次put操作的时候进行数组的初始化。/** * Creates a new, empty map with the default initial table size (16). */public ConcurrentHashMap() {}但是在实际的使用中,如

2021-03-13 19:31:46 354

原创 Java多线程——读写锁ReentrantReadWriteLock

概述ReentrantReadWriteLock,是一种读写锁,对读写操作的多线程访问提供了特殊处理,可以提高读取操作的性能,让读并发,写加锁。读操作可并发 读写操作互斥 写操作互斥其原理与ReentrantLock基本一直,只不过加入了读写锁的逻辑,底层也是使用了AQS同步器,AQS的源码解析可查阅我的另一篇文章:Java多线程——JUC之AQS(AbstractQueuedSynchronizer)分析,ReentrantLock的实现原理解析基本使用package com.le

2021-03-07 18:07:45 183

原创 Java多线程——JUC之AQS(AbstractQueuedSynchronizer)分析,ReentrantLock的实现原理解析

概述AQS是用来构建锁或者其他同步器组件的重要基础框架,是JUC体系的基石。通过内置的FIFO(先进先出队列,CLH队列,是一个单向链表,AQS的队列是CLH的一个变体,虚拟的双向FIFO)队列来完成资源获取线程的排队工作,并通过一个int类型的变量表示持有锁的状态。ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore等底层都是存在一个内部类继承了AbstractQueuedSynchronizer,为这些具体的并发工具提供了一种排队

2021-03-06 21:40:53 246

原创 Java多线程——ForkJoin初步认识及基本使用

概述也是刚接触ForkJoin,简单记录一下,纯属初体验。Fork/Join是JDK1.7加入的新的线程池实现,其体现的是一种分治思想,适用于能够进行任务拆分的CPU密集型运算(默认创建与CPU核心数相同大小的线程池,由于是CPU密集型运算,线程池大小超过CPU核心数没有什么意义)。Fork/Join在分治的基础上加入了多线程,可以把每个任务分解和合并交给不同的线程来完成,进一步的提高运算效率。示例这是一个计算1-n之间所有整数相加的demo,总体来说所谓的分治思想,类似于递归,将1-n

2021-03-03 22:24:27 357 1

原创 Java多线程——线程池的饥饿现象

概述定长线程池的使用过程中会存在饥饿现象,也就是当多线程情况下,当池中所有线程都被占用后,被占用的线程又需要空闲线程去进行下一步的操作,此时又获取不到池中空闲的线程,此时就出现了饥饿现象。示例package com.leolee.multithreadProgramming.threadPool.threadHungry;import lombok.extern.slf4j.Slf4j;import java.util.Arrays;import java.util.List;im

2021-03-03 17:20:18 1193 1

原创 Java多线程——JUC之CountDownLatch、CyclicBarrier与Semaphore

CountDownLatch是JUC下提供的一个计数器,其通过计数递减的方式控制线程的执行顺序。package com.leolee.multithreadProgramming.juc.countDownLatch;import java.util.concurrent.CountDownLatch;/** * @ClassName CountDownLatchTest * @Description: TODO * @Author LeoLee * @Date 2021/3/2 *

2021-03-02 15:07:26 143

原创 Java多线程——使用CAS实现自旋锁

使用JUC的原子引用类的CAS特性实现自旋锁直接上代码package com.leolee.multithreadProgramming.test.spinLock;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicReference;/** * @ClassName SpinLockTest * @Description: 自定义自旋锁 * @Author LeoLee *

2021-03-01 21:36:47 222

原创 CopyOnWriteArrayList解决多线程安全问题原理

CopyOnWriteArrayList部分源码/** * Replaces the element at the specified position in this list with the * specified element. * * @throws IndexOutOfBoundsException {@inheritDoc} */ public E set(int index, E element) { fina

2021-03-01 15:44:50 273 3

原创 Java多线程——JUC Atomic CAS的缺点

概述本文不讨论Atomic原子操作的底层原理与实现,仅针对其缺点进行讨论QaQ。缺点Atomic原子操作类实质上是一个CAS操作的实现,Atomic类的缺点实质上是CAS的缺点:由于Atomic类CAS的实现中,存在do while的循环操作,在最恶劣的情况下,当前线程始终无法对比成功【预期值】,将会进行大量的循环,增加CPU的负荷,以getAndIncrement为例public final int getAndAddInt(Object var1, long var2, int va

2021-03-01 14:12:54 293

原创 Java多线程——自定义线程池

概述上图是一个线程池的示意图,基本分为线程池和任务等待队列两部分。

2021-02-26 11:36:58 200 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除