什么是 IoC?什么是 DI?它们之间是什么关系?
什么是控制反转(IOC)Ioc—Inversion of Control,即“控制反转”,它是一种设计思想,并不是什么技术;在 Java 中,IOC 意味着将我们设计好的对象交给容器控制,而不是传统的需要时在内部构造直接控制;
谁控制谁?控制了什么?
谁控制了谁: IoC 控制了对象;
控制了什么: 主要控制了外部资源的获取,不仅限于对象,包括文件等资源;
什么为正转?什么为反转?
正转:在我们需要某个对象的时候,需要自己主动的去构建对象以及其所依赖的对象;
反转:在我们需要某个对象的时候,只需要在 IoC 容器中获取所需对象,无需关心创建过程以及其中的依赖对象;全盘由 IoC 容器帮我们创建对象以及注入其所依赖的对象,在这里我们把对象的控制权反转给了 IoC 容器,所以称为反转;
举个例子在现实生活中,当我们要用到一样东西的时候,第一反应是去找到这样东西,当我们想吃红烧肉的时候,如果没有饭店的支持,我们需要准备:肉、油、白砂糖、佐料等等一系列东西,然后自己去做,在这个过程中,所有的东西都是自己创造的这个过程称为正转;
然而到了今天,生活变好了加上互联网的兴起,当我们想吃红 ...
为什么StringBuilder是线程不安全的?StringBuffer是线程安全的?
面试中经常问到的一个问题:StringBuilder和StringBuffer的区别是什么?我们非常自信的说出:StringBuilder是线程不安全的,StirngBuffer是线程安全的面试官:StringBuilder不安全的点在哪儿?这时候估计就哑巴了。。。
分析StringBuffer和StringBuilder的实现内部是和String内部一样的,都是通过 char[]数组的方式;不同的是String的char[]数组是通过final关键字修饰的是不可变的,而StringBuffer和StringBuilder的char[]数组是可变的。
首先我们看下边这个例子:
123456789101112131415public class Test { public static void main(String[] args) throws InterruptedException { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i & ...
Java实践-远程调用Shell脚本并获取输出信息
1、添加依赖12345678910<dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>262</version></dependency><dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version></dependency>
2、Api说明
首先构造一个连接器,传入一个需要登陆的ip地址;
1Connection conn = new Connection(ipAddr);
模拟登陆目的服务器,传入用户名和密码;
1boolean isAuthenticated = conn ...
浅谈关于SQL优化的思路
零、为什么要优化
系统的吞吐量瓶颈往往出现在数据库的访问速度上
随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢
数据是存放在磁盘上的,读写速度无法和内存相比
一、观察MySQL优化≠SQL语句优化,理解这一点非常重要,虽然大部分时候我们都在调优SQL语句。
然而,MySQL的优化却是始于观察,而且有时候观察几分钟,几小时就能得出结论的,可能要观察一天以上。
这么做的目的很明显,就是为了帮助我们定位问题所在。比如:MySQL的负载会在固定的某个时间节点突然暴涨,或者一请求某几个页面就产生了较为明显的延迟,甚至影响了随后的各个请求等。
观察的手段有多种多样,阿里云有强大的RDS控制台,也可以自建一套监控平台,最次的就是临时跑个shell脚本,收集MySQL运行状况。观察的指标也不尽相同,最知名的 show status 命令列出的指标就能不下200个,所以观察也要有所取舍。经常受人关注的指标有当前连接数以及最大连接数,当前运行的线程数,慢查询数量等。
二、分析将观察的结果做进一步分析,也就形成了不同的解决思路。
可能是某个时间节点缓存失效,导致MySQL的负载激增 ...
Docker搭建Zookeeper&Kafka集群
前排提示:最新的docker-compole.yml请去github获取,README有相应的操作步骤。Github地址:https://github.com/JacianLiu/docker-compose
最近在学习Kafka,准备测试集群状态的时候感觉无论是开三台虚拟机或者在一台虚拟机开辟三个不同的端口号都太麻烦了(嗯。。主要是懒)。
环境准备一台可以上网且有CentOS7虚拟机的电脑
> 为什么使用虚拟机?因为使用的笔记本,所以每次连接网络IP都会改变,还要总是修改配置文件的,过于繁琐,不方便测试。(通过Docker虚拟网络的方式可以避免此问题,当时实验的时候没有了解到)
# Docker 安装
> 如果已经安装Docker请忽略此步骤
Docker支持以下的CentOS版本:
CentOS 7 (64-bit):要求系统为64位、系统内核版本为 3.10 以上。
CentOS 6.5(64-bit)或更高的版本:要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。
CentOS 仅发行版本中的内核支持 Docker。
yum安装Docker 要 ...
链表
开篇问题问题:如何用链表来实现 LRU 缓存淘汰策略呢?
## 链表的作用
链表一个经典的应用场景就是LRU缓存淘汰算法;
缓存是一种提高数据读取性能的技术,在开发中有着非常广泛的应用,由于缓存的大小有限,当缓存被占满时,哪些数据应该被清理,哪些数据应该被保留?这就需要淘汰策略来决定,常见的淘汰策略有三种:先进先出策略FIFO(First In, First Out)、最少使用策略LFU(Least Frequently Used)、最近最少使用策略LRU(Least Recently Used)。
打个比方:假如说你买了很多书籍,但有一天发现书太多了,太占空间,你要做个大扫除。那么这个时候你会选择扔掉哪些书籍?对应一下,其实就是我们上边说的三种策略;
什么是链表?为了理解起来更容易,我们拿数组来做对比;
相比数组,链表是一种稍微复杂一点的数据结构。从底层的存储结构上来看:数组需要一块儿连续的内存空间,堆内存的要求比较高,如果我们申请一个100MB大小的数组,当内存中没有连续的、足够大的空间的时候,即便内存的剩余总可用空间大于100MB,仍然会申请失败;而链表恰恰相反,它并不需要 ...
记录一次由于线程使用不当引发的血案
背景最近给第三方做了一个接口,接口的作用是接收数据对数据进行验证之后通过kafka推送到模型进行数据处理,最终通过kafka接收模型的数据,开始只做了一个异步的接口,由于对方业务原因需要一个同步的接口传输数据,但是每当运行一段时间之后程序就会进入假死状态,接口无法正常调用;
同步接口同步接口的实现是使用阻塞Map,当对方发送请求时,对数据进行验证,然后推送到模型,等待结果返回之后将处理好的数据推送到对方接口,此时这次请求给调用方返回相应信息;
思路开始认为是由于用户量过大导致内存不足引发的程序假死,使用JMeter进行压力测试异步接口模拟10000个请求同时调用接口,程序如丝滑般运行,没有丝毫问题,所有请求都正常返回(这里由于在家里通过VPN连接的公司开发服务器,网络不稳定,所以就拿少量测试用例为例);
然后开始怀疑是不是同步接口出了问题,刚开始模拟少量请求,因为当时是在开发环境进行测试,模型并没有放上去,所以没有返回信息,一直在等待模型的返回结果,也是没有问题的,这时候调用异步接口也没有任何问题;
思考:所有资源都是阻塞状态,因为没有处理结果,一直没有释放进程,当数据过大时会 ...
数组
问题:为什么数组下标是从0开始,而不是从1开始;
### 什么是数组?
数组是一种线性表数据结构,它用一组连续的内存空间来存储一组相同类型的数据。
线性表结构:数据排成一条线一样的结构,每个线性表上最多只有前和后两个方向,除数组外,链表、队列、栈也是线性结构。
非线性结构:比如:二叉树、图、堆等,在非线性结构中,数据之间并不是简单的前后关系。
连续的内存空间和相同类型的数据:正式因为这两个特性,才有了它的一大特性:“随机访问”;缺点:在数组中要进行删除或者插入操作需要进行大量的迁移工作,效率低下;
关于数组的随机访问:例如一个长度为10的int类型的数组 int a[] = new int[10];在下图中,计算机给数组 a[10]分配了一块儿连续的内存空间 1000~1039;其中,内存的首地址 base_address=1000
我们知道,计算机会给每一个内存单元分配一个地址,通过地址来访问到内存中存储的数据;当计算机需要随机访问数组中的元素时,会根据如下的公式找出该元素存储的内存地址:
1a[i]_address = base_address + i * data_t ...
基于Hexo&GitHub从零搭建个人博客
现在越来越多的人喜欢利用Github搭建静态网站,原因不外乎简单省钱。本人也利用hexo+github搭建了本博客,用于分享一些心得。在此过程中,折腾博客的各种配置以及功能占具了我一部分时间,在此详细记录下我是如何利用hexo+github搭建静态博客以及一些配置相关问题,以免过后遗忘,且当备份之用。
准备工作
下载&安装node.js,默认会安装npm:https://nodejs.org/zh-cn/
下载&安装git:https://git-scm.com/downloads
下载安装hexo。方法:打开cmd 运行npm install -g hexo
本地搭建hexo静态博客
新建一个文件夹,如blog
进入该文件夹内,右击运行git,输入:hexo init(生成hexo模板)
生成完模板,运行npm install(目前貌似不用运行这一步)
最后运行:hexo s (运行程序,访问本地localhost:4000可以看到博客已经搭建成功)
目录介绍1234567891011121314├── _config.yml // 博客配置文 ...
基于Netty-SocketIO的主动推送服务
背景前端时间,公司开发了一款主动服务的机器人的程序,讲产生的消息通过服务端主动推送到客户端(H5、IOS、Android),支持用户的个性化开关设置,用户可自由选择接受的消息类型;同时支持用户主动提问;在此记录下整个部署以及实现的大致思路;
同时感谢我的Leader给予的帮助。
部署Nginx配置
为了保持长连接有效,配置HTTP版本1.1;
配置Upgrade和Connection响应头信息;
完整配置如下:
12345678location / { proxy_pass http://nodes; # enable WebSockets proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";}
Socket配置Socket配置类
123456789101112131415161718192021222324252627282930313233343536 ...