自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(153)
  • 收藏
  • 关注

原创 递归的本质

递归并没有那么神秘,这篇文章就带你解开递归的神秘面纱

2022-08-08 09:58:11 754 1

原创 PageHelper 分页查询「实现篇」

两种情况分两种情况:查出来为 PageQueryRespDTO查出来直接是 Model查出来为 PageQueryRespDTOpublic PageInfo<PageQueryRespDTO> queryPageList(PageQueryReqDTO dto) { PageHelper.startPage(dto.getPageNum(), dto.getPageSize()); List<PageQueryRespDTO> resul

2021-12-16 11:13:36 1329

原创 PageHelper 分页查询「原理篇」

pagehelper简介PageHelper方法分页原理PageHelper方法使用了静态的ThreadLocal参数,分页参数和线程是绑定的。内部流程是ThreadLocal中设置了分页参数(pageIndex,pageSize),之后在查询执行的时候,获取当前线程中的分页参数,执行查询的时候通过拦截器在sql语句中添加分页参数,之后实现分页查询,查询结束后在 finally 语句中清除ThreadLocal中的查询参数。通俗地讲,就是PageHelper.startPage(int page

2021-12-16 11:12:09 9342

原创 Lombok 注解及实例大全

Project Lombok是一个java库,它可以自动插入到编辑器和构建工具中,为Java增添趣味。 永远不要再编写另一个getter或equals方法,只要有一个注释,你的类就有一个功能齐全的构建器,自动化你的日志变量,等等。val用在局部变量前面,相当于将变量声明为 finalval map = new HashMap<String, String>();// 相当于final Map<String, String> map = new HashMap<&g.

2021-12-07 17:38:10 1867

原创 AppID / OpenID / UnionID

首先来看一下微信官方的解释为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID,如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个UnionID,可以在用户管理-获取用户基本信息(UnionID机制)文档了解详情。AppID:一个AppID唯一对应一个小程序(或公众号),尽管一个AppID可以开发多个小程序(或

2021-11-28 21:57:47 1439

原创 谈谈对框架的理解

打个比方,开发一个Web应用,你可以使用Spring,也可以不用,框架的好处在于,在原生的Java语言之上提供了许多组件,其实,说白了,就是提供一系列的Java类,让我们可以直接使用,方便我们专注于业务逻辑,把一些脏活、累活交给框架来做,当然,框架的作用远不止这些。为什么需要框架?简化开发,通过适当的配置即可完成开发;规范开发程序,一个业务逻辑,如果没有框架,不同的人来实现,代码的差异会很大,有了框架,代码的差异性变小,便于维护;提供了更加优雅的实现方式。有些轮子我们也可以自己造,但是由于每个人能

2021-11-21 23:37:39 967 1

原创 谈谈DevOps

DevOps是一种软件开发理念、一种思想,而这个理念又可以通过不同的手段去实现,当下我们可以通过一些集成化办公软件去贯彻这个思想。如果没有这些软件,仍然可以去尽力去秉承这个理念,可以通过制定一些共享文档进行实现,只不过这种方式的局限性在于①比较笨重 ② 很难照顾到软件开发的整个生命周期。自动化软件的诞生可以实现数字化办公,将这一理念更好地贯彻下去。DevOps这个词,其实就是Development和Operations两个词的组合。它的英文发音是 /de’vɒps/,类似于“迪沃普斯”。DevOps是一

2021-11-21 23:14:59 3546

原创 谈谈Controller、Service和Dao

都是Java代码,为啥要区分Controller、Service和Dao,谈谈我的理解。当然,也可以不用区分,直接一条龙,从接受请求,到业务处理,再到数据库查询全写在一个类里,甚至全部在一个方法中完成,但是这样做,一是不利于代码的迭代,二是代码的结构不清晰。当然,早期的代码其实就是这样。总的来说,Controller 用于接收和响应;Service 用于处理业务逻辑,会调用DAO层的API;DAO是对应一张或多张表的,是持久层API,是针对单张或多张表的增删改查。为了更方便理解,首先介绍Cont.

2021-11-21 23:06:09 5783

原创 一个例子帮你理解 同步、异步、阻塞、非阻塞

概念同步/异步:需不需要主动获取,主动获取就是同步,被动通知才是异步。阻塞/非阻塞:去不去干其他的事,去干其他的事就是非阻塞,不去干其他的事就是阻塞。所以同步/异步和阻塞/非阻塞这是两个维度的问题。理论上,有四种搭配:同步阻塞同步非阻塞异步阻塞异步非阻塞一个生动的例子下面就通过一个生活中的例子来对标这四种情况,帮助更好地理解。比如,你去肯德基吃早餐,你可以选择在店里等着啥也不做,眼睛一直盯着屏幕(注意,眼睛一直盯着屏幕就是一个主动获取的行为),看服务员是否已经做好,然后主动去拿,在

2021-08-19 16:30:54 432

原创 Mac 配置支持NTFS写入操作

该方法通过Mac上修改配置文件,无需第三方软件。Mac Os 默认是不支持NTFS格式的磁盘写入操作的,就是你会发现,可以将磁盘中的文件拷贝到Mac上,但是无法将Mac上的文件拷贝到磁盘上,而且也无法对磁盘中的文件进行删除、重命名等写操作。网上查大多教程都是通过第三方软件实现让Mac支持对NTFS格式的磁盘的读写操作,比如NTFS助手之类的软件,但是我搜了一下,这些软甲大多是收费的,而且,还挺贵,公司规定又不能安装破解版软件,无奈之下只能看有没有其他解决办法。找了半天,还真有。就是通过修改Mac上.

2021-05-13 12:48:21 2368

原创 Mac 下如何解决 Docker.raw 占用空间较大

Docker.raw 文件为docker的逻辑磁盘的文件,属于预占用文件。这个大小是可以调整的。点击右上角齿轮⚙标志进入设置页面点击 Resourses -> ADVANCED调整 Disk image size 即可最后有个提醒:将大小调小将会删除磁盘镜像;所有的 Docker 镜像、容器和体积将会丢失。这个视情况而定,确定之后选择右边的 Yes, resize anyway...

2021-04-30 14:37:44 13266 1

原创 利用Python库matplotlib绘制小波能量谱

时间小波能量谱反映信号的小波能量沿时间轴的分布。由于小波变换具有等距效应,所以有:∫R∣f(t)∣2dx=Cψ−1∫R∫R∣WTf(a,b)∣2dadba2\int_{R}|f(t)|^{2}{\rm d}x=C^{-1}_{\psi}\int_{R}\int_{R}|WT_{f}(a,b)|^{2}\frac{{\rm d}a{\rm d}b}{a^2}∫R​∣f(t)∣2dx=Cψ−1​∫R​∫R​∣WTf​(a,b)∣2a2dadb​ ①式中 ∣WTf(a,b)∣2|WT_{f}(a,b

2021-04-13 23:22:01 3326 9

原创 TCP粘包 / 拆包

简介粘包 / 拆包问题是网络比较底层的问题,在数据链路层、网络层以及传输层都有可能发生。我们日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP协议中。什么是粘包 / 拆包?假设客户端向服务端连续发送了两个数据包,用packet1和packet2来表示,那么服务端收到的数据可以分为三种,现列举如下:第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象,此种情况不在本文的讨论范围内。#mermaid-svg-pSwiyjV

2021-03-21 11:17:48 125

原创 Java 高级特性——注解

简介Java注解(Annotation)又称 Java 标注,是JDK1.5 引入的一种注释机制。和 Javadoc(注释)不同,Java 标注可以通过反射获取标注内容。在编译期生成类文件时,标注可以被嵌入到字节码中。 JVM 可以保留注释内容,在运行时可以获取到注释内容。当然它也支持自定义Java注释。理解 Annotation 的关键,是理解 Annotation 的语法和用法;理解 Annotation 的语法和用法之后,再看 Annotation 的框架图,可能有更深刻的体会。注解的分类

2021-03-20 14:34:32 607

原创 一般 for 循环遍历和迭代器遍历 LinkedList 区别

先说区别:普通for循环:每次遍历一个索引的元素之前,都要访问之前所有的索引。每次访问一个元素后,都会用游标记录当前访问元素的位置,遍历一个元素,记录一个位置。普通 for 循环普通 for 循环遍历方式如下:LinkedList<String> linkedList = new LinkedList<>();linkedList.add("A");linkedList.add("B");linkedList.add("C");linkedList.ad

2021-03-19 17:03:57 2314

原创 Java集合源码解析之——ArrayList

简介ArrayList是实现 List 接口的实现类,内部是一个大小可变的数组。ArrayList 是一个用数组实现的集合,支持随机访问,元素有序且可以重复。ArrayList 的好处是可以不用限定容器的大小,它会根据元素的增加而扩容。但是存储进去的数据类型都会变成Object类型,虽然每个元素有自己的index,但不像数组的下标可以更加方便的操作。类定义ArrayList定义如下:public class ArrayList<E> extends AbstractList<E

2021-03-19 14:17:25 255

原创 设计模式之——装饰器模式

装饰器模式(Decorator Pattern)指在无须改变原有类及类的继承关系的情况下,动态扩展一个类的功能。它通过装饰器来包裹真实的对象,并动态地向对象添加或者撤销功能。装饰器模式包括 Source 和 Decorator 两种角色,Source 是被装饰者,Decorator 是装饰者。装饰器模式通过装饰器可以为被装饰者 Source 动态添加一些功能。定义Sourceable接口:public interface Sourceable { public void createCom

2021-03-14 17:27:08 132 2

原创 设计模式系列之——代理模式

代理模式指,通过代理的方式,为对象提供一种访问并控制该对象行为的方法。在客户端不适合或者不能够直接引用一个对象时,可以通过该对象的代理对象来实现对该对象的访问。可以将代理对象理解为客户端和目标对象之间的中介者。比如我们在买房时,通常会有这么几个过程:找房 -> 看房 -> 网签 -> 交易完成,当然真正的过程比这要复杂得多,所以通常会找房产经纪人(中介),这个房产经纪人就是代理,这样我们不需要自己去找房子以及考虑房子后续的签约过程,我们只需要把需求(想要什么样的房子)告诉代理人即可,

2021-03-14 17:20:50 100

原创 JVM系列——垃圾收集算法

JVM 的三种垃圾收集算法:标记-清除算法、标记-复制算法、标记整理算法、分代收集算法1. 标记-清除算法该算法分为“标记”和“清除”两个阶段:首先标记出所有不需要回收的对象,在标记完成后统一回收掉所有没有被标记的对象。它是最基础的收集算法,后续的算法都是对其不足进行改进得到。缺点:效率问题:当存活对象比较多时,那么就会耗费较多的时间去标记;当回收对象较多时,同样会耗费较多的时间去清除空间问题:标记清除后会产生大量不连续的碎片2. 标记-复制算法为了解决标记-清除算法面对大量可

2021-03-11 16:56:40 149

原创 Reactor 线程模型

线程模型不同的线程模型,对程序段的影响很大,先来看看各个线程模型。目前存在的线程模型有:传统阻塞I/O服务模型Reactor模型根据 Reactor 的数量和处理资源池线程的数量不同,有3种典型的实现:单Reactor-单线程单Reactor-多线程主从Reactor-多线程传统阻塞IO服务模型黄色框表示对象;蓝色框表示线程;灰色框表示方法(API)模型特点:采用阻塞IO模式获取输入的数据每个连接都需要独立的线程完成数据的输入、业务处理、数据返回问题分析:

2021-03-09 23:07:57 7721 3

原创 方法区、永久代、元空间的关系

方法区方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。永久代(PermGen)《Java 虚拟机规范》只是规定了有方法区这么个概念和它的作用,并没有规定如何去实现它。那么,在不同的 JVM 上方法区的实现肯定是不同的了。方法区和永久代的关系很像 Java 中接口和类的关系,

2021-03-09 21:09:45 526

原创 大学生/程序员必备技能——画图!

研究生 / 程序员 必备技能:画论文示意图 / 流程图画 UML分享几个最常用的画图的工具Window 版的 VisioMac 版的 OmniGraffle为什么画图是很有必要的呢?在写论文或者在做笔记的过程中,经常需要示意图帮助我们更好的理解知识点,一个简单明了的示意图降低我们的学习及理解成本,有时候语言无法明确表达的知识点,用一张图就可以瞬间领悟,这就是图的魅力。如何画图比较高级?根据我个人绘图习惯,说以下个人绘图的一些习惯(仅供参考)描边一般的填充图.

2021-03-07 23:12:43 1462 2

原创 MAC终端输入换行问题

问题描述当在Mac终端首行输入命令行过长时,会把第一行前面的信息覆盖,直到将第一行填满才会自动换行,如下图:问题分析找了好久才发现是之前配置终端格式的时候造成的,Mac原生的终端界面是这种:可以看到是支持换行的,只是后来为了美观,在配置文件.bash_profile里设置了一下就无法换行了。解决方法解决方法有两种:通过换行符,可以不用还原配置文件,但是以后使用比较麻烦,每次需要输入长命令时都需要先输入\重新配置 .bash_profile ,从根源解决问题,这样既能保证美观,又能换

2021-02-10 16:09:41 8310 5

原创 Jupyter Notebook在清华镜像下安装Nbextensions 插件

清华镜像下安装NbextensionsNbextensions 有很多好用的扩展功能,比如显示目录,显示程序执行时间(Execute Time),美化格式(Code prettify),代码折叠(Codefolding)等。但是直接安装比较慢,我们利用镜像安装。在终端执行:pip install jupyter_contrib_nbextensions -i https://pypi.tuna.tsinghua.edu.cn/simple/关闭 jupyter notebook,在终端运行ju

2021-02-10 15:50:06 3994 2

原创 SpringMVC的执行流程

执行流程用户发送请求至前端控制器 DispatcherServletDispatcherServlet 收到请求调用 HandlerMapping 处理器映射器处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServletDispatcherServlet 调用 HandlerAdapter 处理器适配器HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)C

2021-02-07 22:24:02 270

原创 LeetCode系列之「反转链表」

剑指 Offer 24. 反转链表ListNode// Definition for singly-linked list.public class ListNode { int val; ListNode next; ListNode(int x) { val = x; }}一、迭代解法:class Solution { public ListNode reverseList(ListNode head) { if(h

2021-01-24 16:50:02 235

原创 JavaOJ训练——输入一串以逗号隔开数字然后存入数组中并输出

代码:public class OJ { public static void main(String[] args){ Scanner sc = new Scanner(System.in); System.out.println("请输入一串用英文逗号隔开的整数:"); String input = sc.next(); String[] strArr = input.split(","); int[] nu

2021-01-23 21:22:56 2642 1

原创 MyBatis 中 #{} 和 ${} 区别

二者区别#{} 是预编译处理,传进来的数据会加个" "#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号${}就是字符串替换,直接替换掉占位符$方式一般用于传入数据库对象,例如传入表名SQL 注入使用 ${} 的话会导致 sql 注入。什么是 SQL 注入呢?比如 select * from user where id = ${value}value 应该是一个数值吧,然后如果对方传过来的是 001 and name = tom,这样就相当于多加了一个条件,把SQL语

2021-01-22 23:41:23 109

原创 SpringBoot + Mybatis + Thymeleaf 搭建个人博客——Iceberg-Blog

Iceberg-BlogWhy Iceberg Blog为什么叫 Iceberg Blog ?学无止境,无论何时,我们都会感到知识就像一座冰山,我们学到的只是冰山一角。博客简介项⽬描述:采⽤前后端分离架构实现的博客系统,主体架构采用 SpringBoot + Thymeleaf + MyBatis,基于Java环境采用 IntelliJ IDEA 开发,使用 Maven 工具构建。涉及技术:Spring Boot、MyBatis、Thymeleaf设计细节:整个项⽬分为登录、博客管理、.

2021-01-22 17:42:00 1524 6

原创 MacOS 终端导入/导出 sql 脚本

终端导入sql脚本比如导入一个mysql脚本文件casaba.sql,路径为/Users/superfarr/Desktop/casaba.sql如果脚本中有创建数据库的语句,我们就不需要再次创建,如果没有,我们需要自己创建下面的流程为针对脚本中没有创建数据库语句的教程终端输入:mysql -u root -p有密码的输入密码进入MySQL命令行之后CREATE DATABASE casaba;USE casaba;SOURCE 『将.sql文件直接拖拽至终端,自动补全其文件目

2021-01-21 23:34:30 688

原创 坚持看完保证你能深刻理解Java的反射机制

静态语言 & 动态语言在讲反射之前先来了解一下什么是静态语言和动态语言动态语言是一类在运行时可以改变其结构的语言,例如新的函数、对象、甚至代码都可以被引进,已有的函数可以被删除,或是其他结构上的变化, 通俗地讲就是在运行时代码可以根据某些条件改变自身结构。主要动态语言:Object-C、C#、JavaScript、PHP、Python等。静态语言与动态语言相对应,运行时结构不可变的语言是静态语言,如Java、C、C++。Java不是动态语言,但Java可以称之为“准动态语言”。

2020-12-25 00:57:03 267

原创 到底什么是 JavaBean

JavaBean其实就是特殊的Java类,是一种规范,也可称为一种技术。与其它 Java 类相比JavaBean需满足以下条件:必须提供无参构造方法类中属性都必须私有化(private)需要被序列化且实现 Serializable 接口可能有一系列 setter 或 getter 方法Sun 公司推出 jsp 技术后,同时也推荐了两种 web 应用程序的开发模式,一种是jsp + javabean 模式,一种是 Servlet + jsp + javabean 模式jsp + javab

2020-12-25 00:13:30 233

原创 Java泛型(包括泛型+反射的应用)

泛型简介Java 泛型(generics)是 JDK 5 中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说,所操作的数据类型被指定为一个参数。在创建对象或调用方法的时候才明确具体的类型。类型擦除正确理解泛型概念的首要前提是理解类型擦除。更多关于类型擦除的问题,可以查看这篇文章:《Java泛型类型擦除以及类型擦除带来的问题》什么是类型擦除?Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦

2020-12-25 00:02:45 366

原创 逃逸分析/栈上分配/标量替换/同步消除

逃逸分析前言我们知道:栈中存放一些基本类型的变量数据(int/short/long/byte/float/double/Boolean/char)和对象引用。堆中主要存放对象,即通过new关键字创建的对象。但是在《深入理解Java虚拟机》中关于Java堆内存有这样一段描述:随着JIT编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。在编译期间,JIT 会对代码做很多优化。其中有一部分优化的目的就是

2020-12-21 23:52:11 293

原创 超详细Redis系列之RDB & AOF机制

Redis 不同于 Memcached 的很重要一点就是,Redis 支持持久化,而且支持两种不同的持久化操作:快照(snapshotting,RDB)只追加文件(append-only file, AOF)前沿知识数据库在进行写操作时主要有下面五个过程:#mermaid-svg-rIKc7kiceMfcERDi .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);

2020-12-21 13:09:33 223

原创 LeetCode系列之「用队列实现栈」

225. 用队列实现栈总的来说有两种方法:用两个队列实现用一个队列实现方法一:用两个队列实现最好的方法就是让两个队列q1(入栈队列)和q2(出栈队列)分别充当入栈和出栈的角色,即:push 操作内部将元素添加到q1pop 从q2中poll元素q1和q2只是一个指针,在 push 内部利用一个临时变量来时刻交换q1和q2的指向,使得q1和q2分别指向的队列始终分别指向 入栈队列和 出栈队列。这样做的好处是,可以简化pop()与top()的实现,因为s2是出栈队列,所以只需要分别执

2020-12-04 15:38:43 229 1

原创 LetCode系列之「用栈实现队列」

232. 用栈实现队列请你仅使用两个栈实现先入先出队列。队列应当支持一般队列的支持的所有操作(push、pop、peek、empty)直接上最优解两个栈分别充当不同的角色:一个只负责存(push)一个只负责取(pop)假设负责存和取的栈分别为s1和s2:当存的时候只需要直接push到s1即可,不需要考虑其他的情况当取的时候,肯定直接从s2中取,如果s2不为空有则直接s2.pop(),如果s2为空呢,就只能将s1中的所有元素添加到s2中,然后再执行s2.pop()peek()的

2020-12-03 14:49:17 112

原创 从造轮子开始彻底理解LRU缓存机制

Leetcode146. LRU缓存机制造轮子在面试中,面试官一般会期望读者能够自己实现一个简单的双向链表,而不是使用语言自带的、封装好的数据结构。所以,造轮子还是很有必要的。LRU 缓存淘汰算法就是一种常用策略。LRU 的全称是 Least Recently Used,翻译过来就是最近最久未使用。力扣第 146 题「LRU缓存机制」就是让我们来设计这样一个数据结构:首先要接收一个 capacity 参数作为缓存的最大容量,然后实现两个 API,一个是 put(key, val) 方法存入键值对,

2020-11-16 14:31:01 379

原创 动态规划系列之「编辑距离」

72. 编辑距离给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。你可以对一个单词进行如下三种操作:插入一个字符删除一个字符替换一个字符示例 1:输入:word1 = "horse", word2 = "ros"输出:3解释:horse -> rorse (将 'h' 替换为 'r')rorse -> rose (删除 'r')rose -> ros (删除 'e')示例 2:输入:word1

2020-10-24 23:13:43 305

原创 LeetCode系列之「回文子串」

647. 回文子串给定一个字符串,返回这个字符串中有多少个回文子串。两个相同的回文子串出现在不同的位置,认为是2个回文串。a、aa、aaa、aba、aabaa、abcba均认为是回文子串。示例1:输入"aaa"输出6说明a、a、a、aa、aa、aaa示例2:输入"abcb"输出5说明a、b、c、b、bcb函数签名:import java.util.*;public class Solution{ public int palindromeCou

2020-10-23 21:46:16 352

空空如也

空空如也

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

TA关注的人

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