前言:接触的东西越来越多,学到的东西越来越多,解决的问题越来越多,有时候回想起来,觉得很牛逼,但是细想,却觉得缺少了什么,觉得自己懂得很多,但是又说不上来。所以决定立项,将学到的东西分类汇总,让他们有一个体系,让他们相互连接起来,这样吹起牛来也不至于太尬。
阅读本篇博客注意事项:
- 目录较长,标题就是一个知识点的名字
- 小的知识点直接在本篇博客进行讲解,标题是业内跳转链接,大的知识点需要另开一篇,标题就是外部链接,会自动跳过去。
- 不仅有我自己写的文章,还有我见过的优秀的文章的链接(不会灌水的放心,绝对干货)
- 本篇博客置顶持续更新,一开始可能比较空……
题外话:
接下来写博客的两大方向已经确定,不再像以前那样零零散散的记录所学,想到什么写什么,而是针对某一系列深入研究下去。第一个就是这个学习汇总,将所学详细的分门别类记录起来,并且某一段时间会只专注于某一个类别来写。第二个就是已经在写的从零搭建后端基础设施系列(一)-- 背景介绍,这个系列主要是对所学进行实践,非常的好玩,而且不是单纯的对某个知识点进行实践,而是由面及点的进行。可以说,第一个是理论基础,第二个是实践,两个搭配在一起,乐趣无穷!
-
java基础
JDK1.8 HashMap put源码剖析
jdk1.8 LinkedHashMap源码剖析
java直接内存限制条件
两个对象值相同 (x.equals(y) == true),但却可有不同的 hash code,这句话对不对?
LinkedHashMap是如何保证有序的? -
数据库
MYSQL入门语句
MYSQL数据检索总结
MYSQL常用函数总结
索引和约束的创建
局域网内如何连接MYSQL数据库 -
网络
Socket编程服务端原理简单介绍
Socket编程客户端原理简单介绍
Socket编程-1V1聊天
socket编程UDP服务器原理简介
socket编程UDP客户端原理简介
socket编程UDP小例子
socket多人聊天程序C语言版(一)
socket多人聊天程序C语言版(二)
关于使用UDP实现多人聊天程序的Thinking
Socket多人聊天MFC版
socket非阻塞模式服务器设计与实现
socket select模型服务器设计
基于select模型的多人聊天程序(C++)
重叠I/O之完成例程
完成端口模型
重叠I/O之事件通知
WSAEventSelect模型例子
WSAAsyncSelect模型例子
重叠I/O完成例程模型如何同时投递WSARecv和WSASend
深入浅出JAVA BIO、NIO和AIO(附详细代码实例)
带你搞懂Thrift核心源码(JAVA) -
springboot
springboot之BeanPostProcessor功能及例子(一)
springboot之事件监听机制
spring自定义注解失效的原因
idea+spring boot+mybatis+restful风格的demo
细说@Transactional用法及原理
【追根究底】 为什么@Transactional注解失效了?
【追根究底】@Lazy注解为什么会失效?
【追根究底】使用@Lazy注解为什么会产生两层代理?
【细品springboot源码】彻底弄懂spring bean的创建过程(上)
@DependsOn用法和原理 -
linux
如何安装CentOS7字符界面
Linux下用户和组的增、删、改
Linux如何编译源代码安装软件
Linux如何用rpm安装软件
Linux如何更改yum源
Linux如何用yum安装软件或服务
shell脚本基本语法详解
linux常用查找命令详解
Linux文件的普通权限详解
Linux管道命令符
如何使用Linux重定向符
个性化配置putty并保存配置
使用putty远程连接linux
linux如何用fdisk命令分区
centos7如何开放端口 -
数据结构
线性表之顺序表
栈、递归、循环的关系
顺序表的动态增长
KMP算法next数组详解
KMP算法详解
字符串数据结构实现(链表方式)
广义表C/C++实现详解
二叉树递归实现
二叉树非递归实现
二叉查找树
栈应用之中缀转后缀表达式计算(C++、JAVA)
栈应用之中缀转后缀表达式(C语言版)
线性表之单链表
线性表之循环链表
字符串数据结构实现(数组方式)
线性表之双向链表
线性表之顺序栈
线性表之链栈
线性表之顺序队列
线性表之链队列
线性表之循环队列
约瑟夫问题详解+源码 -
算法
Lake Counting
迷宫的最短路径
剑指offer–替换空格
剑指offer–用两个栈实现队列
插入、快排、堆排、归并、计数和桶排序详解以及测试 -
开发工具
如何正确使用git和github
git用法进阶
git如何删除某几个commit
如何将本地仓库和远程master仓库关联push
idea 不停的 updating indices
idea debug的时候出现because it happened inside debugger evaluation
maven报错"was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced"
.gitignore规则不生效的解决办法
java基础 |
-
java直接内存限制条件
ByteBuffer.allocateDirect受到-XX:MaxDirectMemorySize参数的限制,如果没有设置该参数,那么受到-Xmx参数的限制 -
两个对象值相同 (x.equals(y) == true),但却可有不同的 hash code,这句话对不对?
首先,这句话是对的,因为你可以重写这两个方法,你可以随意规定它们的规则@Override public int hashCode() { return 0; } @Override public boolean equals(Object obj) { return true; }
但是,这是不符合规范的,如果这样用了。。。会被打得很惨的。。。
重写equals的规范:- 自反性,即自己和自己比较肯定相等,
x.equals(y) == true
- 对称性,即
x.equals(y) == true && y.equals(x) == true
- 传递性,即
x.equals(y) == true && y.equals(z) == true && x.equals(z) == true
- 一致性,即不管调用多少次
x.equals(y)
,要么恒为true,要么恒为false x.equals(null)
恒为false`
重写hashcode规范:x.equals(y) == true
时,x.hashCode() == y.hashCode()
x.hashCode() == y.hashCode( )
时,x.equals(y) == true
为什么建议这样做呢?我们都知道hashmap中判断key是否相等是先用的hash值再用的equals如果我new了两个对象,key的值相等,但是hashcode不相等,这样就会出导致,相同的key值却返回false
Key k1 = new Key(1); Key k2 = new Key(1); 没重写的情况下 k1.equals(k2) == false K1.hashCode() != k2.hashCode 只重写equals,在hashmap中会发生这两个key不是同一个 k1.equals(k2) == true K1.hashCode() != k2.hashCode 两个都重写,这两个就相当于是一样的key了 k1.equals(k2) == true K1.hashCode() == k2.hashCode
- 自反性,即自己和自己比较肯定相等,
-
LinkedHashMap是如何保证有序的?
LinkedHashMap是继承HashMap的,所有的put、get等操作都是使用hashmap的。hashmap中有一些protected方法是专门用来给LinkedHashMap重写用的(多态)
LinkedHashMap中的实现如下,发现每一个方法都多了一个linkNodeLast,其作用是,将每一个插入的节点,都放入自己维护的双向链表的尾部
遍历的时候,遍历这个双向链表,那么就能保证和插入的顺序是一致的final LinkedHashMap.Entry<K,V> nextNode() { LinkedHashMap.Entry<K,V> e = next; if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (e == null) throw new NoSuchElementException(); current = e; next = e.after; return e; }
多线程 |
数据库 |
网络 |
springboot |
- @DependsOn用法和原理
- 用法
假设有A、B类
第一种正常用法,A
依赖于B
,需要B
创建后,A
才能创建。
这是一种错误的用法,会造成循环依赖(这个和隐式的循环依赖不同,这是人为直接指定的显式循环依赖),直接报错@DependsOn("b") @Component public class A { public void sayA(){} } @Component public class B { public void sayB(){} }
@DependsOn("b") @Component public class A { public void sayA(){} } @DependsOn("a") @Component public class B { public void sayB(){} }
- 原理
看doGetBean
方法即可
代码可以很清楚的看出来为什么不能那样用了。正常情况下会调用protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { …… // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { //这里会判断是否循环依赖,是的话,就会报错 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { …… } } …… }
getBean
去创建或从缓存获取依赖。因为可能一开始B先于A创建了,然后创建A的时候,依赖已经创建后,getBean
就会直接从缓存拿。
- 用法
linux |
-
centos7如何开放端口
-
如何查看某个端口是否开放
第一种,netstat -aptn 第二种,直接用Telnet ip 端口号命令来测试一下
-
查看防火墙运行状态
firewall-cmd --state 如果是not running systemctl start firewalld.service
-
开启端口
firewall-cmd --zone=public --add-port=xxx/tcp --permanent --zone=public:表示作用域为公共的; --add-port=xxx/tcp:添加tcp协议的端口xxx; --permanent:永久生效,如果没有此参数,则只能维持当前服务生命周期内,重新启动后失效;
-
重启防火墙
systemctl restart firewalld.service
-
5.重新载入配置
firewall-cmd --reload
-
容器 |
数据结构 |
算法 |
工作经验 |
- 接口性能优化
最近发现项目中有些接口返回非常慢,一个搜索接口居然接近1s的返回时间??先排查一下,是不是数据库的问题,发现很快呀。然后就看一下从前端到后端的接口调用链,马上发现问题了。原来在调用第三方接口的时候,没有使用批量调用,而是单个调用。举个例子吧
所以总结一下,如果量多,能用批量一次获取就一次获取,不要过多的RPC调用,发生不必要的损耗。//bad case public List<Result> search(){ //从数据库查找到相应结果 List<XXDomain> domains = dao.search(xxx); //处理原始结果 List<Result> res = new ArrayList<>(); for(XXDomain domain: domains){ Result r = new Result(); //需要根据某个属性作为参数,去调用第三方接口,获取某些信息 //如果domains有几十上百个的话,那么是不是需要几十上百次RPC? //就算RPC性能再好,每一个10ms以下,那量一多,是不是就变慢了? otherService.get(domain.xxx); …… res.add(r); } return res; } //good case public List<Result> search(){ //从数据库查找到相应结果 List<XXDomain> domains = dao.search(xxx); //1.将需要的参数提取出来 …… //2.调用第三方的批量获取接口,将信息存到map中,下面想怎么用就怎么用 …… //处理原始结果 List<Result> res = new ArrayList<>(); for(XXDomain domain: domains){ Result r = new Result(); //在这里,只需要在map中拿,就好了,不需要再发生RPC调用 map.get(domain.xxx); …… res.add(r); } return res; }
开发工具 |
-
git如何删除某几个commit
1.
git log
找到你要删除的分支的前一个
2.git rebase -I commit-id
3.修改要删除的commit的pick 为drop即可 -
如何将本地仓库和远程master仓库关联push
1.github上创建一个带有文件的仓库
2.本地已经写好一个项目,并想把它push上去
3.git init
4.git add .
5.git commit -m ""
6.git remote add upstream url
7.git fetch upstream
8.git merge upstream/master master --allow-unrelated-histories
9.git push upstream master
-
idea 不停的 updating indices
在File-Invalidate Caches / Restart中,选择Invalidate and Restart
-
idea debug的时候出现because it happened inside debugger evaluation
解决办法(虽然网上有说为什么,这是某位仁兄写的原因because it happened inside debugger evaluation,但是我按照这个思路,实在定位不到springboot中的问题,所以就不讲为什么了,直接贴解决办法。)
-
maven报错"was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced"
如图,mvn install的时候,报错。实测,将划线部分的jar包删除,重新下载即可。
-
.gitignore规则不生效的解决办法
第一条命令放心操作,不会将你提交的代码删除的(一开始我也有点慌,因为执行第一条后,git status
居然发现状态是delete
,哈哈),实测是可以的。git rm -r --cached . git add . git commit -m "update .gitignore"