java并发编程实战--第一部分 基础知识
二、线程安全性核心在于要对状态访问进行管理,特别是共享、可变的。
共享意味着变量可以由多个线程进行访问,可变意味着变量的值发生变化。
java同步机制是关键词synchronized,他提供一种加锁方式,但同步术语还得volatile。
修复线程安全的方式:
不在线程之间共享该状态变量
将状态变量修改为不可变的变量
在访问状态变量时使用同步
2.1线程安全性当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。
大多数Servlet对象时无状态的
无状态对象一定是线程安金的。只有当Servlet在处理请求时需要保存些信息,线程安全性才会成为一个问题。由于线程访问无状态对象的行为并不会影响其他线程中操作的正确性,因此无状大多数Servlet都是无状态的,从而极大地降低了在实现Servlet线程安全性时的复杂性。
2.2 原子性当在无状态对象中增加一个状态,如命中计算器,来统计所处理的请求数量。当对一个值,进行修改时,操作并不是原子性的,包括“读取-修改-写入”。在并发编程中执行时序不正确的结果是一种非常重要的情况,他有一个正式的名字:竞态条件。
2.2. ...
shiro
Shiro一、权限的管理1.1 什么是权限管理基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。
权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。
1.2 什么是身份认证身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。
1.3 什么是授权授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的
2.什么是shiro
Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authenticatio ...
redis
一、redis数据结构/获取帮助, 可以使用Tab键来切换 help 命令名称 help @组名
字符串类型string是redis中最基本的数据类型,一个key对应一个value。
String类型是二进制安全的,意思是 redis 的 string 可以包含任何数据。如数字,字符串,jpg图片或者序列化的对象。
string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算。
redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响。
注意:按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis 数值上限范围,将报错。 9223372036854775807(java中long型数据最大值,Long.MAX_VALUE)
tips:
redis用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性
此方案适用于所有数据库,且支持数据库集群
字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体使用 JSON 序列化 ...
笔试
脚本语言和编译语言抽象的级别不同:脚本语言更抽象。在脚本语言中,存在有高级的数据结构,如列表和字典结构,和对这种结构简单方便的嵌套和操作。编译语言有比较明确的定义等等。
类型定义不同:脚本语言对类型的定义就比较松散,不需要类型声明,而且在运行时自动进行动态类型检查。而编译语言通常是强类型定义或静态定义,也就是说变量的类型在程序中指定了。
执行方式不同:脚本语言是解释成指令被立即执行。这样完全将编译过程从编辑-编译-运行循环中去掉了。而编译语言的程序被编译成可执行的二进制。
运行速度不同:脚本语言是解释执行的,在运行时解释每一条语句然后执行。这样比编译执行的语言要慢。而编译语言因为编译成机器码,可以直接运行,所以在运行速度上快比较快。
绿盟
给定年月日计算是那一天123456789101112131415161718192021222324252627282930313233343536373839404142434445public class Day { public static void main(String[] args) { Scanner input = new Scanner(System.in); while (input.hasNext()){ int year = input.nextInt(); int month = input.nextInt(); int day = input.nextInt(); int daysInYear = getDaysInYear(year, month, day); System.out.println(daysInYear); } } pri ...
Git
Git1.SVN和Git集中式(svn):svn存放的是差异,每次回滚的速度慢
优点:代码放在单一的服务器,便于项目的管理。
缺点:
服务器宕机:代码得不到保障
服务器炸了:整个项目的历史记录丢失
分布式(git):每次存放的都是项目的完整快照,需要磁盘空间相对大一点。
客户端并不只是提取最新版本的文件快照,而是把代码仓库完整的镜像下来。
存放的不是版本和版本直接的差异,他存放的是索引(所需磁盘空间最小)
2. 初次运行 Git 前的配置Git 提供了一个叫做 git config 的工具(译注:实际是 git-config 命令,只不过可以通过 git 加一个名字来呼叫此命令。),专门用来配置或读取相应的工作环境变量。而正是由这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:
/etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config ...
Spring知识点
Spring 的理解Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。
Spring 容器的主要核心是:
控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 spring 提供的对象就可以了,这是控制反转的思想。
依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等。公用操作处理的过程就是面 ...
Spring循环依赖
Spring循环依赖12345678spring循环依赖---属性注入---自动注入spring bean的生命周期springbean实例化的大概过程spring循环依赖spring中循环依赖是如何解决的 spring中是默认支持循环依赖的 这么证明他是默认支持的?这么关闭循环依赖 spring解决循环依赖的细节--源码
配置一个循环依赖
1234567891011121314151617181920212223242526272829//配置类@ComponentScan("com.lq")public class AppConfig {}@Componentpublic class IndexService { @Autowired private UserService userService; public IndexService(){ System.out.println("IndexService"); } public void ...
mysql高级
MySQL高级一、索引B+ Tree 原理b+树演示: https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html
1. 数据结构B Tree 指的是 Balance Tree,也就是平衡树。平衡树是一颗查找树,并且所有叶子节点位于同一层。只有叶子节点存储数据。
B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具有 B Tree 的平衡性,并且通过顺序访问指针来提高区间查询的性能。
在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。
2. 操作进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。
插入删除操作会破坏平衡树的平衡性,因此在进行插入删除操作之后,需要对树进行分裂、 ...