论睁了眼看——鲁迅
虚生先生所做的时事短评中,曾有一个这样的题目:《我们应该有正眼看各方面的勇气》(《猛进》十九期)。诚然,必须敢于正视,这才可望敢想,敢说,敢作,敢当。倘使并正视而不敢,此外还能成什么气候。然而,不幸这一种勇气,是我们中国人最所缺乏的。
但现在我所想到的是别一方面——
中国的文人,对于人生,——至少是对于社会现象,向来就多没有正视的勇气。我们的圣贤,本来早已教人“非礼勿视”的了;而这“礼”又非常之严,不但“正视”,连“平视”“斜视”也不许。现在青年的精神未可知,在体质,却大半还是弯腰曲背,低眉顺眼,表示着老牌的老成的子弟,驯良的百姓,——至于说对外却有大力量,乃是近一月来的新说,还不知道究竟是如何。
再回到“正视”问题去:先既不敢,后便不能,再后,就自然不视,不见了。一辆汽车坏了,停在马路上,一群人围着呆看,所得的结果是一团乌油油的东西。然而由本身的矛盾或社会的缺陷所生的苦痛,虽不正视,却要身受的。文人究竟是敏感人物,从他们的作品上看来,有些人确也早已感到不满,可是一到快要显露缺陷的危机一朆之际,他们总即刻连说“并无其事”,同时便闭上了眼睛。这闭着的眼睛便看见一切圆满,当前的苦痛不过是“ ...
关于Java线程的启动与终止学习笔记
本文是我阅读《Java并发编程的艺术》第4章第2节所做的笔记。
在Java中,可以调用start方法启动线程,在run方法执行完毕后,线程也随之终止。接下来,将较为详细的介绍线程的启动与终止。
构造线程线程对象在构造的时候,需要提供其所需要的属性,如线程所属的线程组、线程优先级、是否是Daemon线程等信息。
一个新构造的线程对象是由其parent线程来进行空间分配的,而child线程继承了parent是否为Daemon、优先级和加载资源的contextClassloader以及可继承的ThreadLocal,同时还会分配一个唯一的ID来标识这个child线程。至此,个能够运行的线程对象就初始化好了,在堆内存中等待着运行。
启动线程线程对象在初始化完成之后,调用start()方法就可以启动这个线程。线程start()方法的含义是:当前线程(即parent线程)同步告知Java虚拟机,只要线程规划器空闲,应立即启动调用线程的start()方法。
注意: 启动一个线程前,最好为这个线程设置线程名称,因为这样在使用jstack分析程序或者进行问题排查时,就会给开发人员提供一些提示,自定义的 ...
ThreadMXBean学习笔记
ThreadMXBean是JVM线程系统的管理接口,一个Java虚拟机只有单个实现该接口的实例,该实例可通过方法ManagementFactory.getThreadMXBean() 获得。
该实例的名称是 java.lang:type=Threading,可通过它的getObjectName()方法获得。
可用该实例获得线程ID,查看线程CPU时间,线程内容监视以及同步信息及死锁检测等。
具体可查看:ThreadMXBean
Spring Security之CSRF保护
除了你自定义的过滤器外,Spring Security在过滤链上也加了自己的过滤器。
应用CSRF保护Spring Security 默认开启了csrf保护。
CSRF保护如何在Spring Security 中工作的CSRF 攻击假设用户已登录到 Web 应用程序。 他们被攻击者诱骗打开一个页面,其中包含在用户正在使用的同一应用程序中执行操作的脚本。因为用户已经登录,脚本中的伪造代码现在可以冒充用户并代表他们执行操作。
csrf保护的一种方式?
在发送某个请求(非GET方法)之前,先用GET方法发送发送一个请求,服务端正对该请求生成一个独特的标识(token)。然后服务端之接受头部含有该标识的请求(非GET方法)。
CSRF保护的起始点是过滤链中的过滤器CsrfFilter。它拦截请求,并允许使用GET,HEAD,TRACE,和OPTIONS方法的请求。对于所有其它的请求,它希望其头部有一个标识。如果没有的话,会拒绝这个请求,并把状态码设置为403。
那么这个标识是什么,它来自哪里?其实它不过是一个字符串。
CsrfFilter使用组件CsrfTokenRepository来管理生成 ...
《Java并发变成编程的艺术》学习笔记—重排序
本文是我阅读《Java并发编程的艺术》第3章第2节所做的笔记。
重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
数据依赖性如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。
我的思考:为什么?因为写操作可能会改变数据,影响另外一个操作的结果。所以,当对操作重新排序的时候,可能会使得各个操作的结果与排序前的各个操作的结果不同。重排序是为了使计算机运行指令更快而采用的一种手段,但使用这种手段也会引发一些问题,所以需要一套理论来规范如何使用该技术。例如,可以对指令进行区分,把互相之间没有联系的指令可以重新排序,有联系的则在重排序时采取某种策略(不进行排序等),使得程序运行结果与期望的一致。
对于具有数据依赖性关系的操作,不能重排序,否则会改变程序的运行结果。所以,重排序不是随便对指令进行重排序,是在保证程序结果一致情况下,对指令的重新排序。不然,结果错了,运行效率再高也枉然。所以,为了使程序执行结果一致,就需要一套规则规范重排序。
数据依赖分为下列3种类型:
上面3种情况,只要重排序两个操作的执行顺序,程序的执行结果 ...
LeetCode算法题 Basic Calculator II 小结
本文是我对算法题Basic Calculator II做的一个简单的总结。
题意大致是:给定一个表示数学表达式的字符串,计算并返回它的值。且整数除法应向零截断,这正好与Java中的整数除法一致。
我的解题思路:字符串中只有+、-、*、/四种运算符。前两者的优先度低于后两者的优先度,当前两者混合在一起满足结合律,后两者混合在一起不满足。例如:
2+2-3 = 2+(2-3)2\div2\times3 \neq 2\div(2\times3)假设表示数学表达式的字符串为s,我先去掉字符串中的空格得到s1。在以“+”为分割点,得到一个字符串数组A。
然后对于字符串数组A中每个元素,我再以“-”为分割点,得到一个字符串数组Bi。
此时,数组Bi中的字符串最多只有乘除运算符,我们可以根据相关逻辑,从左往右对它进行计算。
下面是我的实现代码:
class Solution {
public int calculate(String s) {
return helper0(s.replace(" ",""));
}
...
webpack入门教程(一)
webpack是一个管理工具,可以把你写的javascript代码编译到一个或多个文件中,可以管理你项目中的html,css,图片及字体(通过加载器和插件)等文件。
初识webpack安装webpack首先却保你已经安装nodejs及npm,并配置好相关环境变量。
为了判断软件是否已经安装好,可以在命令行输入下面这些指令进行检测,会输出相应版本信息。
$ node -v
v16.13.0
$ npm -v
8.1.0
首先,创建一个文件夹,初始化一个项目。可在命令行通过下面指令完成。
mkdir test01
cd test01
npm init -y
在文件夹test01中,会有一个package.json文件,将用于 NPM 识别项目(名称、版本、作者、主条目文件…)并处理使其运行所需的第三方依赖项。
通过在命令行输入下面指令,安装webpack
$ npm install webpack webpack-cli --save-dev
安装完成之后,会在package.json出现相关信息。如下:
"devDependencies": {
"webpack": "^ ...
LeetCode算法题 Merge Intervals 小结
本文是我对算法题Merge Intervals做的一个简单的总结。
题意是对给定的一组间隔进行处理,使得重叠的间隔合并在一起。
我的解题思路是按间隔的起始点,对间隔数组进行排序,使互相重叠的间隔集中在一起,便于合并。
怎么合并间隔呢?在遍历间隔时,根据下一个间隔是否与当前间隔重叠,来判断是否应该合并,如果是的话,不合并,并记录该间隔的起始位置。当前间隔不是指正在循环里被遍历的间隔,是指正在合并的间隔。
代码如下:
class Solution {
public int[][] merge(int[][] intervals) {
if(intervals == null || intervals.length == 0) return intervals;
Arrays.sort(intervals, (a1, a2)->{
return a1[0] - a2[0];
});
List<int[]> resul ...
Java内存模型学习笔记(一)
本文是我阅读《Java并发编程的艺术》第3章第1节所做的笔记。
并发编程模型的两个关键问题线程之间如何通信?通信是指线程交换信息的机制。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。前者是指通过读写内存中的公共状态进行隐式通信,后者是指通过发送消息显式进行通信。
线程之间如何同步?同步指用于控制不同线程的操作相对有序的机制。在共享内存并发模型中,同步是显式的;在消息传递的模型里,同步是隐式的。
在共享内存模型中,必须显示指定哪些方法是线程互斥执行;而对于消息传递,在一问一回的模式下,已经有了先后顺序,所以已经是同步了。
Java内存模型抽象结构在Java中,所有实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享。局部变量,方法定义参数和异常处理器参数不会在线程之间共享,它们不会有内存可见性问题,也不受内存模型的影响。
能被多个线程访问的资源是共享资源,在多线程编程中,需要对其进行控制。面对只有一个线程访问的资源,不需要怎么处理。
Java线程之间的通信由Java内存模型(本文简称为JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。
从抽象 ...
Spring Security Filter 学习笔记
过滤器可以简单理解成用于拦截请求,并执行相应逻辑的代码。
在Spring Security架构中实现过滤器在SpringSecurity中,可以通过实现 javax.servlet 包中的 Filter接口构造过滤器。
我们通过实现Filter 接口的doFilter() 方法,执行相关逻辑。该方法包含三个参数:
ServletRequest:表示http请求,可用它获得请求相关信息。
ServletResponse:表示http响应,可向它添加相关信息,最后传回客户端。
FilterChain:表示过滤链,用于把请求和响应转发到过滤链上的下一个过滤器。
Spring Security为我们提供了一些过滤器实现,例如:
BasicAuthenticationFilter:用于http认证。
CsrfFilter:用于跨请求保护。
CorsFilter:负责跨域资源共享 (CORS) 授权规则。
多个过滤器集合在一起形成一条过滤链,它们之间有一定顺序。你可以通过存在于过滤链上的一个过滤器,在它的相对位置添加一个新的过滤器。
在过滤链上的一个过滤器前面,添加一个新的过滤器可以通过 ...