lottery lec5-cnblog

发布时间 2024-01-06 13:45:29作者: xyfyy

lottery lec5

修饰符作用域

首先,在学习代码过程中,遇到了protected,先学习一下protected关键词,看看其与在C++中的protected有何区别?

同一个类中 同一个包中 不同包的子类 不同包的无关类
public
protected
无(空着不写)
private

这个表格还需要后续继续去理解,和C++不同点在于引入了无这个作用域,同时由于java中包的概念,和C++中对作用域修饰符的理解也有所不同。

C++中protected表明,在当前类和子类中可以直接使用。

private表明只有在当前类中可以使用(封装)。

public则表明任意类中都可以使用。

BigDecimal

在项目中,使用了BigDecimal,之前只知道这个类可以解决精确度高数据和大数的精确计算问题,具体使用并不太了解。下面简单学习一下这个类。

BigDecimal可以对超过16位有效位的数进行精确计算的问题。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。

下面详细学习一下这个类。

构造函数
BigDecimal(int):将int类型转为BigDecimal

BigDecimal(double):将double类型转为BigDecimal

BigDecimal(long): 将long类型转为BigDecimal

BigDecimal(String): 将String类型转为BigDecimal

在网上看到使用BigDecimal构造函数的一个坑,在此记录一下

BigDecimal a =new BigDecimal(0.1);
System.out.println("a values is:"+a);
System.out.println("=====================");
BigDecimal b =new BigDecimal("0.1");
System.out.println("b values is:"+b);

结果如下:

a values is:0.1000000000000000055511151231257827021181583404541015625
=====================
b values is:0.1

出现这个错误的原因,显然是由于double类型不能准确表示0.1的值,在double不能表示的数据小数位数,会填上其它不确定的值。因此,大多数情况下,优先使用BigDecimal(String)构造函数

常用方法
BigDecimal add(BigDecimal);  // BigDecimal对象中的值相加,返回BigDecimal对象

BigDecimal subtract(BigDecimal)  // BigDecimal对象中的值相减,返回BigDecimal对象

BigDecimal multiply(BigDecimal)  // BigDecimal对象中的值相乘,返回BigDecimal对象
    
BigDecimal divide(BigDecimal)  // BigDecimal对象中的值相除,返回BigDecimal对象
    
String toString()		// 将BigDecimal对象中的值转换成字符串
常见异常

当使用divide时,如果除法导致出现无限小数,会抛出异常java.lang.ArithmeticException

解决方法:需要使用divide方法设置精确的小数点,如:

BigDecimal divide(BigDecimal, int scale, RoundingMole roundMode); 第二个参数即为小数点后的数据位,roundMode是舍入的方法。

tips
  1. BigDecimal都是不可变的(immutable)的, 在进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值。

  2. BigDecimal的底层实现原理⭐用一句话来说:十进制整数在转化成二进制数时不会有精度问题,那么把十进制小数扩大N倍让它在整数的维度上进行计算,并保留相应的精度信息。(后续有时间可以仔细研读一下源码,这句话也拓宽了自己对大数运算的认识,学到啦~)

Lambda表达式

Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确,但现在姑且这么认为),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。

Java 中的 Lambda 表达式通常使用 (argument) -> (body) 语法书写

结构规则:

  • 一个 Lambda 表达式可以有零个或多个参数
  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)(a)效果相同
  • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b)(int a, int b)(String a, int b, float c)
  • 空圆括号代表参数集为空。例如:() -> 42
  • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
  • Lambda 表达式的主体可包含零条或多条语句
  • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
  • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

idea配置mapper xml模板

一图胜千言,按照此方法配置即可~so easy..

image-20240105225700228

PostConstruct注解

首先,这里的Post和Http请求的post请求没有任何关系~

注解是Java jdk提供的注解,而不是Spring框架提供的,作用于Servlet生命周期(servlet是什么..)的注解。

主要功能:依赖注入完成后用于执行初始化的方法,并且只会被执行一次

该注解的方法在整个Bean初始化中的执行顺序:

Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的初始化方法)

servlet

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性, 是运行在 Web 服务器或应用服务器上的程序。

servlet作用

简单来说,servlet是在客户端和服务端之间的一个中间层,主要功能在于收集来自网页表单的用户输入,交互式地浏览和生成数据,还可以生成动态Web内容。

servlet生命周期

创建Servlet对象后---------->初始化(调用 init () 方法)--------->处理/响应客户端的请求(调用 service() 方法)--------->销毁(调用 destroy() 方法,最后由 JVM 的垃圾回收器进行垃圾回收)

其中service方法作用:

service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法进行处理。

感觉瞬间对spring mvc框架中,我们通过注释Get Post等来处理不同类型的请求有了新的认识,应该底层还是通过创建了特定的doGet、dePost方法,交给了servlet来调用,从而调用指定的方法。

业务相关:

首先明确四个po类(persist object)

Activity: 活动类,其成员变量主要是该活动的一些基本信息,活动描述、活动时间、每人可参与活动次数、活动状态

Award: 奖品类,主要成员变量是这种奖品的类型、数量、内容

Strategy: 策略类,主要成员变量是抽奖策略方式(单项概率、总体概率两种)、奖品发放时间

StrategyDetail: 策略详细属性类,主要记录抽奖过程中奖品数量、中奖概率、

一个aggregates(聚合)类:

StrategyRich: 包装了strategy对象和strategyDetail对象,方便使用

aggregates的意思应该是将几个po类包装在一起

抽奖算法:

defaultRateRandomDrawAlgorithm: 当有奖品被抽出,其它奖品的中奖概率也会等比例上调

singleRateRandomDrawAlgorithm:靠hash去抽奖