Day14:单元测试、Junit单元测试框架、反射、注解

单元测试

  • 针对最小的功能单元(方法)进行正确性测试
  • 编写正规的单元测试框架
  • 传统的无法执行自动化测试,且无法得到测试报告

Junit单元测试框架

  • Junit的作用:

image

具体步骤

image

  • 测试类取名:原类名+Test(大驼峰)
  • 测试方法取名:test+原函数名称(小驼峰)
  • 测试方法:必须public,无参,无返回值
  • 测试方法上面必须加上@Test方法,不加不会跑的
  • 测试方法只能判断程序能否正常运行,并不能判断功能是否正确,需要加断言(Assert)
public class StringUtilTest {@Test // 测试方法public void testPrintNumber(){
//        StringUtil.printNumber("admin");StringUtil.printNumber(null);}
}

公共的(Public):JUnit框架在运行测试时,需要能够访问到测试方法。如果测试方法不是公共的,JUnit框架可能无法访问到它,从而无法执行测试。

无参数的:JUnit框架在运行测试时,会自动调用测试方法,而不需要手动传入参数。如果测试方法需要参数,JUnit框架无法知道应该传入什么值,因此,测试方法不能有参数。

无返回值的(Void):JUnit框架通过断言(Assert)来检查测试是否通过,而不是通过返回值。因此,测试方法不需要返回值。

Assert断言(重要)

@Test // 测试方法public void testGetMaxIndex(){int index1 = StringUtil.getMaxIndex(null);System.out.println(index1);int index2 = StringUtil.getMaxIndex("admin");System.out.println(index2);// 断言机制:程序员可以通过预测业务方法的结果。Assert.assertEquals("方法内部有bug!", 4, index2);}
  • Assert.assertEquals(提示信息,希望的输出,实际输出)

自动化测试

  • 自动化测试:IDEA中直接右键run就行(run整个类就是run所有有Test注解的方法)。
  • 右键项目 run all_tests,测试所有

其他常见注解

image

public class StringUtilTest {@Before //每次测试类的每个方法之前都执行一次public void test1(){System.out.println("---> test1 Before 执行了---------");}@BeforeClass //整个类只执行一次public static void test11(){System.out.println("---> test11 BeforeClass 执行了---------");}@Afterpublic void test2(){System.out.println("---> test2 After 执行了---------");}@AfterClasspublic static void test22(){System.out.println("---> test22 AfterClass 执行了---------");}@Test // 测试方法public void testPrintNumber(){
//        StringUtil.printNumber("admin");StringUtil.printNumber(null);}
}
  • 在JUnit 5之后改名了:

image

反射

  • 作用:加载类,并编程解析类中的各种成分(比如成员变量、方法、构造器等)
  • 关键:如何获取类的各种信息

image

加载类

  • 三种方法:

image

(方法三必须先new一个对象才能得到对应的类的class对象)

public static void main(String[] args) throws Exception {Class c1 = Student.class;System.out.println(c1.getName()); // 全类名System.out.println(c1.getSimpleName()); // 简名:StudentClass c2 = Class.forName("com.itheima.d2_reflect.Student");System.out.println(c1 == c2);Student s = new Student();Class c3 = s.getClass();System.out.println(c3 == c2);}

(forName的参数应该是类的全类名:包名.类名)

获取类的构造器

  • 不加Declare只能拿public的,加了就都能拿
  • 拿单个构造器应该表明参数类型(String.class, int.class)(不然不知道是纳哪个构造器)
  • 拿单个的时候会报异常,可以throws抛出

image

public void testGetConstructors(){// 1、反射第一步:必须先得到这个类的Class对象Class c = Cat.class;// 2、获取类的全部构造器// Constructor[] constructors = c.getConstructors();Constructor[] constructors = c.getDeclaredConstructors();// 3、遍历数组中的每个构造器对象for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "--->"+ constructor.getParameterCount());}}
Constructor constructor1 = c.getDeclaredConstructor();//无参构造器// 3、获取有参数构造器
Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class);

获取构造器的作用:初始化对象返回(相当于new)

image

newInstance 初始化对象

Cat cat2 = (Cat) constructor2.newInstance("叮当猫", 3);

找到对应的构造器,相当于new一个对象(实际开发还是用new),这里注意需要强转(Cat)

setAccessible 修改权限(暴力反射)

// 3、获取有参数构造器
Constructor constructor2 =c.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor2.getName() + "--->"+ constructor2.getParameterCount());
constructor2.setAccessible(true); // 禁止检查访问权限
Cat cat2 = (Cat) constructor2.newInstance("叮当猫", 3);
System.out.println(cat2);

将原本private的构造器硬在外部禁止检查访问权限,无论如何都会new出一个对象。

获取类的成员变量

  • 反射第一步:得到class对象
  • 其他跟构造器的差不多,包括declare,setAccessible等
  • getName拿到名字,getType拿到数据类型

image

public void testGetFields() throws Exception {// 1、反射第一步:必须是先得到类的Class对象Class c = Cat.class;// 2、获取类的全部成员变量。Field[] fields = c.getDeclaredFields();// 3、遍历这个成员变量数组for (Field field : fields) {System.out.println(field.getName() +  "---> "+ field.getType());}// 4、定位某个成员变量Field fName = c.getDeclaredField("name");System.out.println(fName.getName() + "--->" + fName.getType());Field fAge = c.getDeclaredField("age");System.out.println(fAge.getName() + "--->" + fAge.getType());}

获取成员变量的作用:赋值(set)和取值(get)

// 赋值Cat cat = new Cat();fName.setAccessible(true); // 禁止访问控制权限fName.set(cat, "卡菲猫");System.out.println(cat);// 取值String name = (String) fName.get(cat);System.out.println(name);
  • 必须有对象才能有对象的成员变量
  • set(变量名,值)
  • get(对象名),需要强转。

setAccessible 修改权限(暴力反射)

fName.setAccessible(true); // 禁止访问控制权限

获取类的成员方法

  • getName拿方法名,getParameterCount拿参数个数,getReturnType拿返回类型
  • getDeclaredMethod要写参数类型,不然不知道找的是哪个同名函数

image

public void testGetMethods() throws Exception {//  1、反射第一步:先得到Class对象。Class c = Cat.class;// 2、获取类的全部成员方法。Method[] methods = c.getDeclaredMethods();// 3、遍历这个数组中的每个方法对象for (Method method : methods) {System.out.println(method.getName() + "--->"+ method.getParameterCount() + "---->"+ method.getReturnType());}//  4、获取某个方法对象Method run = c.getDeclaredMethod("run", String.class); // 拿run方法,无参数的

获取类方法的作用:执行invoke

image

Cat cat = new Cat();
run.setAccessible(true); // 禁止检查访问权限
Object rs = run.invoke(cat); // 调用无参数的run方法,用cat对象触发调用的。
//这里无返回值则返回null
System.out.println(rs);eat.setAccessible(true); // 禁止检查访问权限
String rs2 = (String) eat.invoke(cat, "鱼儿");
System.out.println(rs2);

反射的应用场景

image

示例

image

框架:

public class ObjectFrame {// 目标:保存任意对象的字段和其数据到文件中去public static void saveObject(Object obj) throws Exception {PrintStream ps = new PrintStream(new FileOutputStream("junit-reflect-annotation-proxy-app\\src\\data.txt", true));// obj是任意对象,到底有多少个字段要保存。Class c = obj.getClass();String cName = c.getSimpleName();ps.println("---------------" + cName + "------------------------");// 2、从这个类中提取它的全部成员变量Field[] fields = c.getDeclaredFields();// 3、遍历每个成员变量。for (Field field : fields) {// 4、拿到成员变量的名字String name = field.getName();// 5、拿到这个成员变量在对象中的数据。field.setAccessible(true); // 禁止检查访问控制String value = field.get(obj) + "";ps.println(name + "=" + value);}ps.close();}
}

测试:

public class Test5Frame {@Testpublic void save() throws Exception {Student s1 = new Student("黑马吴彦祖", 45, '男', 185.3, "蓝球,冰球,阅读");Teacher t1 = new Teacher("播妞", 999.9);// 需求:把任意对象的字段名和其对应的值等信息,保存到文件中去。ObjectFrame.saveObject(s1);ObjectFrame.saveObject(t1);}
}

注解(Annotation)

  • java中的特殊标记
  • 作用:让其他程序根据注解信息决定怎么执行该程序。
  • 可以用在类上、构造器上、方法上、成员变量上、参数上等。

自定义注解

image

/*** 自定义注解*/
public @interface MyTest1 {String aaa();boolean bbb() default true;String[] ccc();
}

如何使用?

@MyTest1(aaa="牛魔王", ccc={"HTML", "Java"})public class AnnotationTest1 {@MyTest1(aaa="铁扇公主", bbb=false, ccc={"Python", "前端", "Java"})public void test1(){}public static void main(String[] args) {}
}

(有参数的一定要填,有默认参数的不必须要填)

特殊属性名:value

  • 如果注解中只有一个value属性(或多余的数值为默认值default),使用@注解时可以不写value名称
public @interface MyTest2 {String value(); // 特殊属性int age() default 23;
}
@MyTest2("孙悟空")
public class AnnotationTest1 {@MyTest1(aaa="铁扇公主", bbb=false, ccc={"Python", "前端", "Java"})public void test1(){}public static void main(String[] args) {}
}

注解的原理:本质是一个接口!!!

  • 把注解编译成class再反

image

  • 本质是一个继承Annotation接口的接口!!!
  • 使用注解时创建实现类对象,把参数传进去

元注解

  • 定义:修饰注解的注解
  • 常见:@Target和Retention

@Target

image

  • TYPE:比如Field(变量),TYPE(类)等,多个用{,}隔开
@Target({ElementType.TYPE, ElementType.METHOD}) // 当前被修饰的注解只能用在类上,方法上。
public @interface MyTest3 {
}
@MyTest3
public class AnnotationTest2 {// @MyTest3 这里会报错private String name;@MyTest3public void test(){}
}

Retention

image

@Retention(RetentionPolicy.RUNTIME) // 控制下面的注解一直保留到运行时
public @interface MyTest3 {
}
  • RUNTIME:一直保留到运行阶段(常用)

注解的解析

  • 定义:判断类上/方法上等上是否存在注解,并把注解里的内容解析出来
  • 方法

image

解析案例

image

MyTest4:

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {String value();double aa() default 100;String[] bbb();
}

Demo:

@MyTest4(value = "蜘蛛精", aaa=99.5, bbb = {"至尊宝", "黑马"})
@MyTest3
public class Demo {@MyTest4(value = "孙悟空", aaa=199.9, bbb = {"紫霞", "牛夫人"})public void test1(){}
}

AnnotationTest3:

public class AnnotationTest3 {@Testpublic void parseClass(){// 1、先得到Class对象Class c = Demo.class;// 2、解析类上的注解// 判断类上是否包含了某个注解if(c.isAnnotationPresent(MyTest4.class)){//这里是.class而不是直接输出类MyTest4 myTest4 =(MyTest4) c.getDeclaredAnnotation(MyTest4.class);System.out.println(myTest4.value());System.out.println(myTest4.aaa());System.out.println(Arrays.toString(myTest4.bbb()));}}@Testpublic void parseMethod() throws Exception {// 1、先得到Class对象Class c = Demo.class;Method m = c.getDeclaredMethod("test1");// 2、解析方法上的注解// 判断方法对象上是否包含了某个注解if(m.isAnnotationPresent(MyTest4.class)){MyTest4 myTest4 =(MyTest4) m.getDeclaredAnnotation(MyTest4.class);System.out.println(myTest4.value());System.out.println(myTest4.aaa());System.out.println(Arrays.toString(myTest4.bbb()));}}
}

应用场景

  • 与反射配合做框架

示例

image

image

定义MyTest注解:

@Target(ElementType.METHOD) // 注解只能注解方法。
@Retention(RetentionPolicy.RUNTIME) // 让当前注解可以一直存活着。
public @interface MyTest {
}

定义若干个方法:

public class AnnotationTest4 {// @MyTest 不会被执行public void test1(){System.out.println("===test1====");}@MyTestpublic void test2(){System.out.println("===test2====");}@MyTestpublic void test3(){System.out.println("===test3====");}@MyTestpublic void test4(){System.out.println("===test4====");}public static void main(String[] args) throws Exception {.......}}
}

模拟Junit程序:通过反射配合注解解析

public static void main(String[] args) throws Exception {AnnotationTest4 a = new AnnotationTest4();// 启动程序!// 1、得到Class对象Class c = AnnotationTest4.class;// 2、提取这个类中的全部成员方法Method[] methods = c.getDeclaredMethods();// 3、遍历这个数组中的每个方法,看方法上是否存在@MyTest注解,存在// 触发该方法执行。for (Method method : methods) {if(method.isAnnotationPresent(MyTest.class)){// 说明当前方法上是存在@MyTest,触发当前方法执行。method.invoke(a);}}}

调用结果:

image

  • 1、得到Class对象
  • 2、提取这个类中的全部成员方法
  • 3、遍历这个数组中的每个方法,看方法上是否存在@MyTest注解,执行(必须创建对象,重新new一个)

动态代理

  • 意义:对象身上事儿太多,需要通过代理转移部分职责;
  • 含义:对象有什么方法想被代理,代理也得有,但不真正做,而是一些其他操作+调用对象的。
  • 怎么做:对象声明接口,代理设置实现类。
  1. 接口:
public interface Star {String sing(String name);void dance();
}
  1. 用明星类实现该接口:
public class BigStar implements Star{private String name;public BigStar(String name) {this.name = name;}public String sing(String name){System.out.println(this.name + "正在唱:" + name);return "谢谢!谢谢!";}public void dance(){System.out.println(this.name  + "正在优美的跳舞~~");}
}
  1. 让代理类实现该接口ProxyUtil(工具类,静态方法)
import java.lang.reflect.Proxy;public class ProxyUtil {public static Star createProxy(BigStar bigStar){.......return starProxy;}
}

newProxyInstance:

 newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)参数1:用于指定一个类加载器参数2:指定生成的代理长什么样子,也就是有哪些方法(接收的接口数组)参数3:用来指定生成的代理对象要干什么事情(new一个接口的匿名内部类对象)
Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),new Class[]{Star.class}, new InvocationHandler() {@Override // 回调方法public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 代理对象要做的事情,会在这里写代码if(method.getName().equals("sing")){System.out.println("准备话筒,收钱20万");}else if(method.getName().equals("dance")){System.out.println("准备场地,收钱1000万");}return method.invoke(bigStar, args);}});

回调方法invoke

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 代理对象要做的事情,会在这里写代码if(method.getName().equals("sing")){//当前正在代理sing方法System.out.println("准备话筒,收钱20万");}else if(method.getName().equals("dance")){System.out.println("准备场地,收钱1000万");}return method.invoke(bigStar, args);//返回方法的返回值}
  • proxy:代理对象
  • method:方法;
  • args:方法的参数

如何调用?test:

public class Test {public static void main(String[] args) {BigStar s = new BigStar("杨超越");Star starProxy = ProxyUtil.createProxy(s);String rs = starProxy.sing("好日子");System.out.println(rs);starProxy.dance();}
}

(可通过单步调试追踪调用链条)

应用场景:AOP

动态代理设计模式主要用于以下几种场景:

  1. 接口适配:当一个类已经实现了某个接口,但是需要对该接口的某些方法进行修改时,可以使用动态代理。动态代理可以在不修改原有代码的情况下,对接口的方法进行增强。
  2. AOP(面向切面编程):动态代理是实现AOP的一种方式。在AOP中,通常会在业务方法执行前后插入一些公共的代码,如日志、事务管理等。动态代理可以在运行时动态地为目标对象生成一个代理对象,然后通过代理对象调用目标方法,从而实现在目标方法执行前后插入公共代码。
  3. 远程调用:在远程方法调用(RMI)中,客户端实际上是调用的是本地的一个代理对象,这个代理对象负责与远程服务器通信。这个代理对象就是通过动态代理生成的。
  4. 权限控制:动态代理可以用于实现权限控制。例如,当调用某个方法时,可以通过动态代理检查用户是否有权限执行该方法。
  5. 性能监控:动态代理可以用于监控方法的执行时间,从而实现性能监控。例如,可以在方法执行前后获取系统时间,然后计算出方法的执行时间。
  6. 单元测试:在单元测试中,经常需要模拟一些对象。这些模拟对象可以通过动态代理生成。例如,可以生成一个代理对象,这个代理对象的所有方法都返回默认值。
    什么是AOP?

**面向切面编程(Aspect-Oriented Programming,AOP)**是一种编程范式,其目标是提高模块化的能力,特别是对于横切关注点(cross-cutting concerns)的处理。横切关注点是那些分散在多个模块中,但不能很好地通过传统的面向对象编程(OOP)模块化的问题,例如日志记录、事务管理、安全性等。

在AOP中,一个切面(Aspect)代表一个横切关注点,它可以包含一些通用的代码。这些代码可以被定义为通知(Advice),然后通过切入点(Pointcut)插入到目标对象的方法中。通知定义了何时(例如,方法调用前、后或异常抛出时)以及如何(执行何种代码)应用切面。

例如,你可能有一个用于记录日志的切面,它的通知在每个方法调用前后记录日志,切入点定义了这个切面应用于哪些方法。

AOP可以帮助我们将这些横切关注点从业务逻辑中分离出来,使得业务逻辑更加清晰,同时也更易于维护和重用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/724671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯备战刷题four(自用)

1.砝码称重 #include <iostream> #include <vector> using namespace std; const int N110; const int M100010; int w[N]; int n; int f[N][M]; int m; int ans; //f[i][j]表示到第i个砝码进行放置时的称得的重量为j的方案数 int main() {cin>>n;for(int i1…

DbSchema导出HTML/PDF版表结构

一、连接数据库 登录成功默认显示当前用户的所有资源&#xff08;表、视图、序列、方法、触发器等&#xff09;&#xff0c;如果不操作将导出此用户的全部信息。 至此连接数据库完成 二、表结构导出 本次不想给用户全部导出&#xff0c;只给导出几张&#xff0c;选择需要…

分享7款前端动画特效(附效果图及在线演示)

分享7款好玩的前端动画特效 其中有CSS动画、SVG动画、js小游戏等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 canvas彩色画树特效 基于canvas实现的画树特效 同时还可选择树枝的初始数目进行彩色树生成 以下效果…

企业对接Walmart平台API流程 On-request Reports API(二)

对接On-request Reports API 1、对接指南1.1 报告生成时间1.2 报告保留期1.3 请求限制1.4 报告请求工作流如何申请报告第 1 步&#xff1a;申请取消报告第 2 步&#xff1a;获取报表可用性状态第 3 步&#xff1a;下载报告 URL 2、代码实现2.1、获取访问API的token2.2、构建公共…

【教育部白名单赛事】C语言编程题解析--软件编程邀请赛(决赛)

文章目录 1、保留12位小数的浮点数2、气温统计3.大写字母的判断4、【递归】母鸡的故事5、小白免再排队 1、保留12位小数的浮点数 输入一个双精度浮点数&#xff0c;保留12位小数&#xff0c;输出这个浮点数。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 【输入】 只…

【DPDK】基于dpdk实现用户态UDP网络协议栈

文章目录 一.背景及导言二.协议栈架构设计1. 数据包接收和发送引擎2. 协议解析3. 数据包处理逻辑 三.网络函数编写1.socket2.bind3.recvfrom4.sendto5.close 四.总结 一.背景及导言 在当今数字化的世界中&#xff0c;网络通信的高性能和低延迟对于许多应用至关重要。而用户态网…

【python基础学习10课_面向对象、封装、继承、多态】

一、类与对象 1、类的定义 在类的里面&#xff0c;称之为方法。 在类的外面&#xff0c;称之为函数。类&#xff1a;人类&#xff0c;一个族群&#xff0c;是一个群体类的语法规则&#xff1a;class 自定义的类名():属性 -- 变量方法 -- 函数类&#xff0c;首字母大写&#x…

SpringBoot集成图数据库neo4j实现简单的关联图谱

社交领域&#xff1a;Facebook, Twitter&#xff0c;Linkedin用它来管理社交关系&#xff0c;实现好友推荐 图数据库neo4j安装&#xff1a; 下载镜像&#xff1a;docker pull neo4j:3.5.0运行容器&#xff1a;docker run -d -p 7474:7474 -p 7687:7687 --name neo4j-3.5.0 ne…

Android开发真等于废人,历经30天

前言 回顾一下自己这段时间的经历&#xff0c;三月份的时候&#xff0c;疫情原因公司通知了裁员&#xff0c;我匆匆忙忙地出去面了几家&#xff0c;但最终都没有拿到offer&#xff0c;我感觉今年的寒冬有点冷。到五月份&#xff0c;公司开始第二波裁员&#xff0c;我决定主动拿…

超简单Windows-kafka安装配置

参考大佬文章&#xff1a; Kafka&#xff08;Windows&#xff09;安装配置启动&#xff08;常见错误扫雷&#xff09;教程_kafka在windows上的安装、运行-CSDN博客Kafka&#xff08;Windows&#xff09;安装配置启动&#xff08;常见错误扫雷&#xff09;教程_kafka在windows上…

基于ERNIR3.0文本分类的开发实践

参考&#xff1a;基于ERNIR3.0文本分类&#xff1a;(KUAKE-QIC)意图识别多分类(单标签) - 飞桨AI Studio星河社区 (baidu.com) https://zhuanlan.zhihu.com/p/574666812?utm_id0 遇到的问题&#xff1a;如下 采用paddleNLP下文本分类实例进行分类训练后发现 生成的模型分类不…

嵌入式学习-FreeRTOS-Day1

一、重点 1、VCC和GND VCC&#xff1a; 1、电路中为电源&#xff0c;供应电压 2、3.3v-5v 3、数字信号中用1表示GND&#xff1a; 1、表示地线 2、一般为0v 3、数字信号中用0表示2、电容和电阻 电容 存储电荷 存储能量&#xff1a; 电容器可以在其两个导体板&#xff08;极…

C++之智能指针

为什么会有智能指针 前面我们知道使用异常可能会导致部分资源没有被正常释放, 因为异常抛出之后会直接跳转到捕获异常的地方从而跳过了一些很重要的的代码, 比如说下面的情况&#xff1a; int div() {int a, b;cin >> a >> b;if (b 0)throw invalid_argument(&q…

第三天 Kubernetes进阶实践

第三天 Kubernetes进阶实践 本章介绍Kubernetes的进阶内容&#xff0c;包含Kubernetes集群调度、CNI插件、认证授权安全体系、分布式存储的对接、Helm的使用等&#xff0c;让学员可以更加深入的学习Kubernetes的核心内容。 ETCD数据的访问 kube-scheduler调度策略实践 预选与…

centos7安装maven离线安装

1、从官方网站下载maven文件包 官方下载网站&#xff1a;https://maven.apache.org/download.cgi 2、创建文件夹解压文件 将下载好的安装包&#xff0c;放到创建的目录下&#xff0c;并解压 a、创建/app/maven文件 mkdir /app/mavenb、解压文件 tar -zxvf apache-maven-…

重磅:2024广州国际酒店工程照明展览会

2024广州国际酒店工程照明展览会 Guangzhou international hotel engineering lighting exhibition 2024 时间&#xff1a;2024年12月19-21日 地点&#xff1a;广州.中国进出口商品交易会展馆 承办单位&#xff1a;广州佛兴英耀展览服务有限公司 上海昶文展览服务有限公司…

【Java面试/24春招】技术面试题的准备

Spring MVC的原理 Mybatis的多级缓存机制 线程池的大小和工作原理 上述问题&#xff0c;我们称为静态的问题&#xff0c;具有标准的答案&#xff0c;而且这个答案不会变化&#xff01; 如果没有Spring&#xff0c;会怎么样&#xff1f;IOC这个思想是解决什么问题&#xff1f…

【牛客】VL65 状态机与时钟分频

描述 题目描述&#xff1a; 使用状态机实现时钟分频&#xff0c;要求对时钟进行四分频&#xff0c;占空比为0.25 信号示意图&#xff1a; clk为时钟 rst为低电平复位 clk_out 信号输出 Ps 本题题解是按照1000的状态转移进行的&#xff0c;不按照此状态进行&#xff0c;编译器…

蓝桥杯练习系统(算法训练)ALGO-985 幸运的店家

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 炫炫开了一家商店&#xff0c;卖的货只有一个&#xff0c;XXX&#xff0c;XXX卖N元钱。有趣的是&#xff0c;世界上只有面值…

剑指offer 二维数组中的查找 C++

目录 前言 一、题目 二、解题思路 1.直接查找 2.二分法 三、输出结果 前言 最近在牛客网刷题&#xff0c;刷到二维数组的查找&#xff0c;在这里记录一下做题过程 一、题目 描述 在一个二维数组中&#xff08;每个一维数组的长度相同&#xff09;&#xff0c;每一行都按照…