安利一个好用的IDEA插件 object-helper-plugin
一. 插件背景object-helper 插件是一个日常开发工具集插件,提供丰富的功能,最开始是基于 GenerateO2O 插件开发而来,它提供了对象之间值拷贝代码自动生成的能力,就像这样:
因为它很早之前就停止维护了,新版本IDEA无法使用该插件,所以自己参考它的交互模式,基于新版本API开发了初版 object-helper-plugin插件,再次感谢 GenerateO2O 的作者。
根据日常开发中的痛点,object-helper-plugin 插件不断迭代,提供着我们的开发效率。
欢迎大家在 Issues 中提出宝贵意见,也可以联系我成为一名插件开发者,共同完善插件的功能。
object-helper插件源码:object-helper-plugin
二. 插件下载方式一:
官网下载:ObjectHelper - IntelliJ IDEs Plugin | Marketplace (jetbrains.com)
方式二:
插件市场搜索 “ObjectHelper”
方式三:
Github下载最新安装包,拖入IDEA即可:object-helper-plugin
二. ...
详解 XSS 攻击原理
跨站脚本攻击(Cross Site Scripting)本来的缩写为CSS,为了与层叠样式表(Cascading Style Sheets,CSS)的缩写进行区分,将跨站脚本攻击缩写为XSS。因此XSS是跨站脚本的意思。
XSS跨站脚本攻击(Cross Site Scripting)的本质是攻击者在web页面插入恶意的script代码(这个代码可以是JS脚本、CSS样式或者其他意料之外的代码),当用户浏览该页面之时,嵌入其中的script代码会被执行,从而达到恶意攻击用户的目的。比如读取cookie,token或者网站其他敏感的网站信息,对用户进行钓鱼欺诈等。比较经典的事故有:
一. 存储型XSS攻击1.1 攻击原理存储型XSS又称为持久型XSS,是指:攻击者将XSS代码发送给了后端,而后端没有对这些代码做处理直接存储在数据库中。当用户访问网站时,又直接从数据库调用出来传给前端,前端解析XSS代码就造成了XSS攻击。
存储型 XSS 的攻击步骤:
攻击者将恶意代码提交到目标网站的数据库中。
用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
用户 ...
计算机算法的本质(转)
最近忽然想起自己很久没有刷过算法题了,在 Leetcode 上捡了几题刷了一下,发现手确实生了,看到了 labuladong 大佬对数据结构和算法的理解比较深入,故做此记录。
如果要让我⼀句话总结,我想说算法的本质就是「穷举」。
这么说肯定有人要反驳了,真的所有算法问题的本质都是穷举吗?没有例外吗?
例外肯定是有的,比如前几天我还发了 一行代码就能解决的算法题,这些题目类似脑筋急转弯,都是通过观察,发现规律,然后找到最优解法,不过这类算法问题较少,不必特别纠结。再比如,密码学算法、机器学习算法,它们的本质确实不是穷举,而是数学原理的编程实现,所以这类算法的本质是数学,不在我们所探讨的「数据结构和算法」的范畴之内。
顺便强调下,「算法工程师」做的这个「算法」,和「数据结构与算法」中的这个「算法」完全是两码事, 免得⼀些初学同学误解。
对前者来说,重点在数学建模和调参经验,计算机真就只是拿来做计算的工具而已;而后者的重点是计算机思维,需要你能够站在计算机的视角,抽象、化简实际问题,然后用合理的数据结构去解决问题。
所以,你千万别以为学好了数据结构和算法就能去做算法工程师了,也不要以为只 ...
超大规模流量热点key读问题解决思路
在程序中使用缓存技术,不仅能够提升系统整体的响应速度,还能在一定程度上有效降低关系数据库的负载压力。尽管对 Redis 进行 Cluster后可以理论上认为容量是可以无限延伸的,并且数据的读/写操作经过了水平化处理,不同的key均会落到不同的缓存节点上,以此避免所有的用户流量都集中落到同一个缓存节点上。但是对于限时抢购场景下的热卖商品来说,由于单价比平时更给力、更具吸引力,那么自然会比平时吸引更大的流量进来,这时同一个key必然会落到同一个缓存节点上,因此分布式缓存在这种情况下一定会出现单点瓶颈。
笔者举一个贴近生活的例子,某明星出轨的消息很容易引爆流量,有可能随着事件的发酵会在接下来的一周内稳坐各大新闻版面头条。单从技术细节上来分析,假设这条消息存储在分布式缓存中,但由于消息是缓存在固定的 Slot 上的,尽管缓存系统单点支撑 10w/s 的 QPS 没有任何压力,但是在短短几分钟内,光是用户留言就达到了上百万条,更别说是阅读这条消息时所产生的流量,因此分布式缓存的单点容量容易瞬间被撑爆,导致资源连接耗尽。为了解决分布式缓存存在的单点瓶颈,我们通常可以通过以下两种 ...
详解Spring循环依赖
一. 从类加载说起Java中的类加载器负载加载来自文件系统、网络或者其他来源的类文件。jvm的类加载器默认使用的是双亲委派模式。三种默认的类加载器Bootstrap ClassLoader、Extension ClassLoader和System ClassLoader(Application ClassLoader)每一个中类加载器都确定了从哪一些位置加载文件。于此同时我们也可以通过继承 java.lang.classloader 实现自己的类加载器。
Bootstrap ClassLoader:负责加载JDK自带的rt.jar包中的类文件,是所有类加载的父类
Extension ClassLoader:负责加载java的扩展类库从jre/lib/ect目录或者java.ext.dirs系统属性指定的目录下加载类,是System ClassLoader的父类加载器
System ClassLoader:负责从classpath环境变量中加载类文件
1.1 双亲委派当一个类加载器收到类加载任务时,会先交给自己的父加载器去完成,因此最终加载任务都会传递到最顶层 ...
详解Spring SPI机制
一. 从类加载说起Java中的类加载器负载加载来自文件系统、网络或者其他来源的类文件。jvm的类加载器默认使用的是双亲委派模式。三种默认的类加载器Bootstrap ClassLoader、Extension ClassLoader和System ClassLoader(Application ClassLoader)每一个中类加载器都确定了从哪一些位置加载文件。于此同时我们也可以通过继承 java.lang.classloader 实现自己的类加载器。
Bootstrap ClassLoader:负责加载JDK自带的rt.jar包中的类文件,是所有类加载的父类
Extension ClassLoader:负责加载java的扩展类库从jre/lib/ect目录或者java.ext.dirs系统属性指定的目录下加载类,是System ClassLoader的父类加载器
System ClassLoader:负责从classpath环境变量中加载类文件
1.1 双亲委派当一个类加载器收到类加载任务时,会先交给自己的父加载器去完成,因此最终加载任务都会传递到最顶层 ...
一文搞懂 Spring Bean 的生命周期
一. 前言在学习Spring框架的IOC、AOP两大功能之前,首先需要了解这两个技术的基础——Bean。在Spring框架中,Bean无处不在,IOC容器管理的对象就是各种各样的Bean。理解Bean的生命周期有助于我们更好的理解和使用Spring框架的IOC功能,也有助于我们理解框架如何初始化、使用和管理Bean。接下来我们通过代码实现观察 BeanFactory 与 ApplicationContext 中bean的生命周期。
二. BeanFactory中Bean的生命周期Bean 的生命周期概括起来就是 4 个阶段:
实例化(Instantiation)
属性赋值(Populate)
初始化(Initialization)
销毁(Destruction)
在四个阶段中,Spring框架会向外暴露多个扩展点,此时业务代码可以根据情况,从不同的扩展点切入影响Bean的默认创建行为。
其中橙色和绿色的是容器级别生命周期接口,也就是所有的Bean初始化时都会发生作用。主要包含两个接口InstantiationAwareBeanPostProcessor、BeanPostProc ...
布隆过滤器在缓存系统中的实践
一. 背景在业务开发中,如果遇到并发量很高的情况下,通常会使用缓存对系统查询性能进行优化,在缓存命中率很高的情况下,缓存的使用能够大幅提升系统查询性能。但是在缓存命中率非常低场景下,如果采用传统缓存读取模式,大部分的请求会穿透至数据库,造成数据库的巨大压力。
例如:最近上线一个“贵族”功能,由于贵族价格比较贵,拥有比较强的特权,该功能也主要面向平台头部大R用户,所以如果采用传统的缓存模式,查询一个用户的贵族信息就会大概率出现缓存无法命中去读库的情况。
有些同学可能会将“空结果”缓存至数据库,这样下次去查询该用户的结果时就会命中缓存。但是由于平台巨大的用户量,如果将所有用户的空结果进行缓存成本是非常高的。
此种场景就非常适合使用布隆过滤器去解决缓存命中率低的问题。
二. 什么是布隆过滤器本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。
相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的, ...
开发中你不得不知的一个Git小技巧
一. 背景在工作中大家应会碰到需要频繁在两个分支中切换工作的情况,我们通常做法是利用git stash命令暂存当前工作区中的变更,然后git checkout到目标分支中工作,工作完成后回到刚刚分支使用git stash pop命令还原历史工作区变动。
整体流程大致如下:
12345678910111213141516171819202122232425262728293031323334# 当前工作分支,存在变更$ worktree-test (dev1) git statusOn branch testChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: bbb.txtno changes added to ...
tcc-transaction源码详解
本文主要介绍TCC的原理,以及从代码的角度上分析如何实现的;不涉及具体使用示例。本文通过分析tcc-transaction源码带大家了解TCC分布式事务的实现原理。
需要注意的是,本文所有代码都基于master-1.7.x分支,不同版本的源码会存在一定的差异。完整代码注释请参考:bigcoder84/tcc-transaction
一. 概述1.1 项目模块本文对 tcc-transaction 源码分析。主要涉及如下四个模块:
tcc-transaction-core:tcc-transaction 底层实现。
tcc-transaction-api:tcc-transaction 使用 API。
tcc-transaction-spring:tcc-transaction 对 Spring 的支持。
tcc-transaction-dubbo:tcc-transaction 对 Dubbo 的支持。
本文基于tcc-transaction 1.7.x版本源码进行分析。
1.2 tcc-transaction中的概念在详细分析框架源码之前,我们先熟悉 tcc-trans ...