自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 golang写测试用例报no tests were run

在写go的测试test时,可能·会出现报 no tests were run 或者no test files问题,如果其他解决方法不行的话,可以试一下将该测试的文件名修改成蛇形如:trim_space_test.go 后面加一个 _test 就可以进行测试了。修改前:修改后:...

2021-02-07 10:30:14 4917

原创 Go语言中如何在range循环中修改数组/切片内容

在go语言中,我们经常会使用到range来帮助我们遍历一些数据,通常情况下都是查看操作多一些,但是当我们需要对其原地址上的内容进行变更时,通常都是使用 for i:=0; i<len(); i++ 来修改值。在使用range的时候,通常会将该数据结构进行拷贝,来遍历这一份拷贝后的副本,如果我们进行修改,修改的就只是副本,对原地址上的值不会产生任何影响。下面是两种使用range修改原值的方式:1. 使用指针数组让数据结构中的元素都存储为指针类型,这样在进行修改的时候,就是对地址上的值进行修改,毕竟

2021-01-29 10:25:59 5136

原创 Go语言遍历文件夹下的所有文件,并求出MD5

package mainimport ( "crypto/md5" "encoding/hex" "fmt" "io/ioutil")var files = make([][]byte, 100, 100)//[]byte转md5func ByteToMd5 (fileByte []byte) string { has := md5.Sum(fileByte) //用新的切片存放 has2 := has[:] md5Str := hex.EncodeToString(has

2021-01-08 19:12:27 841 1

原创 GO语言中的指针

我们最常听说的是C语言中的指针,但其实GO语言也有指针。GO语言中会允许这个指针类型对数据进行读写,在传递数据时可以直接使用指针,不用拷贝数据。但是GO语言中的类型指针是不能进行偏移和运算的,根据地址直接获取到整体的数据块。例如数组指针就是直接获取到整个数组信息,而不像c语言中通过偏移或运算来取到具体的元素数据。1. 指针的使用方法&用来取出地址,*用来根据地址取出地址指向的数据值。实际上,指针变量的值就是指针地址,对变量进行&操作可以获取到变量的地址,这个地址也就是指针变量。对指针变

2021-01-07 19:30:46 601

原创 GO语言变量作用域和数组

1. 变量的作用域对于变量来说我们主要分为三种,局部变量、全局变量以及形式参数。局部变量:作用域只在函数体内,参数和返回值变量也是局部。全局变量:可以在整个包甚至外部包(导出)中使用。全局变量和局部变量的名称可以相同,但是函数内会优先使用局部变量。形式参数:会被当做函数中的局部变量来使用。2. 数组数组是唯一具有相同类型的一组长度固定的数据项序列,序列中的数据类型可以是任意的基础数据类型、字符串或自定义结构体类型等。数组元素可以通过索引来对数据进行读写,索引从0开始,依次递增。数组声明格

2021-01-06 20:01:04 201

原创 GO语言中的函数

1. 函数声明go语言中必须有一个main()函数,函数声明提供给编译器函数名称、函数返回类型以及传入参数。go语言标准库中也提供了很多用于开发的内置函数。函数声明必须要用到func这个关键字。格式:func function_name([parameter list]) [return_types] { /*函数体*/}func:函数通过func开始声明。function_name:函数名。parameter list:参数列表。参数可比作一个占位符,调用函数时可以将数据传递给参数,这

2021-01-06 19:40:20 214

原创 GO语言中的循环语句

1. for循环for循环,重复执行语句块。如以下格式:for true { fmt.Println("死循环")}GO语言中没有while,只使用for语句,for后面也不用加括号,直接添加表达式即可。例如:for i := 1; i < 10; i++ { /*循环体*/}2. 循环控制语句break:用于中断当前for循环或跳出switch语句。continue:跳过当前循环的剩余语句,继续下一轮循环。goto:将当前执行跳转到被标记的语句。...

2021-01-06 17:49:11 405

原创 GO语言的常量和空白标识符

1. 常量1.1 格式同大部分语言一样,GO语言中的常量也是通过const关键字来进行声明的。格式:const v_name [type] = v_value和变量声明一样,可以省略类型说明符[type],编译器会根据常量的值来推断类型。1.2 枚举常量还可以用作枚举。例如:const ( apple = 1 banana = 2 lemon = 3)1.3 iota特殊常量iota,特殊常量,可认为是被编译器修改的常量。iota在const关键字出现时将被重置为0,const

2021-01-06 11:47:44 234

原创 GO语言的变量声明和基本数据类型

1. 基础语法1.1 变量的声明声明变量的一般形式是通过关键字 var ,var name type ,其中 name为变量名,type为变量的数据类型。以上为单变量声明,当然也可以在一个语句中对多个变量进行声明,var name1, name2 type = val1, val2,前提是多个变量的类型必须是相同的。1.2 省略var的变量声明在声明变量时也可以使用 := 来进行声明,但是 := 左侧必须为新的变量,如果没有声明新的变量,就会编译错误。具体格式为 v_name := v_value

2021-01-06 11:04:00 267 1

原创 初步认识Redis

简单来说,Redis就是一个缓存中间件,用来处理Java程序和数据库之间的数据交互。要想了解Redis,就要谈到缓存。一、缓存缓存就是一个高速数据交换的存储器,用来快速的对数据进行操作和读取。1.1 缓存的优势速度快。缓存是存储在内存的,相较于磁盘来说,不用进行磁盘IO操作,速度是非常快的。分布式集群。缓存很容易实现多级服务,来平衡单机承受的数据压力。效率高。通过key-value键值对方式存储,操作效率很高。1.2 缓存分类1.2.1 本地缓存(单机缓存)单个服务器和缓存进行交互。

2020-09-01 20:35:35 138

原创 浅谈HTTPS的加密原理

要了解HTTPS的加密原理,就需要先知道对称加密和非对称加密。1. 对称加密所谓对称加密,对称二字含义就是相同,也就是客户端和服务器双方共同使用一个密钥,无论解密或者解密,都可以通过这个密钥来完成。1.2 问题这样虽然保证了双方传输的效率,但是由于存储在浏览器的密钥很容易被窃取,一旦数据在传输过程中被拦截到,就很容易将加密数据包破解。2. 非对称加密...

2020-09-01 19:45:58 219

原创 一句话讲明Java锁升级过程

当我们新new对象的时候,此时对象是一个无锁的状态。当有一个线程要获取该对象的对象锁时,这第一个尝试获取的线程会直接获取到对象锁,并且将MarkWord中的线程ID修改为自己的,此时就由无锁升级为偏向锁。(用户态)此时如果有其他线程参与进来的话,这些线程就会通过自旋CAS的方式,来尝试修改线程ID,修改成功的线程就获取到这个对象锁,此时升级为轻量级锁(自旋锁)。(用户态)但是当等待的线程次数过多,并且等待的线程数量也越来越多时,自旋就会浪费大量的CPU资源,此时就升级为重量级锁。(内核态)...

2020-08-18 23:22:40 154

原创 JDBC的简介及使用

JDBC即Java Data Base Connectivity,Java数据库连接。它是一种用于执行SQL语句的Java API,是属于Java中数据库连接的一个规范。它的API主要由java.sql.* 和javax.sql.* 中的类和包组成。现在很多项目都是使用ORM框架来进行与数据库映射的,例如MyBatis和Hibernate都是在JDBC基础上进行了一层封装来实现的。所以说JDBC还是非常重要的。一、JDBC访问数据库层次结构根据这个层次结构能够看出来,其实JDBC最低层就是从数据库来

2020-08-10 18:59:45 465

原创 搭建个人博客项目---《写点什么》

该项目是通过使用Spring框架来搭建一个个人博客平台。主要分为建立数据映射关系、完善不同功能的服务和控制器以及对应方法映射的SQL语句注入。一、建立数据映射关系1.1 数据库及表的建立该数据库中主要包含了四张表,分别为user用户表、article文章表、category分类表和comment评论表。这四张表也是分别代表着该博客项目提供的不同功能:用户登录功能、文章发表功能、分类功能和评论功能。建表的SQL语句如下:DROP DATABASE if exists blog;CREATE DAT

2020-07-18 11:01:56 523 1

原创 Hibernate和MyBatis两者的具体差别

1. 映射关系MyBatis是一个半自动映射的框架,他是需要我们手动来匹配POJO简单的JAVA对象、SQL和映射关系的。而Hibernate是一个全自动映射的框架,他只需要我们提供POJO和映射关系就行。2. sql优化Hibernate不需要填写大量的SQL就可以做到完全的映射,他具有日志、缓存、级联(比 MyBatis 强大)等特性,同时还额外具有HQL(Hibernate Query Language)来对POJO进行操作。虽然功能更强大些,但是性能消耗也会比较大。MyBatis 需

2020-07-08 13:52:39 229

原创 Mybatis在SpringBoot中集成后的初始化过程

生成SqlSessionFactory,数据库连接会话工厂类,可以生成数据库会话。2. 扫描包内包含@Mapping注解的类,把所有的接口通过代码都生成代理类。加载resources.mapper的xml文件。关联xml文件、@Mapping代理类、实体类。(1)方法和sql建立映射关系;(2)ResultMap,映射查询结果集和Java对象;(3)parameterType传入参数的映射...

2020-07-07 20:42:44 512

原创 Spring AOP的简介及实现原理

AOP是Aspect Oriented Programming的缩写,意为面向切面编程,它是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。1. 为什么会出现AOP?通常我们对于统一处理的代码,需要在对应方法前后进行代码编写,这样就会产生大量重复代码,代码耦合性较高,后期的扩展和维护就会比较麻烦。AOP就会有效减少系统间的重复代码,达到了模块间的低耦合度目的。2. 作用处理统一业务时,可以通过一份代码就让对应方法前后有同样的业务逻辑。3. 使用场景执行时间的统计统一日志

2020-07-03 00:05:09 392

原创 Spring MVC的简介

MVC其实是Model、View和Controller的缩写,他分别代表着Web应用程序的三个不同的功能作用:Model(模型):用来存储数据和处理用户请求的业务逻辑。View(视图):向控制器提交数据,展示模型提供的数据。Controller(控制器):根据视图提交的请求来判断把请求和数据交给哪个模型处理以及判断处理后的结果信息交给哪个视图来更新展示。1. 基于Servlet的MVC模式的实现模型:Bean对象,用来做实体模型(存储数据,由JavaBean类创建)和业务模型(处理业务逻辑,

2020-07-02 23:14:24 189

原创 转发和重定向的区别

重定向会发送两次request请求;转发只会有一次请求。重定向会改变url;转发则不会改变url。tomcat中,重定向是可以定向请求到外面的数据信息;但是转发只能访问内部资源。

2020-07-02 14:22:18 107

原创 简单介绍Spring Boot

Spring Boot的诞生就是为了减少我们在项目中的大量手动配置,因为他会基于Spring框架创建出一个独立运行的的项目,这样能为我们的开发减少很多冗余操作。1. Spring Boot的主要功能创建独立运行的Spring项目。Spring Boot可以以jar包的形式进行独立运行,只需要通过java -jar ***.jar来运行即可。内部嵌套了Servlet容器。Spring Boot可以选择内嵌的Tomcat、Jetty或Undertow,就可以不用war包形式部署项目。提供starter

2020-07-01 22:13:33 184

原创 Spring Bean的作用域及其生命周期

因为Spring控制反转的机制,我们对于对象实例的控制权交给了Spring容器完成,在使用时再注入到程序当中,再对对象之间的依赖关系进行解耦。而Spring容器之所以能做到这些功能,都依靠Spring配置文件使用到的元素—Bean。我们可以把Spring容器看作是一个工厂,而Bean就是工厂中被管理和产出的产品,当我们需要管理Bean时,告诉Spring容器就可以。1. Bean的作用域Spring中Bean有五种作用域,分别为singleton、prototype、request、session和g

2020-07-01 00:12:15 239

原创 简单介绍Spring依赖注入---DI

1. 依赖注入的概念依赖注入就是指Spring容器在创建被调用者的实例时,会自动地把调用者需要的对象实例注入给调用者,这样调用者就可以通过Spring容器直接获取到被调用者的实例。假设在Spring框架下,当一个对象实例A需要调用到另一个对象实例B时,Spring容器就会自动创建一个实例B,并将这个实例B通过不同的注入方法来装配到实例A上,这个将实例B注入给实例A的过程就称为依赖注入。Spring中的依赖注入主要有四种方法:基于构造方法的注入、基于Setter方法的注入、基于自动装配的注入和基于注解的

2020-06-30 16:19:54 205

原创 Spring IoC容器的简单介绍

1. IoC的概念IoC 是 Inversion of Control 的缩写,就是控制反转的意思,他是指在开发过程中,对象的创建不再由调用者处理,而是交给 Spring 容器来创建。Spring 容器会控制程序之间的关系,而是不通过代码直接控制,所以控制权有程序代码转移给了 Spring容器,控制权发生反转,故名为控制反转。Spring 提供了两种 IoC容器,一种是 BeanFactory ,另一种是 ApplicationContext。2. BeanFactoryBeanFactory 是一

2020-06-26 19:38:43 225

原创 项目中为什么要使用框架?

不使用框架的问题1. 资源类对象在方法中new对象问题在项目中我们很多资源类的对象在方法中都会去新建对象,例如进入一个方法就创建对象,但是退出方法时,该对象就不可用了,就需要回收。影响这就会导致我们在调用方法时不停的去创建生命周期短的对象,增加了垃圾回收的负担,也就提升了Full GC的频率,用户线程暂停的时间就会更长,会大大影响执行效率。同时如果该资源类对象创建过程中比较耗费时间的话,,也会让整个程序的性能大打折扣。2. 资源类对象之间互相有依赖关系问题不同的资源类对象之间可能会有引用、继

2020-06-26 18:16:47 670

原创 Java中垃圾回收产生的影响

Java中自带的垃圾回收机制给我们带来了很大的方便,这里就介绍几种JVM常用的垃圾回收器。1. 垃圾回收考虑的因素1.1 新生代和老年代新生代:(Minor GC/Young GC),Minor GC比较频繁,一般回收速度也会比较快。老年代:(Major GC/Full GC),老年代清理对象通常比较多,频次也低,但每次Full GC时间比较长。...

2020-05-07 21:53:14 551

原创 Java的引用类型

1. 强引用强引用指向我们在一般情况下普遍存在的对象。例如我们new一个对象的时候, “Object object = new Object()”这类引用,强引用只要存在,垃圾回收期就无法回收掉这些被引用的对象。2. 软引用软引用指向一些还有用但并不是必需的对象。针对软引用指向的对象,在系统将要抛出OOM(内存溢出异常)之前,会把这类对象划分到回收范围内并进行第二次回收。如果此次GC之后还没...

2020-05-01 12:50:00 115

原创 Java中的垃圾回收算法

我们将不可用对象归为垃圾对象以后,还需要通过一些方法来将垃圾对象进行回收,Java中主要涉及了四种回收算法,分别为标记-清除算法、标记-整理算法、复制算法和分代收集算法。1. 标记-清除算法(Mark-Sweep)标记清除算法主要分为两个阶段:标记:将活动对象进行一一标记。清除:统一把没有标记过的对象进行清除操作。缺点由于可用对象和不可用对象在内存中是连续存储的,所以在标记之后进行...

2020-04-15 13:12:27 297

原创 Java中如何判定一个对象为垃圾对象

1. 引用计数法引用计数法会给对象添加一个引用计数器,当这个对象的引用增加一个,就把引用计数器的值也加一,减少就相反,当引用计数器的值变为0,就说明这是一个失效的垃圾对象。但是引用计数法也有一个问题,就是无法解决对象之间循环引用的问题。假设 object1.A = object2 ,但同时 object2.A = object1 。如图所示:2.可达性分析算法可达性分析算法引入了离散数学...

2020-04-14 22:44:15 931

原创 Java中的类加载机制

1. 类的生命周期加载->连接(验证->准备->解析)->初始化->使用->卸载2. 类加载的具体步骤加载首先通过类的全限定名,来获取到定义这个类的二进制字节流。再将字节流转化为动态的一个数据结构保存到方法区中。把类的class文件读取到内存中,再创建一个java.lang.Class的对象,之后访问这个类的数据时,这个对象就可以作为类的一个访问数...

2020-04-13 17:09:48 134

原创 Java对象的组成部分

每一个对象都由对象头、对象的实例数据区和对齐填充字节这三部分组成。1. 对象头对象头由三部分组成:Mark Word:记录对象和锁的有关信息。当一个对象被 synchronized 关键字加锁之后,围绕锁的操作就都会和MarkWord有关联。MarkWord通常都是 32 bit位大小。会保存一些分代年龄、无锁状态下对象的HashCode、偏向锁的线程ID、轻量级锁指向栈中锁记录的指针、指...

2020-04-09 15:52:30 5089 2

原创 实现一个简单的抽象队列同步器---理解AQS底层原理

AQS是 AbstractQueuedSynchronizer ,译为抽象的队列同步器。它主要为了保证我们高并发场景下的一个线程安全。这里我们通过自己实现一个简单版本的AQS来理解他的核心原理。一、同步加锁思路首先保证加锁的话,任意时刻只能是有一个线程加锁成功,也就是保证它的原子性。这里就提供一个 state 这样一个字段,来记录当前加锁的一个状态,也就是次数。我们要做的就是保证任意时刻,只有...

2020-04-09 15:28:09 272

原创 境外疫情数据爬取项目---整体思路

一、数据抓取流程爬取境外疫情数据,首先需要找到一个提供该信息的网站,所以我们找到腾讯新闻的一个网站: https://news.qq.com/zt2020/page/feiyan.htm?from=timeline&isappinstalled=0#/global?ct=Italy。该网站提供了国内国外的详细疫情信息,这里我们只需要找到国外疫情的部分,如图所示:在开发者工具中找到对...

2020-04-08 23:54:55 1646

原创 JVM内存区域划分

JVM 的内存模型如图所示:一、线程私有部分1.1 程序计数器程序计数器(PC Register)是一块比较小的内存空间,可以把它看成是一个当前线程执行字节码文件对应位置的行号指示器。字节码文件的解释器通过改变程序计数器的一个值,来选取接下来要执行的指令行,比如实现一些循环,跳转等代码的时候,就需要通过程序计数器来完成。不过这只是虚拟机最基本的一种方法。由于在多线程的并发执行环境下,每次...

2020-03-30 17:14:49 110

原创 查看状态中报错 sendmail: fatal: parameter inet_interfaces: no local interface found for ::1

我在云服务器的CentOS系统中使用 crontab 设置定时任务的时候,查询状态时发现了错误日志,如图:这段内容表达的是 参数inet_interfaces::1没有找到本地接口,不只是设置定时任务的时候会遇到这个问题,其他关于本地接口使用时都有可能遇到这个问题,下面就是解决方案。解决方法在 /etc/postfix目录下,找到 main.cf 文件 。执行 vim main.cf找...

2020-03-29 21:06:01 5871 6

原创 TCP中的延迟应答与捎带应答

一. 延迟应答(接收端)1.1 应答方法通常一个数据段可以返回一个ACK应答,但是接收端如果立刻返回ACK应答,会让这个数据段中的窗口大小值比较小。假设我们接收缓冲区的为2M,收到了1M的数据,如果立刻应答,返回的窗口就是1M。实际上接收端处理数据可以很快,很短的时间内就把接收到的1M数据处理掉了。这种情况下,接收缓冲区并没有到达自己的接收数据的极限,窗口就算更大也有能力处理。如果接收端再晚...

2020-03-06 11:27:38 635

原创 TCP中的流量控制与拥塞控制

一. 流量控制(接收端)1.1 产生原因我们知道在接收端接收数据的时候,会先将数据保存在接收缓冲区中,等待应用程序调用recv()方法读取。如果接收缓冲区内的数据一直没有被应用进程读取,接收缓冲区空间被填满,发送端再继续发送数据的话,就会引起丢包等一系列的连锁问题。为了避免这种问题的发生,TCP中可以根据接收端的处理数据的速度和能力,来决定发送端的发送速度,这个机制就叫做流量控制。1.2 ...

2020-03-05 18:16:11 502

原创 TCP中滑动窗口介绍

我们知道TCP协议中有一个确认应答机制,每发送一个数据段,就需要有一个ACK来响应,如果这样一收一发的话,会让数据传输的效率变得很低。滑动窗口就是用来解决这个问题的,也就是我们一次发送多条数据。例如现在不需要等待确认应答可以发送数据的最大值为4000个字节,我们将4000个字节分为四个数据段来进行发送。在发送前四个数据段的时候,我们不需要等待任何的ACK应答,可以直接发送。当收到第一个数据段的AC...

2020-03-05 18:13:14 371

原创 详解TCP协议的连接管理机制——三次握手和四次挥手

一. 建立连接—三次握手首先客户端和服务端都是关闭状态,也就是CLOSED状态。服务器端进入一个监听的LISTEN状态,阻塞等待客户端的连接。第一次握手:客户端向服务端发送一个SYN的标志位以请求连接。此时客户端进入SYN_SEND状态,也就是开始阻塞等待服务器的应答。第二次握手:服务器收到了客户端的SYN连接请求,也就处于SYN_RCVD状态。由于现在客户端向服务端单方面请求连接了,但是...

2020-03-03 15:56:15 451

原创 TCP协议中的确认应答机制和超时重传机制

1. 确认应答机制在TCP协议中,发送端将数据发送到接收端,接收端会自动返回一个ACK的应答,告诉发送端我已经接收到数据。TCP会给每个字节的数据赋予序列号,每一个ACK应答都会携带对应的确认序号,也就是字段中的32位确认号,这个确认号用来告诉发送端,你的数据发送到哪里,你下一次发送应该从哪里开始。比如发送端先发送了1 - 1000 的数据到接收端,接收端再返回一个ACK响应,此时携带的确认号就...

2020-03-02 21:26:13 1794

原创 TCP协议传输的格式内容

TCP的全称为传输控制协议(Transmission Control Protocol),顾名思义,就是可以对传输流程有一个准确的控制。1. 格式上图为TCP协议的格式内容,相比于UDP协议段,TCP的内容就显得更加丰富多样,当然也有一部分有着同样的作用。16位源端口号:标识本机网络通信的进程。16位目的端口号:标识接收方主机进行通信的进程。32位序号:指发送数据的位置序号,每发送一...

2020-03-01 16:18:35 1644

空空如也

空空如也

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

TA关注的人

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