最后我们该如何学习?
1、看视频进行系统学习
这几年的Crud经历,让我明白自己真的算是菜鸡中的战斗机,也正因为Crud,导致自己技术比较零散,也不够深入不够系统,所以重新进行学习是很有必要的。我差的是系统知识,差的结构框架和思路,所以通过视频来学习,效果更好,也更全面。关于视频学习,个人可以推荐去B站进行学习,B站上有很多学习视频,唯一的缺点就是免费的容易过时。
另外,我自己也珍藏了好几套视频资料躺在网盘里,有需要的我也可以分享给你:
2、读源码,看实战笔记,学习大神思路
“编程语言是程序员的表达的方式,而架构是程序员对世界的认知”。所以,程序员要想快速认知并学习架构,读源码是必不可少的。阅读源码,是解决问题 + 理解事物,更重要的:看到源码背后的想法;程序员说:读万行源码,行万种实践。
Spring源码深度解析:
Mybatis 3源码深度解析:
Redis学习笔记:
Spring Boot核心技术-笔记:
3、面试前夕,刷题冲刺
面试的前一周时间内,就可以开始刷题冲刺了。请记住,刷题的时候,技术的优先,算法的看些基本的,比如排序等即可,而智力题,除非是校招,否则一般不怎么会问。
关于面试刷题,我个人也准备了一套系统的面试题,帮助你举一反三:
只有技术过硬,在哪儿都不愁就业,“万般带不去,唯有业随身”学习本来就不是在课堂那几年说了算,而是在人生的旅途中不间断的事情。
人生短暂,别稀里糊涂的活一辈子,不要将就。
Rules API
Easy rules中的一组规则由rules API表示。它的使用方法如下:
Rules rules = new Rules();
rules.register(myRule1);
rules.register(myRule2);
复制代码
Rules
表示已注册规则的命名空间,因此,在同一命名空间下,每一个已经注册的规则必须有唯一的名称。
Rules
是通过Rule#compareTo()
方法进行比较的,因此,Rule
的实现应该正确的实现compareTo()
方法来确保单一空间下拥有唯一的规则名称。
定义事实
Easy Rules中的一个事实是由Fact
表示的:
public class Fact {
private final String name;
private final T value;
}
复制代码
一个事实有一个名称和一个值,两者都不能为null
。另一方面,Facts
API 表示一组事实并充当事实的命名空间。这意味着,在一个Facts
实例中,事实必须有唯一的名称。
下面是一个如何定义事实的例子:
Fact fact = new Fact(“foo”, “bar”);
Facts facts = new Facts();
facts.add(fact);
复制代码
你也可以使用一个更短的版本,用put方法创建命名的事实,如下所示:
Facts facts = new Facts();
facts.put(“foo”, “bar”);
复制代码
可以使用@Fact
注解将事实注入到规则的条件和操作方法中。在以下规则中,rain
事实被注入到itRains
方法的rain
参数中:
@Rule
class WeatherRule {
@Condition
public boolean itRains(@Fact(“rain”) boolean rain) {
return rain;
}
@Action
public void takeAnUmbrella(Facts facts) {
System.out.println(“It rains, take an umbrella!”);
// can add/remove/modify facts
}
}
复制代码
类型为Facts
的参数将被注入所有已知的事实。
注意:
-
如果条件方法中缺少注入的事实,引擎将记录一个警告,并认为条件被计算为
false
。 -
如果动作方法中缺少注入的事实,则不会执行该动作,并且抛出
org.jeasy.rules.core.NoSuchFactException
异常。
定义规则引擎
Easy Rules提供了RulesEngine
接口的两种实现:
-
DefaultRulesEngine
:根据规则的自然顺序(默认为优先级)应用规则。 -
InferenceRulesEngine
:在已知的事实上不断地应用规则,直到没有更多的规则可用。
创建规则引擎
可以使用构造方法创建规则引擎。
RulesEngine rulesEngine = new DefaultRulesEngine();
// or
RulesEngine rulesEngine = new InferenceRulesEngine();
复制代码
可以按如下方式触发已注册的规则。
rulesEngine.fire(rules, facts);
复制代码
规则引擎参数
Easy Rules引擎可以配置以下参数:
| 参数 | 类型 | 默认值 |
| — | — | — |
| rulePriorityThreshold | int | MaxInt |
| skipOnFirstAppliedRule | boolean | false |
| rulePriorityThreshold | int | false |
| skipOnFirstFailedRule | boolean | false |
| skipOnFirstNonTriggeredRule | boolean | false |
-
skipOnFirstAppliedRule
:当一个规则成功应用时,跳过余下的规则。 -
skipOnFirstFailedRule
:当一个规则失败时,跳过余下的规则。 -
skipOnFirstNonTriggeredRule
:当一个规则未触发时,跳过余下的规则。 -
rulePriorityThreshold
:当优先级超过指定的阈值时,跳过余下的规则。
可以使用RulesEngineParameters
API指定这些参数:
RulesEngineParameters parameters = new RulesEngineParameters()
.rulePriorityThreshold(10)
.skipOnFirstAppliedRule(true)
.skipOnFirstFailedRule(true)
.skipOnFirstNonTriggeredRule(true);
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
复制代码
如果你想从你的引擎中获取参数,你可以使用以下代码段:
RulesEngineParameters parameters = myEngine.getParameters();
复制代码
这允许在创建引擎参数后重新设置引擎参数。
定义规则监听器
可以通过RuleListener
API来监听规则执行事件:
public interface RuleListener {
/**
-
在评估规则之前触发。
-
@param rule 正在被评估的规则
-
@param facts 评估规则之前的已知事实
-
@return 如果规则应该评估,则返回true,否则返回false
*/
default boolean beforeEvaluate(Rule rule, Facts facts) {
return true;
}
/**
-
在评估规则之后触发
-
@param rule 评估之后的规则
-
@param facts 评估规则之后的已知事实
-
@param evaluationResult 评估结果
*/
default void afterEvaluate(Rule rule, Facts facts, boolean evaluationResult) { }
/**
-
运行时异常导致条件评估错误时触发
-
@param rule 评估之后的规则
-
@param facts 评估时的已知事实
-
@param exception 条件评估时发生的异常
*/
default void onEvaluationError(Rule rule, Facts facts, Exception exception) { }
/**
-
在规则操作执行之前触发。
-
@param rule 当前的规则
-
@param facts 执行规则操作时的已知事实
*/
default void beforeExecute(Rule rule, Facts facts) { }
/**
-
在规则操作成功执行之后触发
-
@param rule t当前的规则
-
@param facts 执行规则操作时的已知事实
*/
default void onSuccess(Rule rule, Facts facts) { }
/**
-
在规则操作执行失败时触发
-
@param rule 当前的规则
-
@param facts 执行规则操作时的已知事实
-
@param exception 执行规则操作时发生的异常
*/
default void onFailure(Rule rule, Facts facts, Exception exception) { }
}
复制代码
可以实现这个接口来提供自定义行为,以便在每个规则之前/之后执行。要注册监听器,请使用以下代码段:
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.registerRuleListener(myRuleListener);
复制代码
可以注册任意数量的侦听器,它们将按照注册顺序执行。
注意:当使用组合规则时,监听器是围绕组合规则调用的。
定义规则引擎监听器
可以通过RulesEngineListener
API来监听规则引擎的执行事件:
public interface RulesEngineListener {
/**
-
在执行规则集之前触发
-
@param rules 要触发的规则集
-
@param facts 触发规则前的事实
*/
default void beforeEvaluate(Rules rules, Facts facts) { }
/**
-
在执行规则集之后触发
-
@param rules 要触发的规则集
-
@param facts 触发规则前的事实
*/
default void afterExecute(Rules rules, Facts facts) { }
}
复制代码
RulesEngineListener
允许我们在触发整个规则集之前/之后提供自定义行为。可以使用如下方式注册监听器。
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.registerRulesEngineListener(myRulesEngineListener);
复制代码
可以注册任意数量的监听器,它们将按照注册顺序执行。
表达式语言(EL)支持
Easy Rules支持用MVEL
、SpEL
和JEXL
定义规则。
EL提供者注意事项
EL提供者在行为上有一些区别。例如,当一个事实在条件中缺失时,MVEL
抛出一个异常,而SpEL
将忽略它并返回false。因此,在选择Easy Rules使用哪个EL之前,你应该了解这些差异。
通过编程的方式定义规则
条件、动作和规则分别由MVELCondition/SpELCondition/JexlCondition
、MVELAction/SpELAction/JexlAction
和MVELRule/SpELRule/JexlRule
类表示。下面是一个使用MVEL
定义规则的例子:
Rule ageRule = new MVELRule()
.name(“age rule”)
.description(“Check if person’s age is > 18 and marks the person as adult”)
.priority(1)
.when(“person.age > 18”)
.then(“person.setAdult(true);”);
复制代码
通过规则描述文件定义规则
可以使用规则描述文件定义规则,使用MVELRuleFactory
/SpELRuleFactory
/JexlRuleFactory
来从描述符文件创建规则。下面是一个在alcohol-rule.yml
中以YAML
格式定义的MVEL
规则示例:
name: “alcohol rule”
description: “children are not allowed to buy alcohol”
priority: 2
condition: “person.isAdult() == false”
actions:
- “System.out.println(“Shop: Sorry, you are not allowed to buy alcohol”);”
复制代码
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
MVELRule alcoholRule = ruleFactory.createRule(new FileReader(“alcohol-rule.yml”));
复制代码
还可以使用一个文件创建多个规则。
name: adult rule
description: when age is greater than 18, then mark as adult
priority: 1
condition: “person.age > 18”
actions:
- “person.setAdult(true);”
name: weather rule
description: when it rains, then take an umbrella
priority: 2
condition: “rain == true”
actions:
- “System.out.println(“It rains, take an umbrella!”);”
复制代码
可以使用如下方式将这些规则加载到rules
对象中。
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rules rules = ruleFactory.createRules(new FileReader(“rules.yml”));
复制代码
Easy Rules还支持从JSON描述符加载规则。具体参考文档,这里不做展开。
规则定义中的错误处理
关于条件中不正确表达式的引擎行为
对于条件求值过程中可能发生的任何运行时异常(丢失事实、表达式中输入错误等),引擎将记录一个警告,并认为条件求值为false
。可以使用RuleListener#onEvaluationError
来监听评估错误。
关于操作中不正确表达式的引擎行为
对于任何在执行操作时可能发生的运行时异常(丢失事实、表达式中输入错误等),该操作将不会执行,引擎将记录一个错误。可以使用RuleListener#onFailure
来监听操作执行异常。当一个规则失败时,引擎将移动到下一个规则,除非设置了skipOnFirstFailedRule
参数。
实际栗子
====
本栗子使用Easy Rules实现FizzBuzz应用程序。FizzBuzz是一个简单的应用程序,需要从1数到100,并且:
-
如果数字是5的倍数,则打印“fizz”
-
如果数字是7的倍数,请打印“buzz”
-
如果数字是5和7的倍数,请打印“fizzbuzz”
-
否则打印数字本身
public class FizzBuzz {
public static void main(String[] args) {
for(int i = 1; i <= 100; i++) {
if (((i % 5) == 0) && ((i % 7) == 0))
System.out.print(“fizzbuzz”);
else if ((i % 5) == 0) System.out.print(“fizz”);
else if ((i % 7) == 0) System.out.print(“buzz”);
else System.out.print(i);
System.out.println();
}
System.out.println();
}
}
复制代码
我们将为每个需求编写一条规则:
@Rule
public class FizzRule {
@Condition
public boolean isFizz(@Fact(“number”) Integer number) {
return number % 5 == 0;
}
@Action
public void printFizz() {
System.out.print(“fizz”);
}
总结
三个工作日收到了offer,头条面试体验还是很棒的,这次的头条面试好像每面技术都问了我算法,然后就是中间件、MySQL、Redis、Kafka、网络等等。
- 第一个是算法
关于算法,我觉得最好的是刷题,作死的刷的,多做多练习,加上自己的理解,还是比较容易拿下的。
而且,我貌似是将《算法刷题LeetCode中文版》、《算法的乐趣》大概都过了一遍,尤其是这本
《算法刷题LeetCode中文版》总共有15个章节:编程技巧、线性表、字符串、栈和队列、树、排序、查找、暴力枚举法、广度优先搜索、深度优先搜索、分治法、贪心法、动态规划、图、细节实现题
《算法的乐趣》共有23个章节:
- 第二个是Redis、MySQL、kafka(给大家看下我都有哪些复习笔记)
基本上都是面试真题解析、笔记和学习大纲图,感觉复习也就需要这些吧(个人意见)
- 第三个是网络(给大家看一本我之前得到的《JAVA核心知识整理》包括30个章节分类,这本283页的JAVA核心知识整理还是很不错的,一次性总结了30个分享的大知识点)
得最好的是刷题,作死的刷的,多做多练习,加上自己的理解,还是比较容易拿下的。
而且,我貌似是将《算法刷题LeetCode中文版》、《算法的乐趣》大概都过了一遍,尤其是这本
《算法刷题LeetCode中文版》总共有15个章节:编程技巧、线性表、字符串、栈和队列、树、排序、查找、暴力枚举法、广度优先搜索、深度优先搜索、分治法、贪心法、动态规划、图、细节实现题
[外链图片转存中…(img-0HrGAfAO-1715572215540)]
《算法的乐趣》共有23个章节:
[外链图片转存中…(img-FNhpaL7A-1715572215540)]
[外链图片转存中…(img-sg9PFGTI-1715572215541)]
- 第二个是Redis、MySQL、kafka(给大家看下我都有哪些复习笔记)
基本上都是面试真题解析、笔记和学习大纲图,感觉复习也就需要这些吧(个人意见)
[外链图片转存中…(img-IKAGbono-1715572215541)]
- 第三个是网络(给大家看一本我之前得到的《JAVA核心知识整理》包括30个章节分类,这本283页的JAVA核心知识整理还是很不错的,一次性总结了30个分享的大知识点)
[外链图片转存中…(img-lfXsZbCq-1715572215542)]