mvc+动态代理
不使用MVC的时候系统存在的缺陷
一个Servlet都负责了那些工作?
- 负责了接收数据
- 负责了核心的业务处理
- 负责了数据表中的CRUD
- 负责了页面的数据展示
- …
分析银行转账项目存在那些问题?
- 代码的复用性太差。(代码的重用性太差)
- 因为没有进行“职能分工”,没有独立组件的概念,所以没有办法进行代码复用
- 代码和代码之间耦合度太高,扩展力太差。
- 耦合度太高,导致了代码很难扩展。
- 操作数据库的代码和业务混杂在一起,很容易出错,编写代码的时候容易出错,无法专注业务逻辑的编写。
MVC架构模式
1、系统为什么要分层?
- 希望专人干专事。各司其职。职能分工要明确。
- 这样可以让代码耦合度降低扩展力增强,组件的可复用性增强。
2、系统架构中有一个非常著名的模式:MVC结构模式
-
M(Model:业务模型层,数据处理/业务处理)
- Dao层:专门为做数据的CRUD抽取出来的一个类,Dao层又叫做数据持久层。
- service层:专门抽取处理的一个业务类,只写业务,在service中调用Dao层对象。在service类中有一个私有的Dao属性(数据库访问对象)满足has a的关系,service对象通过数据库访问对象操作数据库的中表中的数据。
-
V(View:视图/展示):负责展示的组件
- jsp
- html
- …
-
C(Controller:控制器)
-
在Controller中调用service对象。在Controller类中有一个service私有的属性(业务对象)满足has a的关系,controller对象通过通过调用业务对象完成用户的业务。
- 在service中调用Dao。
-
在Controller中调用view。
-
-
C:是核心,是控制器,是司令官。
-
M:业务模型层,处理业务,处理数据的一个秘书。
-
V:负责页面展示的一个秘书。
-
MVC一个司令官调度两个秘书。去做这件事。
3、Model包含什么?
- pojo、bean、domain:封装数据用的。
- service:抽取出来的业务处理类
- dao:抽取出来的数据持久化层。
4、三层架构和MVC的关系:
- 表示层/展示层/web层:展示层包括控制器和view,包含MVC架构模式中的V和C
- Controller:MVC中的控制器
- 一般是Servlet
- view:MVC中的视图层
- JSP
- HTML
- …
- Controller:MVC中的控制器
- 业务逻辑层:MVC中的Model中的业务处理层(service)
- service:处理业务逻辑的,一般是一个XxxService类名
- 持久化层:MVC中的Model中的持久化层(Dao)
- Dao:将数据持久化保存进数据库
5、持久化层中包含的技术?
- JDBC
- MyBatis
- …
6、SSM:spring、springMVC、MyBatis
- Spring:项目大管家,负责整个项目所都对象的创建以及维护对象和对象之间的关系。
- SpringMVC:将MVC架构模式体现的非常完美。在这个框架的基础之上进行开发,一定是用了MVC架构模式的。
- MyBaits:持久层框架
7、展示层和业务逻辑层和持久化层的调用关系
- 展示层调用业务逻辑层,
- 业务逻辑层调用持久化层,
8、什么是Dao
- DAO的英文全称是:Data Access Object(数据访问对象)
- DAO实际上是一种设计模式,属于JavaEE的设计模式之一。(不是23中设计模式)
- DAO只负责数据库表的CRUD,没有任何业务逻辑在里面。
- 没有任何业务逻辑,只负责表中数据增删改查的对象,有一个特殊的称谓Dao对象(Dao对象是由Dao类实例化得到的)。
- Dao类的命名规范:
- 如果这个Dao对象专门用来处理t_user表的话,Dao类可以叫做UserDao
- 如果这个Dao对象专门用来处理t_student表的话,Dao类可以叫做StudentDao
- 一般情况下:一张表会对应一个DAO类,DAO对象专门用来CRUD的对象。
- pojo对象:POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans。
- 以下的三个对象说的是一个东西,看个人习惯:都是为了封装数据的对象。
- pojo对象
- Bean对象
- domain对象:领域模型
- 以下的三个对象说的是一个东西,看个人习惯:都是为了封装数据的对象。
- 使用Dao对象对数据库中的数据进行增删改查操作,一般先将数据库中的数据封装成一个Java对象这样便于Java程序对数据的操作。
- 一般一个表对应一个JavaBean(封装数据的Java对象,又叫做pojo对象)。
- JavaBean的属性建议使用引用数据类型,因为从数据库中查出来的可能返回一个null,如果是基本数据类型,将null赋值给基本数据类型就会抛异常,尽量使用基本类型的包装类。
- 数据库中的一个字段对应JavaBean中的一个属性。
- JavaBean的属性建议使用引用数据类型,因为从数据库中查出来的可能返回一个null,如果是基本数据类型,将null赋值给基本数据类型就会抛异常,尽量使用基本类型的包装类。
- 一条数据对应一个JavaBean对象,一条记录对象一个pojo对象。
- 有的人也会把这种专门封装数据的对象,称为领域模型对象(domain对象)
- 一般一个表对应一个JavaBean(封装数据的Java对象,又叫做pojo对象)。
- Dao类中的方法名很固定:
- insert
- deleteBy…
- update
- selectBy…
- selectAll
9、什么是Service
- service翻译为:业务。是MVC架构模式中Model中的service层。
- service类的命名规范:XxxService
- 学生的业务类就叫做:StudentService
- 用户的业务类就叫做:UserService
- 业务类的方法命名规范:
- 方法命名一定要体现出要处理的是什么业务。(方法名和业务挂钩)
- 一个业务类中包含多个处理业务的方法,一般一个业务对应一个方法。
- 在该类中编写纯业务代码。(只专注业务,不写别的。不和其他代码混合在一块)
- 事务一定实在Service层进行控制的。
- 一般是一个业务方法对应一个完整的事务。
try语句的资源自动管理机制
-
JDK7 特性之 try-with-resource 资源的自动管理
-
该try-with资源语句是try声明了一个或多个资源声明。一个资源是程序与它完成后,必须关闭的对象。该try-with资源语句确保每个资源在发言结束时关闭。
-
代码:
@Test public void test2() throws IOException {String filepath = "D:\\gui-config.json";try (//任何实现的java.lang.AutoCloseable对象(包括实现的所有对象)java.io.Closeable都可以用作资源。FileReader fileReader = new FileReader(filepath);BufferedReader br = new BufferedReader(fileReader)) {String curline = null;while ((curline = br.readLine()) != null) {System.out.println(curline);}} } // FileReader 和 BufferedReader 均实现了 AutoCloseable 接口
ThreadLocal源码分析
-
多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。ThreadLocal是除了加锁这种同步方式之外的一种保证多线程访问出现线程不安全的方法,当我们在创建一个变量后,如果每个线程对其进行访问的时候访问的都是线程自己的变量这样就不会存在线程不安全问题。
- 相当于一个Map集合一个线程只能对应一份数据。
-
一个ThreadLocal就是一个大Map集合,集合的key就是当前线程对象,集合的value就是我们向集合对象中存储的数据。key不用我们自己存储,key是由JVM来管理的,这样就可以把线程和数据关联起来。
-
ThreadLocal类的常用方法:
T get(); // 返回当前线程对应的数据,T是泛型类型,就是往ThreadLocal中绑定的数据的类型 void set(T value); // 设置当前线程对应的数据,绑定数据,一个线程只能绑定一份数据,这份数据可以是数组、集合等,如果再绑定一次数据第二次绑定的数据会覆盖第一次绑定的数据。 void remove(); // 删除当前线程对应的数据
不同功能的类在不同的包
- 三层架构:层与层之间应当使用接口进行衔接。
- 三层架构的目录规范:
- pojo包:中存放普通JavaBean,用来保存数据的Java类【这个包也可以使用domain包或者bean包替代】
- web包:中存放控制器Controller,用来调度两个秘书的司令官
- web目录:webapp的根目录中存放view,展示层的页面
- dao包:dao包中存放以下两项内容【持久化层】
- 数据库访问的接口
- impl包:中存放实现了数据库访问接口的实现类
- service包:中存放以下两项内容【业务处理曾】
- 业务处理的接口
- impl包:中存放了实现了业务处理接口的实现类
使用了MVC架构模式之后存在的两大问题
- 在service层控制事务,service层的事务控制代码看着有点别扭,以后能不能不写?可以使用动态代理机制解决这个问题。
- 目前虽然面向接口编程了,但是并没有完全解决对象和对象之间的依赖关系,怎么办?以后使用spring和IoC容器来解决这个问题。
- 对象的创建我不管了,交给spring容器
- 对象和对象之间的关系我也不管了,交给spring容器
动态代理机制
-
什么是代理
- 代购
- 中介
- 以中介为例,中介和代理做的事情是一致的
- 出去打工为什么要找中介?
- 因为中介是专业的,可选的工作种类多。
- 也可能工厂不让个人去找工厂,中介在中间起到一个担保的作用。对个人对厂商多是友好的。
- 出去打工为什么要找中介?
- 以中介为例,中介和代理做的事情是一致的
- …
- 等等这些都是代理
-
什么是代理模式?
- 代理模式是指,为其他对象提供了一种代理以控制对这个对象的访问。
- 在某些情况下一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户类和目标对象之间起到中介的作用。
- 换句话说,是用代理对象,是为了在不修改目标对象的基础上,增强业务逻辑。
-
使用代理模式的作用
- 功能增强:常用的作用是为了在原有的功能之上增加新的功能
- 控制访问
-
实现代理的方式
- 静态代理
- 描述:
- 代理类是自己手工实现的,自己创建的一个Java类,表示代理类
- 同时你所要代理的目标类是确定的
- 目标对象和代理对象必须同时实现同一个接口
- 特点:
- 实现简单
- 容易理解
- 缺点:
- 当目标类增加了,代理类可能也需要成倍的增加。代理类数量过多。
- 当接口中功能增加了,或者修改了,会影响到众多的实现类,那么厂家类和代理类都需要修改。影响比较多。修改的比较多,出错的纪律比较大。
- 描述:
- 动态代理
- 优点
- 在静态代理目标类很多的时候,可以使用动态代理,避免静态代理的缺点。
- 动态代理中目标类即使很多,代理类的数量可以很少,当修改了几口中的方法时,不会影响代理类。
- 概念:
- 在程序执行的过程中,使用JDK的反射机制,创建代理类对象,并动态指定要代理的目标类。
- 动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术
- 在程序的执行过程中,使用jdk的反射机制创建代理对象,并且动态指定要代理的目标类。
- 换句话说:动态代理是一种创建java对象的能力,让你不用把代理类手动写出来就能创建代理对象
- 优点
- 静态代理
-
动态代理的实现【动态代理分为两种】
- JDK动态代理:使用Java反射包中的类和接口实现动态代理的功能。
- 反射包:java.lang.reflect里面有三个类:InvocationHandler,Method,Proxy
- cglib动态代理:cglib是第三方的工具库创建代理对象。(Code Generic Library)字节码生成库
- cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中重写父类中的同名方法,实现功能增强。
- 因为cglib是继承,重写方法,所以要求目标类不能是final修饰的,方法不能是final修饰的。
- cglib的要求目标类比较宽松,只要能继承就可以了(而jdk动态代理还需要实现某个特定的接口)。cglib在很多的框架中使用,比如spring。mybatis都有使用。
- JDK动态代理:使用Java反射包中的类和接口实现动态代理的功能。
-
jdk动态代理的实现
-
反射,Method类,表示方法。类中的方法。通过Method可以执行某个方法
-
jdk动态代理的实现:反射包中有三个类:InvocationHandler,Method,Proxy
-
InvocationHandler(译为:调用处理程序)接口:就有一个方法invoke()
-
invoke()表示代理对象要执行的功能代码,你的代理类要完成的功能就写在invoke()方法中。
- 代理类完成的功能
- 调用目标代码,执行目标方法的功能
- 功能增强,在目标方法调用时,增加功能。
- 代理类完成的功能
-
-
-
// 方法源码public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;// proxy:jdk创建的代理对象。// method:目标类中的方法,jdk提供method对象的,代理类强转为接口,当调用接口的a方法method就是a方法对象,当调用接口中的b方法的时候,method就是b方法对象。// args:目标类中方法的参数,jdk提供的// 返回值Object对应代理类的代理方法的返回值【就是目标类返回的类型,这个invoke方法的返回值也应该是什么类型的数据,如果目标对象没有返回值那么invoke方法的返回值就可以随意指定了】- InvocationHandler接口:表示你的代理类要干什么。- 怎么用:1. 创建类实现接口InvocationHandler2. 重写Invoke()方法,把原来静态代理中代理类要完成的功能写到这里来。2. Method类:表示方法的,确切的说就是目标类中的方法。- 作用:通过Mehtod可以执行某个目标类中的方法,Method.invoke();method.invoke(目标对象,方法的参数)- method.invoke()是用来执行目标方法的。3. Proxy类:核心对象,创建代理对象。之前创建对象都是new类的构造方法现在我们使用Porxy类的方法,代替new的使用。public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) ;// loader:类加载器,负责向内存中加载代理类的类加载器。【对于不同的类加载器有不同的优先级,对于用户类(程序员写的类)的类加载器,都是同一个类加载器,随便取一个类加载器就可以】// interfaces:目标对象实现的接口,也是反射获取的。目标对象实现了什么接口,代理类就是先什么接口// h:我们自己写的,代理类要完成的功能。// 返回值时Object类型的,就是目标对象的代理对象,代理对象肯定能强转成目标类实现的接口的类型,因为目标类和代理类实现了同一个接口
-
实现动态代理的步骤:
-
创建接口,定义目标类要完成的功能
-
创建目标类实现接口
-
创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
- 调用目标方法
- 增强功能
-
使用Proxy类的静态方法,创建代理对象,并把返回值转为接口类型.
-
-
总结:
-
什么是动态代理机制:使用jdk动态代理机制,创建对象的能力,创建代理类的对象.而不用你创建类文件.不用写Java文件.
- 动态:在程序执行时,调用jdk提供的方法才能创建代理类对象.【jdk帮我们生成的代理类也实现了目标类实现的接口】
- jdk动态代理必须有接口,目标类必须实现接口,没有接口时,需要使用cglib动态代理
-
动态代理能做什么:可以在不改变原来目标方法功能的前提下,可以在代理类中增强的功能.
-
代理类似过滤器:在执行目标方法之前执行一些增强功能的代码,在目标方法之后执行一些增强功能的代码。
-
jdk为我们动态生成的这个代理类,继承了java.lang.reflect.Proxy类,实现了目标类实现的所有接口,所以目标类需要实现一个接口才能使用jdk的动态代理,如果没有实现接口只能使用cglib动态代理。【调用Proxy的newProxyInstance方法获取代理对象】
- jdk生成的代理类头
- public final class $Proxy0 extends Proxy { … }
- jdk生成的代理类头
-
动态代理:
- 为目标类实现的接口中所有的方法规定了统一的增强的功能,都写在invoke方法中
- 优点:代理的目标类是可以在程序的运行阶段动态调整的,【所有的方法的增强功能都写在incoke方法中,虽然不像静态代理那样目标类中一个方法在代理类中就有一个增强方法,但是可以通过method对象判断调用的是目标类中的哪个方法,从而执行不同的逻辑来完成给不同的方法定义不同的增强功能】
-
静态代理:
- 为每一个方法都声明了增强的功能,确定是代理类代理的对象都是确定的,
- 缺点:代理类的代码得手动写出来。【但是增强规则可以为每一个方法都写一个不同的规则】
-
不是只有接口才能实现动态代理,只是jdk使用接口这种方式实现的动态代理机制,我们不需要关心动态代理的代理类是怎么生成的我们只要会调用jdk中的方法完成动态代理的功能即可,这只是一种常用的方法,当然用别的方法也可以实现动态代理机制。
-
什么是前置通知?什么是后置通知?
- 前置通知:调用目标方法之前执行的代码或者操作叫做“前置通知”
- 后置通知:调用目标方法之后执行的代码或者操作叫做“后置通知”
-
InvocationHandler中的invoke方法的返回值应该与目标类中的目标方法的返回值一致。【InvocationHandler类中的invoke方法就相当于代理类中的代理方法,在代理方法中完成目标方法的调用和功能的增强】
-
在一个类中想调用另一个类中的方法的时候,一般都将另一个类的对象声明为私有的成员属性/或者静态属性,
- 为什么是成员属性?
- 以前我们写的是测试程序,所以我们想调用某个类的某个方法的时候,直接在main方法中调用实例化某个类的对象在调用某个类的方法。真正写业务的时候是将另一个类的对象定义为私有的成员,以便于当前类的所有方法都能使用这个类中的方法。
- 不管调用代理对象的任何一个方法都会被方法拦截处理器拦截,然后就会调用InvocationHandler类中的invoke方法。
- 所以输出代理对象的时候就会调用invoke方法,因为输出对象的时候自动调用toString方法,所以就会执行InvocationHandler中的invoke方法。
-
-
总结2
-
当目标类中有返回值的时候,
- 那么InvocationHandler类中的invoke方法的返回值必须是能转换成目标类的返回值类型的对象。不然就会抛出ClassCastException。
-
当目标类没有返回值的时候
- 那么InvocationHandler类的invoke方法的返回值可以返回任意值。【这样做没有意义,一般目标类返回什么值,这里就返回什么值】
-
为什么在用sout输出代理对象的时候会调用InvocationHandler类中的invoke方法,
-
因为jdk为我们生成的代理类toString方法底层调用了InvocationHandler类中的invoke方法。
-
代理类toString源码:
public final String toString() {/*因为sout输出的时候会调用对象的toString方法,所以在代理对象被输出的时候,会调用jdk为我们生成的这个代理对象的toString方法。通过这个代理对象的源码发现,底层会调用InvocationHandler类的invoke方法,然后将invoke方法的返回值强转成String类型的。强转失败会抛出ClassCaseException异常。*/ toString方法首先会执行InvocationHandler的invoke方法,所以return (String)super.h.invoke(this,m2,(Object[])null); } -
调用接口中的任何方法都会被invoke方法拦截,都会先执行invoke方法。
//假设接口中的方法是 public Student query(Long id); //那么jdk帮我们生成的这个代理类的query方法就是这样的 public final Student query(Long var1) {/*第一个参数就是当前的代理对象(jdk帮我们传入的),第二个参数就是要执行的方法(我们将代理对象转换成接口类型,调用哪个方法,m2就是哪个方法,也是jdk帮我们传入的),第三个参数是传入的参数,我们面向接口掉方法的时候,给方法传进去的是什么样的参数,第三个参数就是我们传入的这个参数。*///面向接口调用query方法的时候,因为实际的对象是代理对象,会调用代理对象的query方法,代理对象的该方法会调用到InvocationHandler类中的invoke方法,所以invoke方法会拦截接口中所有的方法// 将调用invoke方法的返回值强转成接口中定义的返回值类型,如果强转不成功,抛出异常,所以invoke方法的返回值一般都和接口中定义的返回值一样。换句话说就是和目标类的返回值类型一致。return (Student)super.h.invoke(this,m4,new Object[]{var1}); } -
jdk帮我们生成的这个动态代理类的方法都是final修饰的。
-
-
-
相关文章:
mvc+动态代理
不使用MVC的时候系统存在的缺陷 一个Servlet都负责了那些工作? 负责了接收数据负责了核心的业务处理负责了数据表中的CRUD负责了页面的数据展示… 分析银行转账项目存在那些问题? 代码的复用性太差。(代码的重用性太差) 因为没…...
vue-cli(vue脚手架方式搭建)
1.首先安装node前端环境,可以帮助我们去下载其他的组件 下载完成后,去自己的电脑找到node的文件路径,复制去配置环境变量,在path中配 环境搭配完成后,在cmd中进行测试 ,输入一下两个命令进行测试 2.在hbuilderX中创建一个vue-cli项目(标准的前段项目) 3.组件路由 (1)安装 v…...
CentOS 安装 Docker
文章目录 一、更新yum源二、查看docker是否曾经安装过三、安装所需要的软件包四、设置yum源(也可以设置成国内的阿里源等)五、查看docker版本六、.安装docker (默认全部选y)七、查看docker安装版本八、docker 启动/停止/重启/开机…...
别搞了 软件测试真卷不动了...
内卷可以说是 2022年最火的一个词了。2023 年刚开始,在很多网站看到很多 软件测试的 2022 年度总结都是:软件测试 越来越卷了(手动狗头),2022 年是被卷的一年。前有几百万毕业生虎视眈眈,后有在职人员带头“…...
OJ刷题 第十二篇
21308 - 特殊的三角形 时间限制 : 1 秒 内存限制 : 128 MB 有这样一种特殊的N阶的三角形,当N等于3和4时,矩阵如下: 请输出当为N时的三角形。 输入 输入有多组数据,每行输入一个正整数N,1<N<100 输出 按照给出…...
【计算机专业应届生先找培训还是先找个工作过渡一下?】
计算机专业应届生先找培训还是先找个工作过渡一下? 计算机应届生是先培训还是先工作,这个问题应该困扰了很多专业技能一般的同学,尤其是学历方面还没有优势的普通本专科院校。都说技术与学历优秀的人进大厂,技术一般学历优秀的人能…...
MySQL数据库,联合查询
目录 1. 联合查询 1.1 内查询 1.2 外查询 1.3 自连接 1.4 子查询 1.5 合并查询 1. 联合查询 联合查询,简单的来讲就是多个表联合起来进行查询。这样的查询在我们实际的开发中会用到很多,因此会用笛卡尔积的概念。 啥是笛卡尔积?两张表…...
springboot注解(全)
一、什么是Spring Boot Spring Boot是一个快速开发框架,快速的将一些常用的第三方依赖整合(通过Maven子父亲工程的方式),简化xml配置,全部采用注解形式,内置Http服务器(Jetty和Tomcat࿰…...
进制转换—包含整数和小数部分转换(二进制、八进制、十进制、十六进制)手写版,超详细
目录 1.进制转换必备知识: 1.1 二进制逢2进1 8进制逢8进1 10进制逢10进1 16进制逢16进1 1.2为了区分二、八、十、十六进制,我们通常在数字后面加字母进行区分 2. 二进制与八进制、十六进制相互转换 2.1 二进制转八进制 2.2 八…...
什么是UML?
文章目录 00 | 基础知识01 | 静态建模类图对象图用例图 02 | 动态建模时序图通信图状态图活动图 03 | 物理建模构件图部署图 UML(Unified Model Language),统一建模语言,是一种可以用来表现设计模式的直观的,有效的框图…...
5.3 Mybatis映射文件 - 零基础入门,轻松学会查询的select标签和resultMap标签
本文目录 前言一、创建XML映射文件二、MybatisX插件安装三、mapper标签四、select标签UserMapper接口方法UserMapper.xml 五、resultMap标签定义resultMap标签修改select标签 总结 前言 MyBatis的强大在于它的语句映射,它提供了注解和XML映射文件两种开发方式&…...
“华为杯”研究生数学建模竞赛2020年-【华为杯】B题:汽油辛烷值优化建模(附获奖论文和python代码实现)
目录 摘 要: 1 问题重述 1.1 问题背景 1.2 问题重述 2 模型假设 3 符号说明...
C6678开发概述与Sys/bios基本使用
C6678开发概述 参考开发环境标记及术语创建sys/bios自定义平台运行第一个sys/bios程序Clock模块使用Demo 参考 TMS320C6678 Multicore Fixed and Floating-Point Digital Signal Processor Datasheet TMS320C66x DSP CorePac User Guide 官方手册 创龙6678开发教程 开发环境 …...
python算法中的图算法之网络流算法(详解二)
目录 学习目标: 学习内容: 网络流算法 Ⅰ. 网络流模型 Ⅱ . Ford-Fulk...
企业电子招投标采购系统之项目说明和开发类型源码
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...
ERTEC200P-2 PROFINET设备完全开发手册(8-1)
8.1 IRT通讯实验 这里我们使用APP3 IsoApp,修改源代码usrapp_cfg.h的宏为 #define EXAMPL_DEV_CONFIG_VERSION 3 使能App3,对应的主程序为“usriod_main_isoapp.c” 编译后下载运行。打开4.2建立的TIA项目,添加等时模式组织块,…...
手撕Twitter推荐算法
Twitter近期开源了其推荐系统源码[1,2,3],截止现在已经接近36k star。但网上公开的文章都是blog[1]直译,很拗口,因此特地开个系列系统分享下。系列涵盖: Twitter整体推荐系统架构:涵盖图数据挖掘、召回、精排、规则多…...
JAVA多态性测试的基本实验------JAVA入门基础教程
package duotai;public class Person {public void eat(){System.out.println("人吃饭");}public void Pdrink(){System.out.println("人喝水");} }package duotai;public class Man extends Person {public void eat(){System.out.println("男人吃饭…...
小说作者推荐: 妄鸦合集
《惊悚练习生》作品介绍 主人公叫弥赛亚,宗九的小说是《惊悚练习生》,它的作者是妄鸦倾心创作的一本现代耽美、娱乐圈、才女类型的小说,书中主要讲述了:作者:妄鸦 落魄魔术师宗九穿书了他穿到一本恐怖无限流选秀文里,…...
MySQL-自带工具介绍
目录 🍁mysql 🍁mysqladmin 🦐博客主页:大虾好吃吗的博客 🦐MySQL专栏:MySQL专栏地址 MySQL数据库不仅提供了数据库的服务器端应用程序,同时还提供了大量的客户端工具程序,如mysql&a…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
