Shell的常规使用
shell的分类
/bin/bash 是我们在linux或者Mac下常用的shell
zsh 是一种增强shell,在Mac和Linux中可使用,Mac基本自带
日常文件操作
ls :显示文件
cd :进入文件夹
cp :拷贝文件
mv :重命名或迁移文件
cat :查看文件内容,并在控制台打印
head:查看文件头部信息,可指定多少行
tail :查看文件尾部信息,可指定行数,并且可跟踪日志文件
grep:查找过滤,一般用在 操作 | grep , | 表示管道符,将操作的返回的数据,通过grep进行过滤
fgrep : 无正则查询,普通查询快
egrep :有正则查看
shell的快捷键
↑ ↓ 会回显之前执行的代码。默认记录500条
ctrl + R , 快速查看之前执行的命令
ctrl + W,将已输入的命令,以空格划分,每次向前删除一部分
ctrl + U,删除已输入命令所有部分
ctrl + A,将光标移动到最前(已输入内容)
ctrl + E, 将光标移动到最后
ctrl + K,向右删除所有
ctrl + D,向右删除一位
ctrl + L ...
Ruby元编程
本文需要在了解Ruby基本语法的前提下,进行学习
元编程是什么? 元编程是编写能在运行时操作语言构件的代码
在我们使用编辑器编写代码后,代码按照我们所写的内容进行编译,运行。在启动后我们无权再对代码进行干涉,而在一些业务场景中,我们想在不修改源代码的前提下,对一个类进行增强,这在Java中也是一个成熟的技术,例如反射,动态代理。但是Java所能给予的操作相比Ruby,就显得格外的严格且复杂。
Ruby是一门可以在运行时操作语言构建的工具。语言构建就是我们代码中的各个成员(对象,类,模块儿,实例变量等)。通俗来说可以使用Ruby在运行时对已有的类进行灵活的修改,例如修改一个方法的定义。实例变量的定义,甚至我们可以在运行时创建一个没有的类。下面我们使用一些伪代码来进行演示。
我们想对数据库进行操作,最初我们的想法就是写一个Entity基类,然后由子类继承
class Entity
# 提供访问器
attr_accessor :table,:id
def initialize table,id
@table = table
@id = ...
查找算法的演化过程
查找算法的演化过程顺序查找 字面意思,一个个节点查找判断,对数据条件没什么要求,最简单,也最慢。
/**
* 顺序查找
* @param arr 数组
* @param target 目标值
* @return 下标
*/
public static int getIndex(int[] arr, int target) {
// 记录比较多少次找到目标值
int index = 0;
for (int i = 0; i < arr.length; i++) {
index++;
if (arr[i] == target) {
System.out.println("顺序查找次数:" + index);
return i;
}
}
return -1;
}
二分查找 如果我们能让数据有序,我们先找中间数,如果目标值大于中间数,则从中位数往 ...
Java内存模型与线程
Java内存模型与线程
上面的图就是线程,工作内存,主内存的关系,也可以看到线程想要获取数据,需要先到工作内存找,工作内存从主内存中找,那为啥需要这个工作内存 ? 而不直接访问主内存,也可以避免数据不一致的情况了。
这就需要我们对物理计算机中如何并发访问有一点儿了解,我们知道CPU内含有寄存器,但寄存器能存放的内容太少,而大部分时间都要从内存中获取,如果等待从内存中取得数据,CPU又被浪费了,因为两者间的速度差太多,所以引入了高速缓存。
除了增加高速缓存外,为了处理器内部的运输单元能被充分利用,处理器会对输入代码进行乱序执行,在计算后将乱序执行的结果重组,保证该结果与顺序执行的结果一致。而潜在的风险就是一个计算任务依赖另一个计算任务的中间结果,其顺序性不能靠代码的先后顺序来保证,而Java内存模型也保留了这一点,我们也可以看到上面两幅图结构是非常相似的。所以Java内存模型的定义也是由硬件决定的。
内存间交互操作 也就是图1中,线程,工作内存,主内存数据是怎么交互的,Java内存模型定义了8个操作,每个操作都是原子 ...
SQL语句: where 和 having 的区别
SQL语句: where 和 having 的区别
分组查询时,select的字段(不包含聚合函数的字段)是否一定要都在group by的字段中?
例如:
select name,age,sum(money) from user group by
上面所说情况在Mysql5.7之后:sql_mode=only_full_group_by 情况下适用,可以通过 select @@sql_mode;查询自己的sql_mode
解决方案:
修改sql_mode,删除:SET @@sql_mode = sys.list_drop(@@sql_mode, 'ONLY_FULL_GROUP_BY');(不推荐)
group by 主键字段
group by 唯一非空字段
select 字段集合 from table group by 相同字段集合
select @@sql_mode;
SET @@sql_mode = sys.list_add(@@sql_mode, 'ONLY_FULL_GROUP_BY');
SET @@sql_mode = sys.list_dr ...
手写Spring系列:IOC
IOC 我们学Java的基本上都会使用Spring进行开发,而Spring中最为核心的又是IOC和AOP,接下来的内容是在学习手写Spring渐进式源码实践这本书后的学习总结,看是否我们能开发出一个mini-Spring。因为后期代码会很多,而且基本上都是在前一版的基础上进行扩展。这里我只声明每一章的目标扩展点是啥,具体从Github上获取源码:https://github.com/fuzhengwei/book-small-spring
第一章:实现一个简单的Spring Bean容器 先不深究Spring源码,我就看自己平时使用Spring时的体会,使用Spring时,通过XML配置文件或者通过注解,声明哪些类是需要注入到容器中的,到自己使用时,可以从容器中获取该类对象。那这不就是我们基础中学的Collection或者Map就能实现的操作嘛,因为我需要频繁的从容器中获取指定类对象,所以查询返回的效率需要非常高,那就我们就用Map来实现,先不要想那么多。
public class BeanFactory {
// 用Map来存储Bean
priv ...
从单体到分布式
初级阶段(本地调用) 在我们学习java初期,我们都会通过创建一个类对象,用该对象调用自身方法,得到需要的内容。整个过程都在本地当前JVM中进行的。这样的程序是最简单,方便,快速的。后面我们又学习了面向接口编程,用接口去规范子类的行为,也就是说调用者不需要知道具体方法的实现,只调用接口即可。
再后来我们又学习了分布式调用这些高端名词,什么Dubbo,什么RPC框架,什么Zookeeper注册中心,说实话我学完还是挺懵逼的,会有种漂浮的感觉,知道它大概是个什么东西后,又说这玩意儿落伍了,让我去看看SpringCloud,Nacos之类的玩意儿,说学这个没问题。现在回想起来有种知识断层的感觉,这种感觉从普通java程序进阶为Spring框架时有,从SpringBoot到SpringCloud时也有。废话不多说了 ,我们开始理理思路吧。
import lombok.AllArgsConstructor;
import lombok.Data;
public interface Factory {
public User askEntity();
...
从 JDBC 到 ORM(例:Mybatis)
从 JDBC 到 ORM(例:Mybatis)的演化过程 下面我将介绍Java操作Mysql数据的方式的演化过程,从最基本的JDBC到ORM框架的实现,每一次演化都是为了解决现有存在的问题。
JDBC这里需要加入Mysql驱动包或者依赖.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
@Test
public void test1() throws SQLException {
// 注册驱动
Driver driver = new com.mysql.jdbc.Driver();
// 设置配置
Properties properties = new Properties();
properties.setProperty("user","root");
...
第二章:链表问题
第二章:链表问题打印两个有序链表的公共部分/**
* 给定两个有序链表的头指针head1和head2,打印两个链表的公共部分
* @param head1
* @param head2
*/
public static void printCommonPart(Node head1,Node head2) {
// 有序 则说明,我们可以用双指针思想,找到相同的点
while (head1 != null && head2 != null) {
if (head1.value > head2.value) {
head1 = head1.next;
} else if (head1.value < head2.value) {
head2 = head2.next;
} else {
// 如果相等,说明到达了公共节点
Syste ...
手写线程池
手写线程池
我们从初级阶段自己创建线程去异步执行任务,到后期使用线程池不断执行任务,原理书上都有,但都是字面意思,无法深入理解,所以打算自己进行实现。
阶段一:
new Thread(()-> System.out.println("异步执行")).start();
阶段二:
// 抽离出一个统一接口,具体实现由子类完成
interface Executor {
public void execute(Runnable r);
}
// 定义各自的子类去实现execute方法
@Slf4j
class myExecutor implements Executor {
@Override
public void execute(Runnable r) {
// 底层还是执行的 new Thread(r),虽然现在看起来是有点儿麻烦,但更方便我们进行扩展了
new Thread(r).start();
}
}
阶段三:上面我们执行一次方法就创 ...