Redis挖矿分析
为什么当你学习Redis,发现自己的服务器在挖矿了 在我学习Redis时,因为嫌麻烦就没有设置密码,结果导致一段时间后系统提醒我,我的服务器上有挖矿行为,如果不清理就停止运行,我一脸懵逼,并不断上网查找哪里出现问题了,但最终还是没有解决,无奈下我初始化了服务器。希望本篇文章能对你有锁帮助,顺利让你体会到入侵自己服务器的感觉。
你是如何连接服务器的? 在最初我们购买好自己的服务器后,要么在服务器厂商页面进行安全连接,要么通过SSH 用户名@密码方式进行连接,例如下图:
但到后面我们发现每次都需要输入密码,也太麻烦了,可以利用秘钥登陆服务器。那如何获取到你的秘钥呢?
客户端通过命令行模式输入:ssh-keygen生成自己的公钥和私钥(这里可以指定参数,具体自己查)。
手动将客户端的公钥放入远程服务器的指定位置,/root/.ssh/authorized_keys。
现在我们再通过ssh进行登陆,可以看到直接登陆到服务器了
那说了这么多,我们发现只要服务器上有你的秘钥,你就可以直接进行登陆,不需要设置密码。那这和Redis有啥关系呢?
你是如何连接 ...
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) & ...
封装自己的SDK
封装自己的SDK 我们在开发Spring项目时常常会引入各种xxx-spring-boot-starter的依赖包,然后在配置文件中填入必要的信息,就可以使用依赖提供好的容器。这里是在鱼皮新项目直播中学习到的,特此记录一下。可在未来封装自己的SDK进行封装与装逼。
SDK项目下
将pom.xml中的标签删除
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>o ...
拦截器与过滤器的区别
拦截器与过滤器的区别
底层思想是什么?
拦截器与过滤器都是基于AOP面向切面编程的思想来实现的。
两者有什么相同,有什么不同?
相同点:都可以对请求做出统一的处理,例如在方法调用前进行一些操作,在方法调后后处理一些操作
不同点:
拦截器是Spring提供的(org.springframework.web.servlet.HandlerInterceptor),而过滤器是Servlet提供的(java.servlet.*)
触发时机不同,过滤器在请求到达Servlet前被拦截开始执行,拦截器在到达Controller前被拦截开始执行
实现不同,过滤器基于方法回调实现,而拦截器是基于动态代理(底层反射)实现
支持的项目不同,过滤器只能在Web项目中用,拦截器可以在Swing,Application中都能用
使用场景不同,因为拦截器更接近业务系统,所以拦截器主要用来实现项目中的业务判断的,比如:登录判断、权限判断、日志记录等业务。而过滤器通常是用来实现通用功能过滤的,比如:敏感词过滤、字符集编码设置、响应数据压缩等功能。
为什么使用他们?
在我们的日常业务中,我们 ...
分布式事务
简介 我们在过去总是使用本地事务,也就是数据库提供的事务操作,其中具有ACID的特性,但在如今我们的各个模块儿被拆分,服务与服务间相互调用,简单来说就是需要跨进程的事务,我们来想一下现有的本地事务是否能解决分布式事务。情况1:跨JVM,跨数据库产生分布式事务
graph TD;
用户下订单-->订单模块;
订单模块-->物流模块;
订单模块-->订单表;
物流模块-->物流表;
用户直接调用订单模块儿,开启事务,然后在订单表中存入数据,然后再远程调用物流模块儿,去操作物流模块儿,我们可以想到如果物流模块儿出现问题,订单模块儿远程调用发生错误,是会进行事务回滚的。应该是没问题的。那如果物流模块儿确实修改成功了,但网络传输出现了问题,订单模块儿就进行回滚了,则就导致了物流模块儿有数据,订单模块儿没数据的问题。我们再考虑下面的问题:
情况二:跨数据库实例产生分布式事务
graph TD;
人员管理模块儿-->用户数据库;
人员管理模块儿-->订单数据库;
前置理论
CAP理论 CAP表示一致性 ...
后端演化过程
后端风云 本文简单概况了一下刘欣老师的《码农翻身》的后端风云章,这本书强烈推荐给大家,每看一遍都有不同的感觉,通俗易懂且知识面大而全。居家旅行,必备良药!!!
早期初级阶段:
在我们早期学习 javaWeb阶段,将订单模块儿,购物车模块儿,支付模块儿都写在了一个项目中,并访问一个Mysql数据库,这在自己练手项目中是没问题的,但如果系统上线,有大量的用户同时访问该系统,Tomcat服务器首先需要考虑能不能支撑住大的并发量(默认150,当超过250时,就应该考虑的服务器的集群),其次是Mysql数据库,在高并发两三千也就差不多了,要知道Mysql数据库读取数据是很慢的操作,它本质是从硬盘中读取文件的。
优化点1:使用缓存
可以看到我们给中间加了一个Redis中间件作为缓存,现在服务器需要获取数据,先到缓存中找数据,如果找不到再去Mysql中找数据,找到数据后再写回Redis中,这样下次请求数据可以直接在缓存中获取数据,那缓存的好处是啥,缓存是加载在内存中的,读取数据那肯定是快的多。这样就减轻Mysql数据库的压力。但是如果用户每次请求先去缓存找,如果都没 ...
并发编程
基础的概念什么是并发操作?利用多核CPU去完成任务,类似于使用影分身去完成不同的作业,这肯定比我一个人一个个写要快的多
什么时候可以使用并发?当有多核CPU时。如果只有一个CPU,那并发实际上只是线程的不断切换,好比我在数学作业上先写点儿,再到语文上再写点儿,因为处理的很快,给人的感觉是同时操作的。但实际上只会比原来更慢(因为有线程切换的损耗)。
如何使用并发编程?public class BasicLearn {
public static void main(String[] args) {
new Thread(new A()).start();
new Thread(new FutureTask<String>(new B())).start();
new C().start();
}
}
// 无返回值
class A implements Runnable {
@Override
public void run() {} ...
Mysql的事务与索引
Mysql事务与索引
需求:先从数据库中读取一个字段的值,然后修改该字段,由于操作不是原子性,无法保证线程安全,也就是当A线程读取值为1时,想在原有基础上+1,赋值为2。而B线程已经将数据修改为2了,那么A线程应该是在2的基础上+1,赋值为3。但实际中可能该值都到8了,A又给人家改回2了。所以我们该如何解决数据安全问题?
本能想到利用JVM层面的锁机制,保证每次只有一个线程进行操作,但这个性能太差,而且JVM锁无法在分布式中生效。
利用数据库事务操作,下文我们主要讲Mysql事务的知识。
数据库事务 在讲事务之前,我们需要明确Mysql中只有Inndb存储引擎支持事务,如果是其他存储引擎则无法使用事务,所以我们应先检查自己的存储引擎是否正确。
查看数据库支持的存储引擎:show engines
查看自己的表使用的引擎:show table status from 数据库名 where name = '表名';
修改表的存储引擎:ALTER TABLE 表名 ENGINE=引擎名称;
查看是否是自动提交:show variables like & ...
第三章:二叉树问题
树形dp套路在做树结构的题目中,如果求解规则可以分为,以某个节点为子树,先向左要数据,再向右要数据,最后返回总数据,我们就可以使用该套路。
递归进行遍历
public static void QTraverse2(Point tree) {
if (tree == null) {
return;
}
System.out.println("先序");
QTraverse2(tree.left);
System.out.println("中序");
QTraverse2(tree.right);
System.out.println("后续");
}
非递归进行遍历
//非递归前序遍历 使用栈
public static void QTraverse1(Point tree) {
Stack<Point> stack = new Stack<> ...
Shell脚本
Shell输入输出重定向
我们在后台挂在jar包时,常使用过一个命令:nohup java -jar xxx.jar > java.log 2>&1 &
这里就有几个知识点:
末尾的 & 代表后台默认启动,页面关闭后,程序终止。
头部的 nohup 表示页面关闭后,后台仍继续运行,如果没有指定日志文件,则默认将输出重定向到nohup.log文件
java -jar xxx.jar最基本的启动jar包
> java.log 将运行jar包后的输出日志文件重定向到 java.log文件中
2>&1将标准输出与标准错误输出合并,在当前语义下就是将所有信息输出到 java.log文件。
如果只写 > 表示只将正常输出重定向到log文件中,错误信息直接显示页面
如果写 2> 表示只将错误输出重定向到log文件中,正常信息直接显示页面
> 默认表示重定向,并覆盖原来内容
>> 表示以追加的方式重定向
这样我们就可以监控到后台运行程序的日志信息了。
shell脚本保证程序运行
需求:当我们将项目挂在到服务 ...

