shiro快速入门
shiro的基本概念权限管理包括 ==身份认证== 和 ==授权== 两部分。
首先经过身份认证,认证通过后该用户具有权限再访问受访问控制的资源。
shiro中的认证最常见思路:核对用户名和口令。
认证的关键对象:subject,访问系统的主体。
Principal:身份信息,身份认证的标识。标识必须具有唯一性。一个主体可以有多个身份信息,但是必须有一个主身份。
credential:凭证信息,只有主体自己知道的安全信息,如密码,证书等。
认证的源码流程(想要深入了解,就从quickStart开始,一点点看源码学习,使用调试工具来看)
subject.login一定是关键的步骤:
对于下面的函数:currentUser.login(token);点击进去看看发生了什么:我们会看到底层是securityManager在做这个认证的核心流程:
1234public void login(AuthenticationToken token) throws AuthenticationException { this.clearRunAsIdentitiesInternal ...
JVM调试工具初探(jhat,jps,jstack)
jhat查看OOM产生的dump文件首先试一下java自带的工具查看一下内存溢出时候的堆文件情况:
首先到进入run选项,点击configure
然后执行下面这样一个肯定会出现堆内存溢出的程序:
12345678910111213141516package JVMTest;import java.util.ArrayList;import java.util.List;public class HeaPOOM { static class TestObject{ } public static void main(String[] args) { List<TestObject> list=new ArrayList<TestObject>(); while(true){ list.add(new TestObject()); } }}
因为配置了-XX:+HeapDumpOnOutOfMem ...
simpleDb实验一记录
exercise 1实现
src/simpledb/TupleDesc.java
src/simpledb/Tuple.java
通过
TupleDescTest
TupleTest
两个test。
结构关系最主要的难点是理清楚一个大致的结构关系。
首先看看两个类的方法,好的方法从名字就可以猜出对应的实现。
首先可以看出来,Tuple是由TupleDesc作为参数进行构造的。即每次在建立元组的时候,都要传入一个视图信息。所以先看看TupleDesc又是由什么构造的。
TupleDesc内部生命了一个静态类,TDItem。静态内部类的特点是无法调用外部类的方法。这样设计的含义是,外部类要用到该内部类,但是该内部类与外部类相对独立。
我们看看TDItem的内部结构:
1234567891011121314151617181920212223public static class TDItem implements Serializable { private static final long serialVersionUID = 1L; /** ...
漫谈jvm垃圾回收机制及垃圾回收器
Java语言的一个重要特点就是对内存的管理。
对于内存,有两个相依相存的概念,一个是内存溢出,一个是内存泄露。内存溢出即大名鼎鼎的OOM。指内存空间已经满了,无法继续分配空间,导致程序无法进行。而内存泄露本身则不一定导致程序的崩溃,它指的是已经分配的内存,在不再需要使用的时候,没有及时清理。一旦没有及时清理的内容多了,那么就可能造成OOM。
而Java对内存的管理特点,十分明显地体现在其垃圾回收机制中。这里的垃圾回收,就是上面说的已经不再需要但占据内存空间的程序对象。由于Java语言的使用场景的变迁,垃圾回收机制以及实现垃圾回收机制的垃圾回收器也有诸多的不同。
从Stop the world说起垃圾回收的一个经典概念是Stop The World,简称STW。在垃圾回收的时候,由于要对内存进行清理,如果这个时候程序还是自顾自运行,那么很可能出现问题。因此在进行垃圾回收的时候,正在运行的各个用户线程需要停止,只留下垃圾回收的线程做垃圾回收的工作。由于线程是程序世界的绝对主角,各个线程都停止了,也就相当于整个程序世界都静止了。
不过,初学JVM的时候,我有一个疑问,CMS垃圾回收器也有ST ...
ArrayList源码详解
引言ArrayList是JAVA中的经典集合类,其底层是数组队列,与普通的数组类型相比,它的容量能动态增长。
源码解析首先我们看看构造函数。构造函数有含参数的构造参数和无参数的构造参数。其中,有参数的构造函数,其中一个可以用来指定数组的大小,其实就是创建一个指定大小的数组,避免了扩容可能带来的时空损耗。
12345678910111213public ArrayList(int initialCapacity) { if (initialCapacity > 0) { //如果传入的参数大于0,创建initialCapacity大小的数组 this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { //如果传入的参数等于0,创建空数组 this.elementData = EMPTY_ELEMENTDATA; ...
HashMap源码解析
引言HashMap是java的经典类,也是面试常常问的类,因此,阅读hashmap的源码不仅可以加深我们对hashmap的了解,更能让我们学习一些设计思想和技巧。话不多说,开始看源码。
源码解析我们的源码解析以jdk1.8为主。同时可能会回顾一些jdk1.7中的hashmap的实现作为参考。
首先我们看看hashmap的几个静态变量:
1234567private static final long serialVersionUID = 362498820763181265L;static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16static final int MAXIMUM_CAPACITY = 1 << 30;static final float DEFAULT_LOAD_FACTOR = 0.75f;static final int TREEIFY_THRESHOLD = 8;static final int UNTREEIFY_THRESHOLD = 6;static final in ...
在线运行java程序网站的设计
需求:1.提供一个供用户使用的网页,该网页支持用户输入程序,然后用户可以运行程序,然后得到返回的结果。
2.该编译网站支持多个用户提交请求。
思路我们需要来考虑一下java编译网站做了什么事情。
用户在网页的栏目中编程,那么用户实质上提交的是 字符串,我们设计的系统需要对字符串进行处理,然后返回对应的结果。
首先明确一点,我们设计的是java在线编译系统,因此,至少要完成字符串到可运行程序的这个过程。
以我们在本地运行java程序进行类比,那么就相当于是我们编辑了一个.java的文件,而最终要将该文件以程序的方式运行起来。
回忆java从文件到执行文件的过程,第一步我们需要将.java这个文件变成.class文件。
实现.java—–.class的转变,一个直接的思路是调用javac命令。可以在java程序中调用javac命令吗?答案是肯定的,但是我们应该考虑到,利用javac固然可以将.java文件转换为.class文件,但是这样一次编译过程,就会产生一个class文件,我们还需要去做class文件的删除工作。而有时候可能会出现多个用户同时执行请求,这个时候就可能会出现问题;另外,通 ...
leetcode题目总结
每次做题需要检查一下的问题:1.字母拼写。看看写着写着变量名是不是写偏了。
2.while循环 for循环 还有链表里面有没有移动,循环是否可以结束。
3.如果函数的参数比较多的话,检查下函数参数有没有填对,仔细想想。
N皇后问题详解具体的思考思路如下:
1.数据结构的选择:
选用什么数据结构可以模拟出一个棋盘。联想到Z型字符串,似乎对于这种问题,利用StringBuilder的list可以用来模拟一个字符串二维序列。
为了解决这个问题,我们应当从一个空棋盘开始回溯:
12345678910111213public List<List<String>> solveNQueens(int n) { List<List<String>> res=new ArrayList<>(); List<StringBuilder> board=new ArrayList<>();//选取StringBuilder的list作为一个二维字符串序列的容器 for(int i ...
JUC学习笔记-volatile的基本使用
创建线程的三种方法
实现Runnable接口
继承Thread类
通过callable和Future创建线程
参考
Volatile的作用volatile提供了一种轻量的同步机制,其最为重要的特点为:
保证可见性
不保证原子性
禁止指令重排
可见性在多线程程序中,每个线程都会拥有一个属于自己的工作空间(栈空间)。对操作数的操作在该空间进行。但是每个线程所操作的操作数可能是同一个操作数,这个时候就需要用一种同步机制,让任何线程改变操作数的时候,都可以保证其他线程可以知道操作数的最新值。
这里的基本设计就是,每次线程改变操作数的时候,就将操作数写回到多个线程共有的主内存,然后其他线程通过主内存操作数的变化得知操作数已经发生了改变。
为了实现上述的可见性,提出了许多协议。例如MESI协议,要求CPU写公共操作数的时候,会通知其他CPU将其缓存设置为无效;而其他CPU在读的时候,如果发现CPU缓存无效,就读取主内存的值。
那么,上述的通知其他CPU将缓存设置为无效是怎么实现的呢?这里用到了总线嗅探的技术。就是CPU会监控总线传播的数据,如果发现自己缓存对应的内存地址的值发生变化,那么就读 ...