设计模式-责任链模式
责任链模式(Chain of Responsibility)客户端对象发起请求,请求由下一个对象往下传递,直到被处某一个对象处理了此请求。客户端对象不需要知道是哪个节点进行了处理。这就可以在不景响客户端对象的情况下动态地重新组织和分配责任。
白话:一条对象链调下去。A->B->C->DA 持有 B 的引用,B 持有 C 的引用,C 持有 D 的引用。开始执行A的逻辑,A能处理就处理了,不能处理就拿着B的引用,调用B去处理。整个逻辑就是这样一直往下去推。
1.角色抽象处理者(Hand):处理请求的接口。所有处理者都实现这个接口。接口可以定义出一个方法以设定和返回对下家的引用。通常由抽象类或接口实现。具体处理者(ConcreteHandler)具体处理者接到请求后可以选择将请求处理掉,或者将请求传给下家。因为具体处理都持有下家的引用。
2.处理顺序可线性,可循环。
1.手动构建责任链这种方式,我觉得挺low的,需要手动构建,不过在刚学习的时候,还是可以帮助理解。需要角色:
Handler
Handler实现类
12345678910111213141516171819 ...
java反射04-获取方法调用栈
前言实际开发中,有多个接个有多个实现类时,搞不清调用栈,可以用这个方法来查看。
实现实现方式,通过拿到当前线程的所有调用栈信息,再遍历输出即可,虽然简单吧,但是实用呀,有时候一个方法报错了,没有异常调用栈,就比较难受了,加上这个方法,自己打调用栈。
获取方法调用栈方式:
1Thread.currentThread().getStackTrace();
代码比较简单,如下:
12345678910111213141516171819202122232425262728293031323334public class Test { public static void main(String[] args) { //打印所有调用栈 testInvoke(); } public static void testInvoke() { defaultTag(); } private static String defaultTag() { StackTraceElement[] stackTrace ...
C-指针的初始化
前言必须初始化才可以使用,未经初始化的指针会产生一个垃圾数据,这个数据是胡乱读取到的。不初始化先危险
初始化反例使用指针必须初始化,否则报错。
123int *p;//错误,必须先初始化*p = 5;
NULL 空指针在 stdio.h 头文件中 NULL 是常量,表示不指向任何地址。if point == NULL 判断指针有没有被使用过。
1234//表示内存为 Ox000000;int *p//访问冲突,0x000000 是操作系统使用的。= NULL;*p = 5;
VS 会报错,未经初始化的变量,但是有的IDE是不会报错的。
C-指针类型不兼容
类型不兼容不同类型的指针不可以赋值。否则赋值后,编译可以通过,但是执行后数据会变量错误数据。
1234567int a = 32138;//合法int *p = &a;//合法,但是问题就在这里char *p1 = p;printf("%d,%d", *p, *p1);printf("\n%d,%d", sizeof(*p), sizeof(*p1));
指针都是4个字节存,这个没问题,问题在取,取的时候根据什么类型,就会读多大的长度,如果是 int *则会读4个字节,如果是 char *类型,则只会读一个字节,数据错误。
在 vs 上重现不出来,vs 直接报 类型不兼容。
C-一级指针简单理解
两个关键符号&: 取内存地址符*: 取内存值符
指针的操作规律
1.声明的时候是往里放地址 int *p = &num,2.直接拿的时候就是直接操作地址内的值 *p = 10;
在 C 中操作地址就可以操作值,就跟 java 中两个引用类型拿到引用可以操作内一个对象一样。
123变量名 内存地址 值a [0x23fa32] 100*p [0x24aa34] [0x23fa32]
指针存放的是 a 的内存地址,&p则是自己的内存地址 [0x24aa34]
创建一个针指并使用12345678void main() { int num = 100; //将内存地址给 *p int *p = # printf("%x, %x",&num, &p); *p = 10; printf("%d", num); //10}
分析过程:根据拿到的直址 分别查看 &num,和 &p。&num 的地址以 带符号 4 ...
竟态条件 racing condition
竟态条件 racing condition多个线程读时,线程是安全的。当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。我的理解,竞态条件就是一种情况。
代码示例假设有 A、B 两个线程,调用 add 方法分别传入 1 和 2,理想条件下结果应该是 3。现在出现了不安全的情况,有可能结果不对。add 方法就是临界区,count 就是同一资源。
123456class Counter { protected long count = 0; public void add(long value) { this.count = this.count + value; } }
其实这样一看,说白了,就是要严格控制线程的执行顺序,假设是按A、B的顺序执行来讲,B依赖于A先执行完成,B再执行结果才是正确的,中间不能出现问题,否则如果,中间交叉执行,就有可能发生了竞态条件。
checkout 检出和切换
这个命令是个多功能的命令用法很灵活。切换分支、撤消修改下面文中是 -- 两个杠框是连在一起,中间没有空格,因为字体太小,所说中间给个空格看着明显一些。
1.切换分支
git checkout <name>
2.创建并切换分支
git checkout -b <name>这其实可以拆解成两步操作 -b 应该就是branch
3.撤销工作区修改实际就是“以旧换新”的操作有两种情况:1.如果未添加到暂存区,则把版本库中的最新版本覆盖2.如果已添加到暂存区,则把暂存区中的修改拿出覆盖
撤销工作区修改:
git checkout -- <file>
git checkout -- .
4.连招假如有一个文件,做了修改,但是不确定后面的修改是不是想要的。先添加到暂存区中,过了一会这个修改是不想要的,想要把工作区的文件从暂存区撤回覆盖。
git add //放一份当前写到一半觉得没问题的放到暂存区中
git checkout - - file //将 版本库 中的修改替换到 工作区中没有 add 的情况 ...
java 注解简述
前言注解(annotation)相当于一个运行于内存当中的自定义类型的数据存储区域,理解以后才发现它的好用,就是数据存储区,相当于一个运行在内存当中的XML,所有的注解数据在JDK加载完类以后,就可以被使用。
JDK内置注解三个基本内置注解:1.@override2.@Deprecated //加在类或方法上,标注为过时3.@SuppressWarnings //制编译器
元注解 MetaData元注解使用和创建注解的方式,让自己可以创建自己的注解。元数据/元注解作用:就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation 类型作说明。
Java5.0定义的元注解:@Documented 标记生成javadoc@Inherited 标记继承关系@Retention 注解的生存期@Target 标注的目标
@Target 注解说明了Annotation所修饰的对象范围:
Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)
类型成员(方法、构造方法、 ...
简单说明 lock 锁和 Condition 的操作
作用:使当前线程进入等待状,并交换执行执,等待被交换的当前执行线程唤醒,才可以继续执行,如果不被唤醒?场景:多个线程操作同一个共享资源时使用。
Condition 是执行条件。类似传统技术中的 wait 的 notify 功能。Condition 是基于一个 lock 而存在。注意的是,Condition 的创建来自同一个 lock 对象,
Condition 也行 wait 也好,套路就是使用三个工具来完成三步套路。即,用两个线程,同时跑两个代码,并且用 while 不段的去读取一个条件,来判断自己是否应该唤醒对方。
步骤:
先lock住
通过 lock 拿到 condition。再进行操作如 await
然后多个线程开始 await、single注意 await 会释放锁。
1await()的作用是能够让其他线程访问竞争资源,所以挂起状态就是要释放竞争资源的锁。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585 ...
git push的一些总结
git pull拉取并合并远程代码
git pull <远程主机名> <远程分支名>:<本地分支名>
1.拉取next 分支 拉到 本 master。
git pull origin fast:master把远程的
2.拉取到当前分支省略定法,表示拉取并合并自当前分支
git pull origin fast
3.等价上面的操作
git fetch origingit merge origin/fast
4.手动建立跟踪跟踪不是只能跟踪 master,可以指定本地和远程不同的分支。意义在于可以使用简化命令 git push/pull,而不需要显示指定的版本库。
git branch --set-upstream master origin/fastgit branch --set-upstream develop origin/develop