手写Spring:第3章-实现Bean的定义、注册、获取
文章目录
- 一、目标:实现Bean的定义、注册、获取
- 二、设计:实现Bean的定义、注册、获取
- 三、实现:实现Bean的定义、注册、获取
- 3.1 工程结构
- 3.2 实现Bean的定义、注册、获取类图
- 3.3 定义Bean异常
- 3.4 BeanDefinition定义和注册
- 3.4.1 BeanDefinition定义
- 3.4.2 BennDefinition定义注册接口
- 3.5 单例注册接口定义和实现
- 3.5.1 单例注册接口
- 3.5.2 单例注册接口的实现
- 3.6 抽象类定义模板方法
- 3.6.1 Bean工厂接口
- 3.6.2 抽象Bean工厂基类,定义模板方法
- 3.6.3 实例化Bean类
- 3.6.4 核心类:默认的Bean工厂实现
- 四、测试:实现Bean的定义、注册、获取
- 五、总结:实现Bean的定义、注册、获取
一、目标:实现Bean的定义、注册、获取
💡 实现 Bean 容器关于 Bean 对象的注册和获取?
- 把 Bean 的创建交给容器,而不是我们在调用时候传递一个实例化好的 Bean 对象。
- 另外还需要考虑单例对象,在对象的二次获取时是可以从内存中获取对象的。
- 此外不仅要实现功能还需要完善基础容器框架的类结构体,否则将来就很难扩容进去其他的功能。
二、设计:实现Bean的定义、注册、获取
💡 实现Bean的定义、注册、获取?
- 首先是在 Bean 注册的时候只注册一个类信息,而不会直接把实例化信息注册到 Spring 容器中。
- 那么就需要修改 BeanDefinition 中的属性
Object
为Class
,接下来就是在获取 Bean 对象时需要处理 Bean 对象的实例化操作以及判断当前单例对象在容器中是否已经缓存起来。
- 首先需要定义 BeanFactory 这样一个 Bean 工厂,提供 Bean 的获取方法
getBean(String name)
,之后这个 Bean 工厂接口由抽象类 AbstractBeanFactory 实现。- 这样用 模板模式 的设计方式,可以统一设计通用核心方法的调用逻辑和标准定义,也就很好的控制了后续的实现者不用关心调用逻辑。
- 按照统一方式执行。那么类型的继承者只需要关心具体方法的逻辑实现即可。
- 在继承抽象类 AbstractBeanFactory 后的 AbstractAutowireCapableBeanFactory 就可以实现相应的抽象方法了。
- 因为 AbstractAutowireCapableBeanFactory 本身也是一个抽象类,所以它只会实现属于自己的抽象方法,其他抽象方法由继承 AbstractAutowireCapableBeanFactory 的类实现。
- 这里就体现了类实现过程中的各司其职,你只需要关心属于你的内容,不是你的内容,不要参与。
- 另外还有块重要的知识点,就是关于单例 SingletonBeanRegistry 的接口定义实现,而 DefaultSingletonBeanRegistry 对接口实现后,会被抽象类 AbstractBeanFactory 继承。
- 现在 AbstractBeanFactory 就是一个非常完整且强大的抽象类了,也能非常好的体现出它对模板模式的抽象定义。
三、实现:实现Bean的定义、注册、获取
3.1 工程结构
spring-step-02
|-src|-main| |-java| |-com.lino.springframework| |-factory| | |-config| | | |-BeanDefinition.java| | | |-SingletonBeanRegistry.java| | |-support| | | |-AbstractAutowireCapableBeanFactory.java| | | |-AbstractBeabFactory.java| | | |-BeanDefinitionRegistry.java| | | |-DefaultListableBeanFactory.java| | | |-DefaultSingletonBeanRegistry.java| | |-BeanFactory.java| |-BeansException.java|-test|-java|-com.lino.springframework.test|-bean| |-UserService.java|-ApiTest.java
3.2 实现Bean的定义、注册、获取类图
- Spring Bean 容器的功能实现,已经具备了一定的设计复杂性,这些复杂的类关系设计在各个接口定义和实现以及在抽象类继承中都有所体现。
- BeanFactory 的定义由 AbstractBeanFactory 抽象类实现接口的
getBean
方法。 - 而 AbstractBeanFactory 又继承实现了 SingletonBeanRegistry 的 DefaultSingletonBeanRegistry 类。这样 AbstractBeanFactory 抽象类就具备了单例 Bean 的注册功能。
- AbstractBeanFactory 中又定义了两个抽象方法:
getBeanDefinition(String beanName)
、createBean(String beanName, BeanDefinition beanDefinition)
,这两个抽象方法分别由 DefaultListableBeanFactory、AbstractAutowireCapableBeanFactory 实现。 - 最终 DefaultListableBeanFactory 还会继承抽象类 AbstractAutowireCapableBeanFactory 也就可以调用抽象类中的
createBean
方法了。
- BeanFactory 的定义由 AbstractBeanFactory 抽象类实现接口的
- 所有的实现都以职责划分、共性分离以及调用关系定义为标准搭建的类关系。
3.3 定义Bean异常
BeansException.java
package com.lino.springframework;/*** @description: 定义 Bean 异常*/
public class BeansException extends RuntimeException {public BeansException(String msg) {super(msg);}public BeansException(String msg, Throwable cause) {super(msg, cause);}
}
3.4 BeanDefinition定义和注册
3.4.1 BeanDefinition定义
BeanDefinition.java
package com.lino.springframework.factory.config;/*** @description: Bean 对象信息定义*/
public class BeanDefinition {/*** bean对象*/private Class beanClass;public BeanDefinition(Class beanClass) {this.beanClass = beanClass;}public Class getBeanClass() {return beanClass;}public void setBeanClass(Class beanClass) {this.beanClass = beanClass;}
}
- 在 Bean 定义类中把
Object
替换为Class
,这样就可以把 Bean 的实例化操作放到容器中处理了。
3.4.2 BennDefinition定义注册接口
BeanDefinitionRegistry.java
package com.lino.springframework.factory.support;import com.lino.springframework.factory.config.BeanDefinition;/*** @description: Bean 定义注册接口*/
public interface BeanDefinitionRegistry {/*** 向注册表中注册 BeanDefinition** @param beanName Bean 名称* @param beanDefinition Bean 定义*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
- Bean 定义注册接口只有一个接口方法,就是向注册表中注册 BeanDefinition。
3.5 单例注册接口定义和实现
3.5.1 单例注册接口
SingletonBeanRegistry
package com.lino.springframework.factory.config;/*** @description: 单例 Bean 注册表*/
public interface SingletonBeanRegistry {/*** 返回在给定名称下注册的(原始)单例对象** @param beanName 要查找的bean的名称* @return 返回注册的单例对象*/Object getSingleton(String beanName);/*** 注册单例对象** @param beanName Bean 对象名称* @param singletonObject Bean 对象*/void registerSingletonBean(String beanName, Object singletonObject);
}
- 这个类比较简单,主要是定义了一个获取单例对象和注册单例对象的接口。
3.5.2 单例注册接口的实现
DefaultSingletonBeanRegistry.java
package com.lino.springframework.factory.support;import com.lino.springframework.factory.config.SingletonBeanRegistry;
import java.util.HashMap;
import java.util.Map;/*** @description: 通用的注册表实现*/
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {private Map<String, Object> singletonObjects = new HashMap<>();@Overridepublic Object getSingleton(String beanName) {return singletonObjects.get(beanName);}@Overridepublic void registerSingletonBean(String beanName, Object singletonObject) {singletonObjects.put(beanName, singletonObject);}
}
- 在 DefaultSingletonBeanRegistry 主要实现
getSingleton
方法和registerSingletonBean
方法。
3.6 抽象类定义模板方法
3.6.1 Bean工厂接口
BeanFactory.java
package com.lino.springframework.factory;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @description: 定义 Bean 工厂接口*/
public interface BeanFactory {/*** 返回 Bean 的实例对象** @param name 要检索的bean的名称* @return 实例化的 Bean 对象* @throws BeansException 不能获取 Bean 对象,抛出异常*/Object getBean(String name) throws BeansException;
}
3.6.2 抽象Bean工厂基类,定义模板方法
AbstractBeanFactory.java
package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.BeanFactory;
import com.lino.springframework.factory.config.BeanDefinition;/*** @description: 抽象的 Bean 工厂基类,定义模板方法*/
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {@Overridepublic Object getBean(String name) throws BeansException {Object bean = getSingleton(name);if (bean != null) {return bean;}BeanDefinition beanDefinition = getBeanDefinition(name);return createBean(name, beanDefinition);}/*** 获取 Bean 对象** @param beanName 要检索的bean的名称* @return Bean 对象*/protected abstract BeanDefinition getBeanDefinition(String beanName);/*** 创建Bean对象** @param beanName 要检索的bean的名称* @param beanDefinition Bean对象* @return 实例化的Bean对象*/protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);
}
- AbstractBeanFactory 首先继承了 DefaultSingletonBeanRegistry,也就具备了使用单例注册类方法。
- 接下来很重要的一点是关于接口 BeanFactory 的实现。
- 在方法
getBean
的实现过程中可以看到,主要是对单例 Bean 对象的获取以及在获取不到时需要拿到 Bean 的定义做相应 Bean 实例化操作。 - 那么
getBean
并没有自身的去实现这些方法,而是只定义了调用过程以及提供了抽象方法,由实现此抽象类的其他类做相应实现。
- 在方法
- 后续继承抽象类 AbstractBeanFactory 的类有两个。
- 包括:
AbstractAutowireCapableBeanFactory
、DefaultListableBeanFactory
,这两个类分别做了相应的实现处理。
- 包括:
3.6.3 实例化Bean类
AbstractAutowireCapableBeanFactory.java
package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;/*** @description: 实现默认bean创建的抽象bean工厂超类*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {@Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition) {Object bean = null;try {bean = beanDefinition.getBeanClass().newInstance();} catch (InstantiationException | IllegalAccessException e) {throw new BeansException("Instantiation of bean failed", e);}registerSingletonBean(beanName, bean);return bean;}
}
- 在 AbstractAutowireCapableBeanFactory 类中实现了 Bean 的实例化操作
newInstance
。 - 在处理完 Bean 对象的实例化后,直接调用
registerSingletonBean
方法存放到单例对象的缓存中去。
3.6.4 核心类:默认的Bean工厂实现
DefaultListableBeanFactory.java
package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;
import java.util.HashMap;
import java.util.Map;/*** @description: 默认的Bean工厂实现类*/
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();@Overrideprotected BeanDefinition getBeanDefinition(String beanName) {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition == null) {throw new BeansException("No bean named '" + beanName + "' is defined");}return beanDefinition;}@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);}
}
- DefaultListableBeanFactory 在 Spring 的源码中也是一个非常核心的类。
- DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 类,也就具备了接口 BeanFactory 和 AbstractBeanFactory 等一连串的功能实现。
- 除此之外这个类还实现了接口 BeanDefinitionRegistry 中的
registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
方法。- 还会看到一个
getBeanDefinition
的实现,这个方法是抽象类 AbstractBeanFactory 中定义的抽象方法。现在注册 Bean 定义与获取 Bean 定义就可以同时使用了。 - 接口定义了注册,抽象类定义了获取,都集中在 DefaultListableBeanFactory 中的
beanDefinitionMap
里。
- 还会看到一个
四、测试:实现Bean的定义、注册、获取
ApiTest.java
@Test
public void test_BeanFactory() {// 1.初始化 BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// 2.注册beanBeanDefinition beanDefinition = new BeanDefinition(UserService.class);beanFactory.registerBeanDefinition("userService", beanDefinition);// 3.第一次获取beanUserService userService = (UserService) beanFactory.getBean("userService");userService.queryUserInfo();// 3.第二次获取beanUserService userService_singleton = (UserService) beanFactory.getBean("userService");userService_singleton.queryUserInfo();
}
- 在此次的单元测试中处理包括:
Bean 工厂、注册 Bean、获取 Bean
三个步骤,还额外增加了一次对象的获取和调用。- 这里主要测试验证单例对象是否正确的存放到了缓存中。
- 此时,我们把
UserService.class
传递给了 BeanDefinition。
测试结果
查询用户信息查询用户信息
- 这里会有两次测试信息,一次是获取 Bean 时直接创建的对象,另外一次是从缓存中获取的实例化对象。
- 此外从调试的截图中看出第二次获取单例对象,是从内存中获取的。
五、总结:实现Bean的定义、注册、获取
- 在 Spring Bean 容器的实现类中要重点关注类之间的职责和关系,几乎所有的程序功能设计都离不开接口、抽象类、实现、继承。
- 而这些不同特性类的使用就可以非常好的隔离开类的功能职责和作用范围。
相关文章:
![](https://img-blog.csdnimg.cn/img_convert/c9caa39d1079a900f30be7eb6ce41641.png#pic_center)
手写Spring:第3章-实现Bean的定义、注册、获取
文章目录 一、目标:实现Bean的定义、注册、获取二、设计:实现Bean的定义、注册、获取三、实现:实现Bean的定义、注册、获取3.1 工程结构3.2 实现Bean的定义、注册、获取类图3.3 定义Bean异常3.4 BeanDefinition定义和注册3.4.1 BeanDefinitio…...
![](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2Fdeda4fee499b4843975bb16d60fa8757~tplv-tt-origin-asy2%3A5aS05p2hQOWklui0uOWOn-WKmw%3D%3D.image&pos_id=exeZewTt)
这些国外客户真直接
最近在某平台上遇到的客户,很大一部分都是非英语国家的客户,然而他们也有很多共性的习惯。 第一种:直接表达自己对这个产品感兴趣,然后接下来就没有下文了,而之所以可以看得懂,则是借助平台本身的翻译系统&…...
![](https://img-blog.csdnimg.cn/80ce3b047a014fcaafa7d387573adcbb.png)
使用Apache Doris自动同步整个 MySQL/Oracle 数据库进行数据分析
Flink-Doris-Connector 1.4.0 允许用户一步将包含数千个表的整个数据库(MySQL或Oracle )摄取到Apache Doris(一种实时分析数据库)中。 通过内置的Flink CDC,连接器可以直接将上游源的表模式和数据同步到Apache Doris&…...
![](https://img-blog.csdnimg.cn/6570e779677947b2999da5d73895ceef.png)
【1++的数据结构】之哈希(一)
👍作者主页:进击的1 🤩 专栏链接:【1的数据结构】 文章目录 一,什么是哈希?二,哈希冲突哈希函数哈希冲突解决 unordered_map与unordered_set 一,什么是哈希? 首先我们要…...
![](https://img-blog.csdnimg.cn/d89cd44d058f4ce18c1390225ced7166.png)
【网络编程】深入了解UDP协议:快速数据传输的利器
(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮࿰…...
![](https://img-blog.csdnimg.cn/4d5ab832b6e94b6f9b5d540af187f15b.png)
WordPress(5)在主题中添加文章字数和预计阅读时间
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 样式图一、添加位置二、找到主题文件样式图 提示:以下是本篇文章正文内容,下面案例可供参考 一、添加位置 二、找到主题文件 在主题目录下functions.php文件把下面的代码添加进去: // 文章字数…...
![](https://img-blog.csdnimg.cn/325704f984354c96be3c8b35f9cd36e9.png)
STM32WB55开发(1)----套件概述
STM32WB55开发----1.套件概述 所用器件视频教学样品申请优势支持协议系统控制和生态系统访问功能示意图系统框图跳线设置开发板原理图 所用器件 所使用的器件是我们自行设计的开发板,该开发板是基于 STM32WB55 系列微控制器所构建。STM32WBXX_VFQFPN68 不仅是一款评…...
![](https://img-blog.csdnimg.cn/2c0ebd76c79f4bd4b04355bc2f406e60.png)
CUDA相关知识科普
显卡 显卡(Video card,Graphics card)全称显示接口卡,又称显示适配器,是计算机最基本配置、最重要的配件之一。就像电脑联网需要网卡,主机里的数据要显示在屏幕上就需要显卡。因此,显卡是电脑进…...
![](https://img-blog.csdnimg.cn/f27d43de6b3d47f1bf9e2f5a8f8e09d0.png)
恒运资本:总市值和总资产区别?
总市值和总财物是财政术语中经常被提到的两个概念,很多人会将它们混淆。在金融领域中,了解这两个概念的差异十分重要。本文将从多个视点深入分析总市值和总财物的差异。 1.定义 总市值是指公司发行的一切股票的商场总价值。所谓商场总价值…...
![](https://img-blog.csdnimg.cn/f92e887de19e4063a7987284851aa16a.png)
CTF安全竞赛介绍
目录 一、赛事简介 二、CTF方向简介 1.Web(Web安全) (1)简介 (2)涉及主要知识 2.MISC(安全杂项) (1)介绍 (2)涉及主要知识 3…...
![](https://img-blog.csdnimg.cn/265f0526da094080b0c5ba73b643706e.png)
DC/DC开关电源学习笔记(四)开关电源电路主要器件及技术动态
(四)开关电源电路主要器件及技术动态 1.半导体器件2.变压器3.电容器4.功率二极管5.其他常用元件5.1 电阻5.2 电容5.3 电感5.4 变压器5.5 二极管5.6 整流桥5.7 稳压管5.8 绝缘栅-双极性晶体管1.半导体器件 功率半导体器件仍然是电力电子技术发展的龙头, 电力电子技术的进步必…...
![](https://img-blog.csdnimg.cn/c2016eb6754e44ab84b820aa0cf55e32.png)
数据可视化与数字孪生:理解两者的区别
在数字化时代,数据技术正在引领创新,其中数据可视化和数字孪生是两个备受关注的概念。尽管它们都涉及数据的应用,但在本质和应用方面存在显著区别。本文带大探讨数据可视化与数字孪生的差异。 概念 数据可视化: 数据可视化是将复…...
![](https://www.ngui.cc/images/no-images.jpg)
C++ socket编程(TCP)
服务端保持监听客户端, 服务端采用select实现,可以监听多个客户端 客户端源码 在这里插入代码片 #include <iostream> //#include <windows.h> #include <WinSock2.h> #include <WS2tcpip.h> using namespace std; #pragma co…...
![](https://www.ngui.cc/images/no-images.jpg)
ldd用于打印程序或库文件所依赖的共享库列表
这是一个Linux命令行指令,将两个常用的命令 ldd 和 grep 组合使用。我来逐一为您解释: ldd: 这是一个Linux工具,用于打印程序或库文件所依赖的共享库列表。通常,当你有一个可执行文件并且想知道它链接到哪些动态库时,你…...
![](https://img-blog.csdnimg.cn/66c6aa2be3484433b55f369fe7f4ccc0.png)
vue+elementUI el-table实现单选
if (selection.length > 1) {this.$refs.table.clearSelection();this.$refs.table.toggleRowSelection(selection.pop());}...
![](https://img-blog.csdnimg.cn/img_convert/cd1f5d804d6de672a94d8b67c3d7f07a.png)
前端组件库造轮子——Message组件开发教程
前端组件库造轮子——Message组件开发教程 前言 本系列旨在记录前端组件库开发经验,我们的组件库项目目前已在Github开源,下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。 文章旨在总结经验,开…...
![](https://img-blog.csdnimg.cn/d0b9bb0a3cfb4a0faf4d4425f3b2ae11.png)
单片机第二季:温度传感器DS18B20
目录 1,DS18B20介绍 2,DS18B20数据手册 2.1,初始化时序 2.2,读写时序 3,DS18B20工作流程 4,代码 1,DS18B20介绍 DS18B20的基本特征: (1)内置集成ADC,外部数字接…...
![](https://img-blog.csdnimg.cn/775632765b6744fbbecbd8fdd097d1ab.png)
抓包工具fiddler的基础知识
目录 简介 1、作用 2、使用场景 3、http报文分析 3.1、请求报文 3.2、响应报文 4、介绍fiddler界面功能 4.1、AutoResponder(自动响应器) 4.2、Composer(设计请求) 4.3、断点 4.4、弱网测试 5、app抓包 简介 fiddler是位于客户端和服务端之间的http代理 1、作用 监控浏…...
![](https://www.ngui.cc/images/no-images.jpg)
监控基本概念
监控:这个词在不同的上下文中有不同的含义,在讲到监控MySQL或者监控Redis时,这里只涉及数据采集和可视化,不涉及告警引擎和事件处理。要是监控系统的话,不但包括数据采集和可视化,而且也包括告警和事件发送…...
![](https://img-blog.csdnimg.cn/img_convert/a25e47d23c0c51e59d851696c2be23d4.gif)
【数据结构】 七大排序详解(壹)——直接插入排序、希尔排序、选择排序、堆排序
文章目录 🍀排序的概念及引用🐱👤排序的概念🐱👓排序运用🐱🐉常见的排序算法 🌴插入排序🎋基本思想:🛫直接插入排序📌算法步骤&…...
![](https://img-blog.csdnimg.cn/098c7fd1537d46078098d181159134c8.png)
【Linux】高级IO --- Reactor网络IO设计模式
人其实很难抵制诱惑,人只能远离诱惑,所以千万不要高看自己的定力。 文章目录 一、LT和ET模式1.理解LT和ET的工作原理2.通过代码来观察LT和ET工作模式的不同3.ET模式高效的原因(fd必须是非阻塞的)4.LT和ET模式使用时的读取方式 二…...
![](https://img-blog.csdnimg.cn/69ae7bf7dbd24ee3ba2e6a742215ae25.png)
Agisoft Metashape相机标定笔记
Lens Calibration(镜头标定) 使用Metashape进行自动相机标定是可能的。Metashape使用LCD显示屏作为标定目标(可选:使用打印的棋盘格图案,但需保证它是平坦的且单元格是正方形)。 相机标定步骤支持全相机标定矩阵的估计ÿ…...
![](https://www.ngui.cc/images/no-images.jpg)
vue-cropper在ie11下选择本地图片后,无显示、拒绝访问的问题
问题:vue-cropper在ie11下选择本地图片后,网页上并未显示出图片,打开F12有报错:拒绝访问blabla的。但是在chrome下一切正常。 开发环境:node14.17.5 , vue2 , vue-cropper0.6.2 , macOS big sur 11.4(M1). 解决办法&…...
![](https://img-blog.csdnimg.cn/e7dedc996d474f69b3a1d2fd94bdfadb.jpeg)
Excel VSTO开发11-自定义菜单项
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 11 自定义菜单项 自定义菜单项可以在插件启动时候添加,即增加到ThisAddIn_Startup() 内。 下面以具体代码说明&#x…...
![](https://img-blog.csdnimg.cn/d6d6f2e5d9b04b80b19e22322855eebe.png)
stm32之30.DMA
DMA(硬件加速方法)一般用于帮运比较大的数据(如:摄像头数据图像传输),寄存器-》DMA-》RAM 或者 RAM-》DMA-》寄存器提高CPU的工作效率 源码-- #include "myhead.h" #include "adc.h"#…...
![](https://img-blog.csdnimg.cn/9ea53473e3e54e9cad4cf51b37b8d746.png)
【LeetCode75】第四十九题 数组中的第K个最大元素
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目很简单,就是给我们一个数组,让我们返回第K大的元素。 那么很直观的一个做法就是我们直接对数组进行降序排序…...
![](https://img-blog.csdnimg.cn/7d755e86adda46d58eacbf73eaec8772.png)
嵌入式面试笔试刷题(day14)
文章目录 前言一、进程控制块1.PCB控制块的作用2.PCB的存储位置 二、进程的三级映射三、return , exit, pthread_exit四、pthread_join作用五、互斥锁和信号量的区别六、怎么判断链表是否有环总结 前言 本篇文章继续我们的刷题之路。 一、进程控制块 这里只讲解进程的PCB控制…...
![](https://img-blog.csdnimg.cn/d63b15c8ea0041bc9d71175052ce6a70.png)
好用免费的Chat GPT(亲测有用)
1、MindLink麦灵 MindLink麦灵 点进登录后 普通用户可以提问100次 2、你问我答 你问我答 无限次数的。 3、灵感 灵感 点击链接后会提示你如何下载使用。 这个有win版和mac版,点击登陆后,每日都会有30次GPT3/3.5的提问。 4、WebTab 在浏览器插件中…...
![](https://img-blog.csdnimg.cn/fbf2ad3fa5c4479090bbbdd1cbd32370.png)
SpringBoot项目--电脑商城【上传头像】
一、易错点 1.错误写法: 把文件存到数据库中,需要图片时访问数据库,数据库将文件解析为字节流返回,最后写到本地的某一个文件.这种方法太耗费资源和时间了 2.正确写法: 将对应的文件保存在操作系统上,然后再把这个文件路径记录下来,因为在记录路径的…...
![](https://img-blog.csdnimg.cn/9331706a154a43aab3e85731e1899d4c.png)
优化SOCKS5的方法
在今天的互联网世界中,保护个人隐私和提升网络速度至关重要。作为一种常用的代理协议,SOCKS5代理服务器不仅可以保护您的隐私,还可以实现更快速的网络访问。本文将为您介绍一些优化SOCKS5代理服务器的方法,以提高网络速度和安全性…...
![](/images/no-images.jpg)
网站开发行业怎么样/全国各大新闻网站投稿
综述 最近跑项目linux用的比较多 在使用vi编辑器时出现了一些问题 特别是在进入vi后 方向键变ABCD删除键失效 有人说可以安装一些强版本的vim;但是,这里给出另一种解决方案 echo "set nocompatible">>~/.vimrc更改配置信息 echo &quo…...
![](/images/no-images.jpg)
大岭山做网站/站外引流推广渠道
冀中能源峰峰集团关于做好2015年度河北省职称计算机应用能力考试考务工作的通知根据邯郸市人力资源和社会保障局《关于做好2015年度河北省职称计算机应用能力考试考务工作有关问题的通知》文件通知,现将2015年度全省职称计算机应用能力统一考试考务工作有关问题通知…...
![](/images/no-images.jpg)
美国地接公司怎么在中国网站做推广/怎样能在百度上搜索到自己的店铺
亲测可用,若有疑问请私信 MySQL5.7.5后only_full_group_by成为sql_mode的默认选项之一,这可能导致一些sql语句失效。 比如在使用group by进行分组查询报错 1 查看自己的sql_mode配置: 在sql命令行中输入select sql_mode;这时我们能够看到自己的…...
![](/images/no-images.jpg)
app开发定制哪家公司好/兰州网站seo诊断
– Start 观看可汗视频 集中趋势 (central tendency) 又称“数据的中心位置”,常用测量方法有均值,中位数和众数。 import numpy as np from scipy import stats# 定义数据集 data_set np.array([23, 29, 20, 32, 23, 21, 33, 25])# 均值(平均值) 数…...
![](/images/no-images.jpg)
中国建设银行官网企业网银登录/长沙seo行者seo09
在Oracle中查看所有的表:select * from tab/dba_tables/dba_objects/cat;看用户建立的表 :select table_name from user_tables; //当前用户的表select table_name from all_tables; //所有用户的表select table_name from dba_tables; //包括系统表select * from user_indexes…...
![](http://dl.iteye.com/upload/p_w_upload/0079/8352/06f503f7-8c77-3f4c-b055-5aa6407e7be8.jpg)
什么是响应式网站/seo点击器
K(在线演示)是一个能够帮助你快速开发web界面的套件,使用简单并且可扩展。使用了HTML/CSS/Javascript技术来设置布局,展示常用的界面元素,并且实现互动的特性,所有这些都是以内容为中心的,并且对…...