JiaHe's Blog

读万卷书,行万里路

/**
* Java实现DFA算法进行敏感词过滤
*/
public class SensitiveWordUtil {
private final TrieNode root;

public SensitiveWordUtil() {
root = new TrieNode();
}

/**
* 添加敏感词
*
* @param word 词
*/
public void addWord(String word) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
node = node.getChildren().computeIfAbsent(ch, c -> new TrieNode());
}
node.setEndOfWord(true);
}

/**
* 是否在敏感词库中
*
* @param word 词
*/
public boolean containsWord(String word) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
node = node.getChildren().get(ch);
if (node == null) {
return false;
}
}
return node.isEndOfWord();
}

/**
* 是否存在敏感词
*
* @param text 文本
*/
public boolean containsSensitiveWord(String text) {
for (int i = 0; i < text.length(); i++) {
if (containsWordStartingFromIndex(text, i)) {
return true;
}
}
return false;
}

private boolean containsWordStartingFromIndex(String text, int startIndex) {
TrieNode node = root;
for (int i = startIndex; i < text.length(); i++) {
char ch = text.charAt(i);
node = node.getChildren().get(ch);
if (node == null) {
return false;
}
if (node.isEndOfWord()) {
return true;
}
}
return false;
}

/**
* 将敏感词替换为*
*
* @param text 文本
*/
public String filterWords(String text) {
StringBuilder filteredText = new StringBuilder();
StringBuilder word = new StringBuilder();
TrieNode node = root;

for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
node = node.getChildren().get(ch);

if (node != null) {
word.append(ch);
if (node.isEndOfWord()) {
char[] chars = new char[word.length()];
Arrays.fill(chars, '*');
filteredText.append(new String(chars));
word.setLength(0);
node = root;
}
} else {
filteredText.append(text.charAt(i));
node = root;
word.setLength(0);
}
}

filteredText.append(word);
return filteredText.toString();
}

public List<String> findSensitiveWords(String text) {
List<String> sensitiveWords = new ArrayList<>();
for (int i = 0; i < text.length(); i++) {
int wordEndIndex = findWordEndIndex(text, i);
if (wordEndIndex != -1) {
String word = text.substring(i, wordEndIndex + 1);
if (containsWord(word)) {
sensitiveWords.add(word);
}
i = wordEndIndex;
}
}
return sensitiveWords;
}

private int findWordEndIndex(String text, int startIndex) {
TrieNode node = root;
int endIndex = -1;
for (int i = startIndex; i < text.length(); i++) {
char ch = text.charAt(i);
node = node.getChildren().get(ch);
if (node == null) {
break;
}
if (node.isEndOfWord()) {
endIndex = i;
}
}
return endIndex;
}

private static class TrieNode {
private final Map<Character, TrieNode> children;
private boolean endOfWord;

public TrieNode() {
children = new HashMap<>();
}

public Map<Character, TrieNode> getChildren() {
return children;
}

public boolean isEndOfWord() {
return endOfWord;
}

public void setEndOfWord(boolean endOfWord) {
this.endOfWord = endOfWord;
}
}

public static void main(String[] args) throws IOException {
SensitiveWordUtil filter = new SensitiveWordUtil();
filter.addWord("敏感词1");
filter.addWord("敏感词2");
filter.addWord("敏感词3");

String text = "这是一个包含敏感词1的测试文本,敏感词2也在其中。";

String filteredText = filter.filterWords(text);
System.out.println("修正后的内容:" + filteredText);

List<String> words = filter.findSensitiveWords(text);
System.out.println("包含以下敏感词:" + words);

double asDouble = Arrays.stream(new int[10000]).mapToLong(o -> {
long dfaStartTime = System.nanoTime();
filter.containsSensitiveWord(text);
return (System.nanoTime() - dfaStartTime);
}).average().getAsDouble();
System.out.println("DFA算法耗时:" + asDouble + "纳秒");

// 使用正则表达式查找敏感词
double asDouble1 = Arrays.stream(new int[10000]).mapToLong(o -> {
long regexStartTime = System.nanoTime();
boolean regexResult = text.matches(".*(敏感词1|敏感词2|敏感词3).*");
return (System.nanoTime() - regexStartTime);
}).average().getAsDouble();
System.out.println("正则表达式耗时:" + asDouble1 + "纳秒");

System.out.println(asDouble1 / asDouble);

}
}

jmeter官方版自带的图表不多,只有聚合报告、察看结果树等有限几个。但是Jmeter支持插件,我们可以在jmeter的官网上找到这些图表的插件。

现在我需要以下图标插件

--- Response Times Over Time

--- Transactions per Second

1、我们访问 https://jmeter-plugins.org/wiki/Start/

找到需要的插件。

2、找到后,点击对应的插件名字进入详情页

这里,我点击“Response Times Over Time”

进入插件的介绍页。

3、点击“Download”,进入搜索下载页面;

为什么是搜索下载页面呢?个人【不负责任猜测】是因为这个“Response Times Over Time”是图表的名称,但是对应的jar包却不一定是这个名字,所以官网就帮我们搜索对应的jar包,如下图

这里我就被坑了很多时间,点击红色框住的“ Download Versions”,一点反应都没有,

一定要点击紫色框住的版本号“2.0”,才可以下载。

4、下载后,我们解压后放到jmeter的安装目录的相同位置,如:

lib目录下的就放到apache-jmeter-3.0\lib下

ext下的就放到apache-jmeter-3.0\lib\ext\ 下,

放后后重新Jmeter,

5、重启后,可以添加对应的图表了:

原文:https://zhuanlan.zhihu.com/p/250666652

锁是使用数据库时避不开的问题,MySQL 中的锁可以分成两个粒度:表锁和行锁。

表锁:表级读锁,表级写锁,读意向锁,写意向锁,自增锁

行锁:读记录锁,写记录锁,间隙锁,Next-key 锁,插入意向锁。

这些锁一旦冲突就会导致死锁问题的产生。

阅读全文 »