搭建博客,利用Webhook自动更新
Hexo d 推送至服务器 前段时间利用Hexo搭建博客,并配合GitHub page进行页面显示,一切都很美妙,但有一个问题就是访问速度太慢,后面我希望将博客迁移到腾讯云中,之后就从服务器访问了。现在关于Hexo搭建基本博客的帖子已经很详细了,所以我会放一些我参考的链接,主要介绍如何从本地将文件同步到自己的服务器中。
前置知识Hexo博客搭建三水同学的笔记:https://sanshui.vip/2022/08/10/indexday1/ (这里操作完,基本上就是博客雏形和Github page的显示)
Butterfly主题有了基本的博客雏形,但样式比较单一,这时候就可以利用现有的Hexo主题,这里只列举了Butterfly,还有些其他主题,可以自行查找。
推荐教程:https://www.fomal.cc/posts/4aa2d85f.html (这里操作完,样子就会好看许多,剩下的就是页面的修改,按照自己的意愿)
页面音乐播放我当时觉得博客加点儿音乐很有感觉,就捣鼓了些。
推荐教程:https://blog.csdn.net/qq_41467882/article/ ...
第一章:栈与队列
第一章:栈与队列设计一个有getMin功能的栈
要求:pop,push,getMin的时间复杂度为:O(1)
public class stackTemplate {
// 记录插入值
private Stack<Integer> stack = new Stack<>();
// 记录插入值的最小值
private Stack<Integer> minStack = new Stack<>();
public void push(int value) {
stack.push(value);
// 如果最小值栈的栈顶元素 大于 当前元素,则说明有新的最小值了,
if (minStack.isEmpty() || minStack.peek() >= value) {
minStack.push(value);
}
}
public int pop() { ...
Redis 底层结构
BigKey是什么 ?BigKey通常以Key的大小和Key中成员的数量来综合判定,例如:
Key本身的数据量过大:一个String类型的Key,它的值为5 MB。
Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10,000个。
Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的Value(值)总大小为100 MB。
推荐值:
单个key的value小于10KB
对于集合类型的key,建议元素数量小于1000
有什么危害 ?
网络阻塞
对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例,乃至所在物理机变慢
数据倾斜
BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡
Redis阻塞
对元素较多的hash、list、zset等做运算会耗时较旧,使主线程被阻塞
CPU压力
对BigKey的数据序列化和反序列化会导致CPU的使用率飙升,影响Redis实例和本机其它应用
怎么识别 ?
redis-cli –bigkeys
利用re ...
内存划分与溢出
概述 对于java与C&C++开发的一大区别就在内存管理方面。Java是通过虚拟机管理内存,但如果不熟悉虚拟机怎么使用管理内存,出现内存泄露和内存溢出问题,修正就会很艰难。
运行时数据区域 Java虚拟机在执行Java程序的过程中会把所管理的内存划分为一个个小部分,有的部分随着进程的启动而一直存在,有的部分随着用户线程的启动和结束而创建和销毁。其管理的内存分为以下几个运行时数据区域。
程序计数器 是一块儿较小的内存空间,他可以看做是当前线程所执行的字节码的行号指示器,通俗的来讲就是通过改变计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支,循环,跳转,异常处理,线程恢复等基础功能都是依赖计数器完成的。
在java多线程中,是利用线程轮流切换,分配处理器执行时间的方式来实现的,也就是说我执行了一会儿A线程,时间到了,我要去执行B线程了,那B线程执行时间到,我要再切换会A线程,那我怎么知道刚才任务完成到哪了?所以每个线程都私有一个程序计数器来保证线程切换后能回到正确的位置。
...
垃圾回收与内存分配
垃圾收集器与内存分配策略概述我们先提出三个问题:
哪部分内存需要回收?
什么时候进行回收?
如何进行回收?
生存还是死亡?where 我们都知道在Java中,栈,本地方法区,程序计数器都是线程私有的,随着线程的创建和结束,内存也会自动的分配和销毁,执行的方法也随着栈帧的插入和弹出而创建和销毁。所以这部分区域我们不必担心。
而方法区(元空间)和堆空间,是线程共享的,这部分区域的内存就是我们需要去进行垃圾回收的区域。
when 什么时候进行垃圾回收,就需要我们判断这个对象是否仍被引用,如果没有一个指针指向它,那我们就可以放心的进行垃圾回收,如果仍被引用,那就不行(你杀根本干嘛,这人我正用着呢),关于对象引用判断分为两种:
引用计数法 就是说一个人引用,就对一个引用计数器加一,如果这个人不引用了,我们就减一,当引用计数器等于0的时候,我们就可以判定,可以被垃圾清理了。
该方法易理解,且实现简单。但一个缺点就是遇到循环依赖,不好处理。在主流的java虚拟机中都没有使用该方法进行判断。下面用代码进行说明。
class referenceCountingG ...
类加载机制
概述
虚拟机是如何加载Class文件的?
Class文件进入虚拟机后会有什么变化?
在Java中我们知道有编译期和运行期,其中编译期为我们写的java代码通过javac编译成一个一个的class文件,而运行期则为将class文件通过jvm加载到内存中,通过一些列操作变成可以jvm直接使用的Java类型。这为Java带来了极高的扩展性和灵活性,例如动态链接和到动态加载,具体下来可用面向接口编程和一系列设计模式进行举例。
类的加载时机 一个类型从加载到jvm内存中开始,到卸载出内存为止,整个生命周期经历了:
其中加载,验证,准备,初始化是按部就班的开始的,解析则不一定,一些情况中解析是在初始化后的,而这也是为了支持java的运行时绑定特性。
一般类的加载在《java虚拟机规范》中并没有强制要求,根据具体的虚拟机实现完成,而类的初始化则严格按照规定,有且只有六中情况,必须对类进行初始化,而前面的步骤自然也要提前完成。
遇到new,getstatic,putstatic,invokestatic 这四条字节码指令时,如 ...
后端编译与优化
后端编译与优化编译器优化技术逃逸分析
逃逸分析本身不是直接进行优化的方法,而是一种为优化提供帮助的分析算法
逃逸分析的原理:
我们分析对象的动态作用域,如果对象创建在方法中,可能被外部方法所引用到,例如作为参数被外部方法进行调用,这叫做方法逃逸,
被外部线程所访问到,例如赋值给外部线程使用的变量中。称为线程逃逸
从不逃逸,方法逃逸,线程逃逸。称为对象从小到大的逃逸程度,我们因此也可以做不同的优化策略、
栈上分配 大家都知道在java中,所有的对象都存储在堆空间中,随着存放 的对象越来越多,也就需要垃圾回收器来进行工作,而这一步也是非常消耗性能的,那这里就引出一个概念栈上分配,也就是当我们进行逃逸分析后,发现对象不存在线程逃逸,我们将对象存储在栈上,随着栈帧的插入与弹出,对象本身也跟着创建和销毁。
这里我们需要提醒两点:
之前放在堆中,堆中对象是被各个线程共享的,只要有指针指向该对象的地址,就可以进行使用。但栈是线程独有的。所以栈上分配的第一点:对象不会被线程共享,也叫做线程逃逸。
如果对象被分配到栈上了,随 ...
Redis挖矿分析
为什么当你学习Redis,发现自己的服务器在挖矿了 在我学习Redis时,因为嫌麻烦就没有设置密码,结果导致一段时间后系统提醒我,我的服务器上有挖矿行为,如果不清理就停止运行,我一脸懵逼,并不断上网查找哪里出现问题了,但最终还是没有解决,无奈下我初始化了服务器。希望本篇文章能对你有锁帮助,顺利让你体会到入侵自己服务器的感觉。
你是如何连接服务器的? 在最初我们购买好自己的服务器后,要么在服务器厂商页面进行安全连接,要么通过SSH 用户名@密码方式进行连接,例如下图:
但到后面我们发现每次都需要输入密码,也太麻烦了,可以利用秘钥登陆服务器。那如何获取到你的秘钥呢?
客户端通过命令行模式输入:ssh-keygen生成自己的公钥和私钥(这里可以指定参数,具体自己查)。
手动将客户端的公钥放入远程服务器的指定位置,/root/.ssh/authorized_keys。
现在我们再通过ssh进行登陆,可以看到直接登陆到服务器了
那说了这么多,我们发现只要服务器上有你的秘钥,你就可以直接进行登陆,不需要设置密码。那这和Redis有啥关系呢?
你是如何连接 ...
拦截器与过滤器的区别
拦截器与过滤器的区别
底层思想是什么?
拦截器与过滤器都是基于AOP面向切面编程的思想来实现的。
两者有什么相同,有什么不同?
相同点:都可以对请求做出统一的处理,例如在方法调用前进行一些操作,在方法调后后处理一些操作
不同点:
拦截器是Spring提供的(org.springframework.web.servlet.HandlerInterceptor),而过滤器是Servlet提供的(java.servlet.*)
触发时机不同,过滤器在请求到达Servlet前被拦截开始执行,拦截器在到达Controller前被拦截开始执行
实现不同,过滤器基于方法回调实现,而拦截器是基于动态代理(底层反射)实现
支持的项目不同,过滤器只能在Web项目中用,拦截器可以在Swing,Application中都能用
使用场景不同,因为拦截器更接近业务系统,所以拦截器主要用来实现项目中的业务判断的,比如:登录判断、权限判断、日志记录等业务。而过滤器通常是用来实现通用功能过滤的,比如:敏感词过滤、字符集编码设置、响应数据压缩等功能。
为什么使用他们?
在我们的日常业务中,我们 ...
Spring如何解决循环依赖
Spring循环依如何解决?
循环依赖是什么?
class A{
B b;
}
class B{
A a;
}
//简单来说就是A的创建依赖于B,B的创建依赖于A。
在一般场景下,如何解决循环依赖的问题?
我们知道对象的创建一般有:
无参构造器+属性Set方法初始化对象
有参构造器直接初始化对象
//通过有参构造器初始化
class A{
B b;
public A(B b) {
this.b = b;
}
}
class B{
A a;
public B(A a) {
this.a = a;
}
}
class client{
//我们发现会无限套娃下去,有参构造器方法不能使用
new A(new B(new A(new B())))
}
//通过无参参构造器初始化
class A{
B b;
public void setB(B b) & ...