- 博客(50)
- 收藏
- 关注
原创 程序员的自我修养——远离“外包思维”
在我们做开发的日子里,不免会进行跳槽,跳来跳去公司无非就分成两大类——互联网公司、外包公司。当然我们本次讨论的并不是外包公司,而是一些外包公司所培养出来的“外包思维”。什么是 “外包思维”呢?简单来说,就是由多年外包经历所影响,逐渐总结出来的一些工作经验。事实上并不是所有的工作经验都对大家有帮助,有些工作经验反而只会坑到你。那么下面我们来看看有哪些常见的“外包思维”吧。技术是为业务服务的单看这句话其实说的并没有毛病,但是不少程序员却对这句话进行了曲解。每个技术的出现都有它的适用场景,比如MongoD
2021-04-12 21:15:24
1092
转载 Java位运算
Java提供的位运算符有:左移( << )、右移( >> ) 、无符号右移( >>> ) 、位与( & ) 、位或( | )、位非( ~ )、位异或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符。1、左移( << )Test1、将5左移2位: package com.xcy; public class Test { public static void main(String[] ar
2021-03-27 22:27:22
209
原创 酷帅狂拽吊炸天——一统江湖的持久层框架之SpringData
一、SpringData概述1.1 现有问题 随着互联网的发展,互联网产品的复杂度越来越高,在开发中使用到的数据存储产品不再仅限于关系型数据库,还会使用到Redis、MongoDB、Elasticsearch、Solr等不同应用场景的数据库系统。而这些数据库产品,在Java中也都提供了优秀的访问技术,如Mybatis、Jedis等等。这些技术虽然对相应的数据库提供很便捷的操作方式,但是由于不同的持久层技术的api是不一样的,开发人员就必须同时掌握多种数据访问技术,增加了学习和开发成本。 那么,
2021-03-08 17:31:42
521
原创 数据结构与算法——B+树
B+树 ☆☆☆☆☆B+树是对B树的一种变形树,它与B树的差异在于:非叶结点仅具有索引作用,也就是说,非叶子结点只存储key,不存储value;树的所有叶结点构成一个有序链表,可以按照key排序的次序遍历全部数据。1 B+树存储数据若参数M选择为3,那么每个结点最多包含2个键值对,我们以3阶B+树为例,看看B+树的数据存储插入 C N G A H E K Q 数据为例2 B树和B+树对比B+ 树的优点在于:1.由于B+树在非叶子结点上不包含真正的数据,只当做索引使用,因此在内存相同的
2021-03-04 21:44:08
433
3
原创 数据结构与算法——B树
B-树☆☆☆☆前面我们已经学习了二叉查找树、2-3树以及它的实现红黑树。2-3树中,一个结点做多能有两个key,它的实现红 黑树中使用对链接染色的方式去表达这两个key。接下来我们学习另外一种树型结构B树,这种数据结构中,一个结点允许多于两个key的存在。B树是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(logn)的时间复杂度进行查找、顺序读取、插入和删除等操作。1 定义用阶定义B树B树中允许一个结点中包含多个key,可以是3个、4个、5个甚至更多,并不确定,需要看具体的实现。现在我
2021-03-04 21:42:57
488
1
原创 数据结构与算法——红黑树
红黑树(面试必问)☆☆☆☆我们前面介绍了2-3树,可以看到2-3树能保证在插入元素之后,树依然保持平衡状态,它的最坏情况下所有子结点 都是2-结点,树的高度为lgN,相比于我们普通的二叉查找树,最坏情况下树的高度为N,确实保证了最坏情况下的 时间复杂度,但是2-3树实现起来过于复杂,所以我们介绍一种2-3树思想的简单实现:红黑树。红黑树主要是对2-3树进行编码,红黑树背后的基本思想是用标准的二叉查找树(完全由2-结点构成)和一些额外的信 息(替换3-结点)来表示2-3树。我们将树中的链接分为两种类型:
2021-03-04 21:41:48
304
1
原创 数据结构与算法——平衡树
平衡树之前我们学习过二叉查找树,发现它的查询效率比单纯的链表和数组的查询效率要高很多,大部分情况下,确实是 这样的,但不幸的是,在最坏情况下,二叉查找树的性能还是很糟糕。 例如我们依次往二叉查找树中插入9,8,7,6,5,4,3,2,1这9个数据,那么最终构造出来的树是长得下面这个样子:我们会发现,如果我们要查找1这个元素,查找的效率依旧会很低。效率低的原因在于这个树并不平衡,全部是向 左边分支,如果我们有一种方法,能够不受插入数据的影响,让生成的树都像完全二叉树那样,那么即使在最坏情 况下,查找的效
2021-03-04 21:40:31
367
1
原创 GET和POST请求到底有什么区别?
看到这个标题,想必大部分人都已经想关掉这篇博客了。先别急,你真的知道这两个的区别吗?做过WEB开发的朋友可能很熟悉,看到这个问题能立马脱口而出二者的区别。GET在浏览器回退时是无害的,而POST会再次提交请求。GET产生的URL地址可以被Bookmark,而POST不可以。GET请求会被浏览器主动cache,而POST不会,除非手动设置。GET请求只能进行url编码,而POST支持多种编码方式。GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。GET请求在URL中传
2020-09-30 14:50:00
337
原创 数据结构与算法——二叉树、堆、优先队列
七、树7.1 树7.1.1 树的定义树是我们计算机中非常重要的一种数据结构,同时使用树这种数据结构,可以描述现实生活中的很多事物,例如族谱、单位的组织架构、等等。树是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树树具有以下特点:每个结点有零个或多个子结点;没有父结点的结点为根结点;每一个非根结点只有一个父结点;每个结点及其后代结点整体上可以看做是一棵树,称为当前结点的父结点的一个子树;7.1.2 树的相关术语结点的度:一个
2020-09-24 15:40:12
397
原创 Java版数据结构与算法——线性表
五、线性表线性表是最基本、最简单、也是最常用的一种数据结构。一个线性表是n个具有相同特性的数据元素的有限序列前驱元素: 若A元素在B元素的前面,则称A为B的前驱元素后继元素: 若B元素在A元素的后面,则称B为A的后继元素线性表的特征:第一个数据元素没有前驱,这个数据元素被称为头结点;最后一个数据元素没有后继,这个数据元素被称为尾结点;除了第一个和最后一个数据元素外,其他数据元素有且仅有一个前驱和一个后继。如果把线性表用数学语言来定义,则可以表示为(a1,…ai-1,ai,ai+1,…an
2020-08-13 15:55:25
378
原创 JDK8那些惊为天人的新特性
介绍随着java的发展,越来越多的企业开始使用 java8 版本。Java8 是自 java5之后最重要的版本,这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。本次课程将着重学习其中的一些重点特性。Jdk8新增的特性如下:Lambda表达式类似于ES6中的箭头函数 新的日期APIDatetime 引入Optional防止空指针异常 使用Base64 接口的默认方法和静态方法 新增方法引用格式 新增Stream类 注解相关的改变 支持并行(parallel)数...
2020-05-27 23:57:09
706
原创 Mybatis源码阅读(五 ):接口层——SqlSession
SqlSessionSqlSession是Mybatis的核心接口之一,对外提供常用的数据库操作api。mybatis提供了两个SqlSession的实现,其中最常用的是DefaultSqlSession。SqlSession的代码如下/** * 接口层,也是开发人员使用mybatis去操作sql所使用的主要的接口 * * @author Clinton Begin */public interface SqlSession extends Closeable { /**
2020-05-13 19:32:25
482
1
原创 Mybatis源码阅读(四):核心接口4.2——Executor(下)
SimpleExecutor接上一章博客继续。SImpleExecutor继承了BaseExecutor类,是最简单的Executor实现。Executor使用了模板方法模式,所以SimpleExecutor不必在关心一级缓存等操作,只需要实现基本的4个方法。首先看doQuery /** * 执行查询操作 * @param ms * @para...
2020-04-27 21:07:10
393
原创 Mybatis源码阅读(四):核心接口4.2——Executor(上)
ExecutorExecutor是Mybatis的核心接口之一,其中定义了数据库操作的基本方法。在实际应用中涉及的SqlSession的操作都是基于Executor实现的。Executor代码如下。/** * Mybatis的核心接口,定义了操作数据库的方法 * SqlSession接口的功能都是基于Executor实现的 * @author Clinton Begin */p...
2020-04-16 17:42:12
286
1
原创 Java只使用位运算实现加减乘除
前言接前面一篇博客,这又是某个公司的奇葩面试题(都说了到底是哪家公司才会出这种没营养的面试题)。不过吐槽归吐槽,这个题目还是有点学问的,比前面那个不使用比较运算符如何比较两个数的大小 强多了(但是还是能看出面试官是在存心刁难人)。原题是“只给加法,如何实现减乘除”,我寻思着,既然减乘除都不给了,那就加大点难度,加法也别给了吧,今天就手动去实现加减乘除。这里只实现int类型的加减乘除。...
2020-04-11 10:03:04
1352
7
原创 Java非阻塞异步编程——CompletableFuture
前言对于Node开发者来说,非阻塞异步编程是他们引以为傲的地方。而在JDK8中,也引入了非阻塞异步编程的概念。所谓非阻塞异步编程,就是一种不需要等待返回结果的多线程的回调方法的封装。使用非阻塞异步编程,可以很大程度上解决高并发场景的各种问题,提高程序的运行效率。为什么要使用非阻塞异步编程在jdk8之前,我们使用java的多线程编程,一般是通过Runnable中的run方法进行的。这种方...
2020-04-10 12:49:38
2539
4
原创 不使用比较运算符如何比较两个数的大小
前言今天在水群的过程中看到有位群员谈论到这个话题,是他找工作过程中某家公司的面试题(到底是哪家公司才会出这种没营养的题目刁难别人),有点兴趣,就开始写了。开搞想了一下,其实就是题目怪了一点,难度其实并不高。这个题目让我想起了前两年看到的题目,只给你加法,怎么计算加减乘除(都说了到底是哪家公司才会出这种没营养的题目)。相比起来,这题好歹是考了计算机中的加法器,而本文主题中谈论的题目则真的...
2020-04-09 14:31:56
3769
2
原创 Flutter、ReactNative、uniapp对比
前言最近对App开发比较感兴趣,因原生学习起来成本可能较大,就把目光转向了大前端的跨端开发技术。说到跨端开发,那么选择空间就是Flutter、RN、uniapp这几个了。flutter最近比较热闹,毕竟是谷歌出品。但我们不是炒作热点的媒体,也不是忽悠你交学费的培训机构,我们作为实际的跨平台开发者,冷静的分析下这个东东。flutter是Google为Fuchsia操作系统设计的应用开发方...
2020-03-26 14:33:59
18895
5
原创 Mybatis源码阅读(四):核心接口4.1——StatementHandler
前言难得复工了,公司百业待兴,有一大堆接口需要对接,忙的不行。回过神来发现自己快一个月没写博客了,赶紧抽时间写一写,不能断更。截止上一篇博客,我们已经把结果集映射的内容介绍完毕,接下来就是对Mybatis中的核心接口进行介绍,通过介绍这些核心接口,使读者们更深刻地理解Mybatis的运行机制以及原理。StatementHandlerStatementHandler接口是Mybati...
2020-03-26 13:25:25
323
1
原创 Mybatis源码阅读(三):结果集映射3.3 —— 主键生成策略
前言在前面两篇博客中,我们介绍了对于select语句的简单映射和嵌套映射。mybatis中使用ResultHandler等一系列的类,将查询结果封装到实体类中,可以说是mybatis中最复杂的过程,而剩下的insert、update、delete语句的操作则显得较为简单,没有复杂的映射逻辑。这里需要提的是在insert语句中,关于主键自增的问题。KeyGenerator在我们实际的开发...
2020-03-03 18:00:05
1713
原创 前两天看到的段子。
一个测试工程师走进一家酒吧,要了一杯啤酒;一个测试工程师走进一家酒吧,要了一杯咖啡;一个测试工程师走进一家酒吧,要了0.7杯啤酒;一个测试工程师走进一家酒吧,要了-1杯啤酒;一个测试工程师走进一家酒吧,要了2^32杯啤酒;一个测试工程师走进一家酒吧,要了一杯洗脚水;一个测试工程师走进一家酒吧,要了一杯蜥蜴;一个测试工程师走进一家酒吧,要了一份asdfQwer@24dg!&*(@;一个测试...
2020-02-27 18:40:59
355
1
原创 Mybatis源码阅读(三):结果集映射3.2 —— 嵌套映射
前言这段时间疫情原因躺在家做咸鱼,代码也没怎么敲,源码也没怎么看,博客拖更了一个月,今天心血来潮继续读了点源码,晚上正好抽空发个博客,证明我还活着。关于结果集映射,在一个月前的博客中已经将简单映射给讲述完毕,在实际应用中,除了单表查询以外,还可能通过连表查询多张表的记录,这些记录需要映射成多个java对象,而对象之间存在一对一、一对多等复杂的关联关系,这时候就需要嵌套映射。handle...
2020-02-18 20:15:48
509
原创 程序员到底要不要重复造轮子?
关于这个话题,现在这里阐述立场:就公司工作而言,不建议重复造轮子。就个人技术而言,强烈建议造轮子!程序员圈子里流行这么一句话:“不要重复造轮子”。它的原文是:“Stop Trying to Reinvent the Wheel”,意思是“不要重复发明轮子”。首先我们要搞清楚两个概念 —— 造轮子和发明轮子。轮子是在距今6800年前被发明出来,在此之前我们的祖先可能已经就在尝试对轮子的创造。...
2020-01-19 22:14:51
3973
2
原创 Mybatis源码阅读(三):结果集映射3.1 —— ResultSetBuilder与简单映射
前言在前面的文章中,已经介绍了三种SqlSource的代码,下面开始介绍执行select语句对查询结果集封装的过程。ResultSetHandler前面的文章中得知,mybatis会将结果集按照映射配置文件中定义的映射规则,如resultMap节点,映射成相应的结果对象。在StatementHandler接口执行完指定的select语句后,会将查询结果集交给ResultSetHan...
2020-01-16 16:39:20
408
原创 varchar字段长度最好是2的n次方-1
计算机是二进制计算的,1 bytes = 8 bit ,一个字节最多可以代表的数据长度是2的8次方 11111111 在计算机中也就是-128到127。而varchar类型存储变长字段的字符类型,当存储的字符串长度小于255字节时,其需要1字节的空间,当大于255字节时,需要2字节的空间。使用2 ^ n长度是更好的磁盘或内存块对齐。对齐块更快。今天“块”的大小更大,内存和磁盘足够快,可以忽...
2020-01-10 18:55:45
4164
3
原创 Mybatis源码阅读(二):动态节点解析2.2 —— SqlSourceBuilder与三种SqlSource
SqlSourceBuilder前面我们对SqlSource和SqlNode进行了介绍,在经过SqlNode.apply方法的解析之后,Sql语句会被传递到SqlSourceBuilder中进行进一步的解析。SqlSourceBuilder主要完成了两方面的操作,一方面是解析Sql中的#{}占位符定义的属性,如jdbcType、javaType(使用较少),一方面是把#{}占位符替换成?占位符...
2020-01-06 09:51:59
545
3
原创 String s = new String(123) 究竟创建了几个对象
前言今天上班划水的过程中有人询问到这个问题,网上对于这个问题也有争议,有说创建了一个对象,有说两个,有说三个。首先说三个的肯定是扯淡了,今天来讨论一下这条语句到底创建了几个对象。在进入正题之前,先回顾一下几个基础知识。常量池常量池是为了避免对对象的重复创建和销毁而影响系统性能,从而实现对象共享。在编译期就能确定的字符串,会被存放到常量池中,如String s = "123";。...
2020-01-02 14:40:48
1986
原创 count(1),count(*),count(主键) 性能对比及辟谣
前言前段时间关于统计数量的sql问题和朋友进行了讨论,网上关于这三种查询方式说法不一,主要有以下两种说法。count(*) = count(主键) > count(1) count(主键) > count(*) > count(1)今天对这三种方式进行探究。数据库为mysql 5.7.12,引擎为InnoDB。建表CREATE TABLE `user` ...
2019-12-29 22:43:45
1710
原创 Mybatis源码阅读(二):动态节点解析2.1 —— SqlSource和SqlNode
前言前面的文章介绍了mybatis核心配置文件和mapper文件的解析,之后因为加班比较重,加上个人也比较懒,一拖就是将近半个月,今天抽空开始第二部分的阅读。由前面的文章可知,mapper文件中定义的Sql节点会被解析成MappedStatement,其中的SQL语句会被解析成SqlSource。而Sql语句中定义的动态sql节点(如if节点、foreach节点)会被解析成SqlNode。...
2019-12-29 22:09:46
1058
2
原创 Mybatis源码阅读(一):Mybatis初始化1.3 —— 解析sql片段和sql节点
前言接上一篇博客,解析核心配置文件的流程还剩两块。Mybatis初始化1.2 —— 解析别名、插件、对象工厂、反射工具箱、环境本想着只是两个模块,随便写写就完事,没想到内容还不少,加上最近几天事情比较多,就没怎么更新,几天抽空编写剩下两块代码。解析sql片段sql节点配置在Mapper.xml文件中,用于配置一些常用的sql片段。 /** * 解析sql节点。...
2019-12-16 20:52:23
366
原创 Mybatis源码阅读(一):Mybatis初始化1.2 —— 解析别名、插件、对象工厂、反射工具箱、环境
接上一节 上一节:解析properties和settings解析typeAliasestypeAliases节点用于配置别名。别名在mapper中使用resultType时会使用到,是对实体类的简写。别名有两种配置方式通过package,直接扫描指定包下所有的类,注册别名 通过typeAliase,指定某个类为其注册别名别名注册代码如下 /** * 解析t...
2019-12-11 22:39:56
457
原创 Mybatis源码阅读(一):Mybatis初始化1.1 解析properties、settings
前言笔者大概是从今年的5月份开始喜欢上源码阅读的,起初是阅读徐郡明前辈的《Mybatis技术内幕》入的坑,不得不说大佬就是大佬,书中讲得东西很细很全。半年过去了,笔者对mybatis略知一二,也开始在为公司搭架构,并且基于Mybatis写了一套框架,但是尽管如此还是感觉自己对于源码的理解稍微有点浅。好比是初高中学数学吧,光看例题不做题是记不住的,因此产生了为mybatis写注释的想法,想要通过...
2019-12-09 22:17:16
276
原创 Java中序列化是如何破坏单例模式的
单例设计模式单例设计模式的核心思想是,程序运行中只允许某个类只有一个实例单例设计模式序列化破坏单例模式首先写一个单例的类public class Student implements Serializable { private static Student student; private Student() { } public st...
2019-12-06 10:04:41
339
原创 注解版poi操作工具
最近在搭公司新项目的架构,测试的过程中深感导出Excel极为不便,因此就产生了写一个通用导出工具类的想法。写完后经测试发现比较好用,因此将公司相关的代码移除,单独拿出来这个模块进行开源。项目的GitHub地址:POI操作工具如果您对本工具比较感兴趣,可以加入下面QQ群进行技术交流:781943947使用方式:创建数据库(这个操作就不贴代码了)导入工程下db目录的数据库创建类...
2019-12-01 17:08:58
1300
原创 JDK8新特性
函数式编程面向对象强调“一切皆对象”,如果想要做事情,必须要找到对象来做。函数式编程思想强调“做什么”,而不是“怎么做”普通的开启线程// 匿名内部类对象Runnable task = new Runnable() { @Override public void run() { System.out.println("乌鸦坐飞机"); }}...
2019-11-25 18:46:34
627
2
原创 JVM内存调优参数
-XmsJVM启动时申请的初始Heap值,默认为操作系统物理内存的1/64但小于1G。默认当空余堆内存大于70%时,JVM会减小heap的大小到-Xms指定的大小,可通过-XX:MaxHeapFreeRation=来指定这个比列。Server端JVM最好将-Xms和-Xmx设为相同值,避免每次垃圾回收完成后JVM重新分配内存;开发测试机JVM可以保留默认值。-XmxJVM可申请的最大H...
2019-11-20 19:19:33
1092
原创 新生代与老年代
Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。其中新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。堆的内...
2019-11-17 21:17:49
829
1
转载 Kafka、ActiveMQ、RabbitMQ及RocketMQ区别
https://blog.csdn.net/luoyang_java/article/details/93625832
2019-11-15 19:45:19
154
原创 垃圾回收算法
标记清除算法概念该算法有两个阶段。1. 标记阶段:找到所有可访问的对象,做个标记。2. 清除阶段:遍历堆,把未被标记的对象回收缺点:会产生碎片,不够连贯应用场景该算法一般应用于老年代,因为老年代的对象生命周期比较长。优缺点标记清除算法的优点和缺点1. 优点- 是可以解决循环引用的问题- 必要时才回收(内存不足时)2. 缺点:- 回收时,应用需...
2019-11-15 19:42:32
150
原创 Java内存结构
据 JVM 规范,JVM 内存结构共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。这里的java内存结构与前面所述的Java内存模型是两个概念,不可以混淆。堆java堆是java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配(从这...
2019-11-08 21:26:14
188
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人