Spring IoCDI(3)—DI详解

目录

一、属性注入

二、构造方法注入

小结:构造函数的注入

三、Setter注入

四、三种注入的优缺点分析(面试题)

1、属性注入

优点:

缺点:

2、构造方法注入(Spring4.X推荐)

优点:

缺点:

3、Setter注入(Spring3.X推荐)

优点:

五、@Autowired存在问题

1、引入Autowired的错误代码:

(1)属性注入:

(2)构造方法注入:

(3)Setter方法注入:

(4)启动类代码:

2、Autowired查找依赖顺序:

3、解决方案

(1)解决方案一:根据名称去查

(2)解决方案二:给想要拿到的对象加上@Primary注解

(3)解决方案三:加@Qualifier注解,指定引入的依赖对象

(4)解决方案四:加@Resource注解

4、@Autowired 与 @Resource 的区别(常见面试题)

六、Spring IoC&DI 的总结

1、Spring,Spring Boot 和 Spring MVC的关系以及区别

(1)Spring

(2)Spring MVC

(3)Spring Boot

(4)总结

2、bean的命名

(1)五大注解存储的bean

(2)@Bean注解存储的bean

3、常见面试题


        上篇博客学习了控制反转IoC的细节,接下来就开始学习依赖注入DI的细节。

        依赖注入是一个过程是指IoC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象。我们使用 @Autowired 注解,完成依赖注入的操作。

        简单来说,就是把对象取出来,放到某个类的属性中。在一些文章中,依赖注入也被称之为 “对象注入”、“属性装配”,具体含义需要结合文章的上下文来理解。

        关于依赖注入,Spring也给我们提供了三种方式:

1、属性注入(Field Injection)

2、构造方法注入(Construct Injection)

3、Setter 注入(Setter Injection)

一、属性注入

        属性注入是使用 @Autowired 实现的,将UserService 类注入到UserController类中,UserService 类代码如下:

@Service
public class UserService {public void doService() {System.out.println("do Service...");}
}

        UserController类的实现代码如下:

@Controller
public class UserController {//注入方法1:属性注入@Autowiredprivate UserService userService;public void sayHi() {userService.doService();System.out.println("hi, UserController");}
}

        启动类获取到UserController的doService方法,代码如下:

@SpringBootApplication
public class SpringIoC2Application {public static void main(String[] args) {//获取Spring上下文对象ApplicationContext context = SpringApplication.run(SpringIoC2Application.class, args);//从Spring上下文中获取对象UserController userController = (UserController) context.getBean("userController");//使用对象userController.doService();}
}

        执行结果:

        如果去掉 注解@Autowired,再运行一下程序,结果如下:

        报错了,提示空指针异常,没办法调用doService() 方法,因为userServer为空。原因就是没有加@Autowired注解,没有注入依赖,Spring拿不到这个属性,也自然不会给它初始化了,那么它肯定就是一个空指针了

二、构造方法注入

        构造方法注入就是在类的构造方法中实现注入,代码如下:

@Controller
public class UserController {//注入方法2:构造方法注入private UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService = userService;}public void doController() {userService.doService();System.out.println("do UserController");}
}

注意事项如果类只有一个构造方法,那么@Autowired注解可以省略;但如果类有多个构造方法,那么就需要添加上@Autowired来明确指定要使用哪个构造方法了。下面的代码练习:

@Controller
public class UserController {//注入方法2:构造方法注入private UserService userService;public UserController(){}public UserController(UserService userService) {this.userService = userService;}public void doController() {userService.doService();System.out.println("do UserController");}
}

        加了个无参的构造函数,运行程序会报错,如图:

        报错解释空指针异常,虽然这个类交给Spring管理了,Spring内部也会给我们自动创建对象,但也是通过构造函数创建的,这里我们写了两个构造函数,如果不加@Autowired注解,Spring默认使用无参构造函数,自然也就没有成功创建对象了,那么这个userService也自然是空指针了

        现在代码改一下,把无参构造函数注释掉,再加一个构造函数,代码如下:

@Controller
public class UserController {//注入方法2:构造方法注入private UserService userService;private UserComponent userComponent;
//    public UserController(){
//
//    }public UserController(UserService userService) {this.userService = userService;}public UserController(UserService userService, UserComponent userComponent) {this.userService = userService;this.userComponent = userComponent;}public void doController() {userComponent.doComponent();userService.doService();System.out.println("do UserController");}
}

        运行代码报错了,报错信息如下:

        报错解释没有找到默认的构造方法,因为这里出现了两个构造方法,Spring不知道该用哪个,现在给第二个构造方法加上@Autowired注解,表示让Spring使用被注解的构造方法,代码如下:

@Controller
public class UserController {//注入方法2:构造方法注入private UserService userService;private UserComponent userComponent;
//    public UserController(){
//
//    }public UserController(UserService userService) {this.userService = userService;}@Autowiredpublic UserController(UserService userService, UserComponent userComponent) {this.userService = userService;this.userComponent = userComponent;}public void doController() {userComponent.doComponent();userService.doService();System.out.println("do UserController");}
}

        运行结果:

        程序跑起来了。

小结:构造函数的注入

1只有一个构造函数的情况,可以不加@Autowired

2如果有多个构造函数,需要指定默认的构造函数(通过@Autowired指定,如果未指定,默认使用无参的构造函数)

构造规范如果添加构造函数,把无参构造函数显示添加(也就是把构造函数写下来,再给注释掉)


三、Setter注入

        Setter注入和属性的Setter方法实现类似,只不过在set方法的时候需要加上@Autowired注解,代码如下:

@Controller
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void doController() {userService.doService();System.out.println("do UserController");}
}

        启动类代码:

@SpringBootApplication
public class SpringIoC3Application {public static void main(String[] args) {//拿到Spring上下文ApplicationContext context = SpringApplication.run(SpringIoC3Application.class, args);//拿到Spring上下文对象UserController userController = context.getBean(UserController.class);//使用对象userController.doController();}
}

        执行结果:

        如果我们把@Autowired注解去掉呢?结果如下:

        又是空指针异常,原因和属性注入把@Autowired的情况一样。


四、三种注入的优缺点分析(面试题)

1、属性注入

优点:

        1、简洁、使用方便

缺点:

        1、只能用于IoC容器,如果非IoC容器则不可用,并且只有在使用的时候才会回出现NPE(空指针异常)

        2、不能注入一个final修饰的属性

1 的解释:

        可以看到,它的来源是Spring的,那么就只能用于IoC容器了。

2 的解释:

        final修饰的属性有个特点,必须初始化,如果我们给属性加上final,会有两种解决方案:1、提供构造函数,如图:

        如果加上构造方法,那不就是构造方法注入了吗,也就不是属性注入了,违背了初心。

        2、给它初始化,new 一个对象,如图:

        但是这样不就是我们自己管理我们的代码了吗,并不是Spring帮我们管理了,也违背了初心。

2、构造方法注入(Spring4.X推荐)

SpringBoot和Spring的版本号对应:

Spring Boot3.X -> Spring 6

Spring Boot2.X -> Spring 4

优点:

        1、可以注入final修饰的属性

        2、注入的对象不会被修改

        3、依赖对象在使用前一定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法

        4、通用性好,构造方法是JDK支持的,所以更换任何框架,它都是适用的

1 的解释:final修饰的属性要初始化,构造方法会进行初始化,复合它的要求。

2 的解释:因为构造方法在这个类创建的时候就会给它进行赋值了,不会再对它进行修改。

3 的解释:在类加载的这个阶段,就会执行构造方法了,把依赖对象给初始化完成。

4 的解释:因构造方法是JDK支持的,不再Spring框架也能正常的使用。

缺点:

        1、注入多个对象时,代码会比较繁琐

3、Setter注入(Spring3.X推荐)

优点:

        1、方便在类实例之后,重新对该对象进行配置或注入

1 的解释:因为Setter方法是可以被其他地方调用的,所以即使类已经被实例化了,也可以重新对该对象进行配置或注入。

缺点:

        1、不能注入一个final修饰的属性

        2、注入对象可能会被改变,因为Setter方法可能会被多次调用,就有被修改的风险

1 的解释:因为可能会被多次修改,所以不能使用final修饰。

2 的解释:Setter方法当然能被修改了,这即使它的优点,也是它的缺点。

4、Autowired查找依赖顺序:

1、根据名称和类型去查

2、如果根据名称查不到,就会根据类型去查

        根据名称查不到了,去查找类型,这时如果类型匹配多个,就会报错


五、@Autowired存在问题

        当同一类型存在多个bean时,使用@Autowired会存在问题。代码如下:

@Component
public class BeanConfig {@Beanpublic UserInfo userInfo1() {UserInfo user = new UserInfo();user.setId(6);user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic UserInfo userInfo2() {UserInfo user = new UserInfo();user.setId(7);user.setName("lisi");user.setAge(19);return user;}
}

        此时我们在UserController类里面注入UserInfo类,代码如下:(下面这几个的注入方式都是错误的)

1、引入Autowired的错误代码:

(1)属性注入:

@Controller
public class UserController {@Autowiredprivate UserInfo userInfo;public void sayHi() {System.out.println("hello, controller");}
}

        可以看到,还没运行代码,就报红线了,如图:

(2)构造方法注入:

@Controller
public class UserController {private UserInfo userInfo;@Autowiredpublic UserController(UserInfo userInfo) {this.userInfo = userInfo;}
}

        这个也是,还没运行代码,就报红线了,如图:

(3)Setter方法注入:

@Controller
public class UserController {private UserInfo userInfo;@Autowiredpublic void setUserInfo(UserInfo userInfo) {this.userInfo = userInfo;}public void sayHi() {System.out.println("hello, controller");}
}

        可以看到,这个也报红线了,如图:

(4)启动类代码:

@SpringBootApplication
public class SpringIoC3Application
{public static void main(String[] args) {//拿到Spring上下文ApplicationContext context = SpringApplication.run(SpringIoC3Application.class, args);//拿到Spring上下文对象UserController bean = context.getBean(UserController.class);//使用对象bean.sayHi();}
}

上面这三种方式注入都会出问题,启动程序后,而报错信息也都是一样的(有两个细微的差别,Field和Parameter,下面会介绍),如下图:

        可以看到,程序还没启动就失败了,可以看出来,Spring的依赖注入是在项目启动前就开始注入的了。

        上面报错提示UserController类需要一个bean,但是有两个,下面也打印出是哪两个bean了,Action介绍的就是解决方案。报错日志非常详细

        报错信息说UserController类找不到依赖注入的是哪一个,因为有多个方法被@bean注释,而依赖注入时,三个方法的属性名都是userInfo,先根据userInfo名称查找,但BeanConfig类没有这个方法名,那就只能去根据类名找了,但有2个bean,Spring就不知道要找那个了,并不是@bean注释下的方法名(userInfo1 / userInfo2),Spring并不知道该注入哪个依赖,所以报错了

        在项目启动失败,可以把Filed看都属性,如图:这个是使用属性注入的,会有Field

        构造方法和Setter注入都是第一张报错图,但就不是Field了,而是Parameter,但其实三种注入的报错原因都是一样的。

        解决方案使用属性注入时,就把属性名改成bean修饰的其中之一的方法名就好了;使用@Parimary注解;使用@Qualifier注解;使用@Resource注解

3、解决方案

(1)解决方案一:根据名称去查

属性名改成bean修饰的其中之一的方法名

属性注入:

@Controller
public class UserController {@Autowiredprivate UserInfo userInfo2;public void sayHi() {System.out.println("hello, controller");}
}

构造方法注入:

@Controller
public class UserController {private UserInfo userInfo;@Autowiredpublic UserController(UserInfo userInfo2) {this.userInfo = userInfo2;}
}

Setter方法注入:

@Controller
public class UserController {private UserInfo userInfo;@Autowiredpublic void setUserInfo(UserInfo userInfo2) {this.userInfo = userInfo2;}public void sayHi() {System.out.println("hello, controller");}
}

        执行结果都一样,这里虽然注入了依赖,但没有用这些依赖,所以打印的都是:hello controller,如图:

(2)解决方案二:给想要拿到的对象加上@Primary注解

这个可以理解为依赖注入后,有多个依赖的方法,但默认使用加了@Primary的方法,代码如下:

UserController类:

@Controller
public class UserController {@Autowiredprivate UserInfo userInfo;public void sayHi() {System.out.println(userInfo.toString());System.out.println("hello, controller");}
}

BeanConfig类:

@Component
public class BeanConfig {@Primary@Beanpublic UserInfo userInfo1() {UserInfo user = new UserInfo();user.setId(6);user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic UserInfo userInfo2() {UserInfo user = new UserInfo();user.setId(7);user.setName("lisi");user.setAge(19);return user;}
}

启动类:

@SpringBootApplication
public class SpringIoC3Application
{public static void main(String[] args) {//拿到Spring上下文ApplicationContext context = SpringApplication.run(SpringIoC3Application.class, args);//拿到Spring上下文对象UserController bean = context.getBean(UserController.class);//使用对象bean.sayHi();}
}

        代码运行结果:

        其他注入的方式,使用@Primary注解用法也一样,把想要拿到的对象加上@Primary注解就好了。

(3)解决方案三:加@Qualifier注解,指定引入的依赖对象

UserController类:

@Controller
public class UserController {@Qualifier("userInfo2")@Autowiredprivate UserInfo userInfo;public void sayHi() {System.out.println(userInfo.toString());System.out.println("hello, controller");}
}

BeanConfig类:

@Component
public class BeanConfig {@Beanpublic UserInfo userInfo1() {UserInfo user = new UserInfo();user.setId(6);user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic UserInfo userInfo2() {UserInfo user = new UserInfo();user.setId(7);user.setName("lisi");user.setAge(19);return user;}
}

启动类:

@SpringBootApplication
public class SpringIoC3Application
{public static void main(String[] args) {//拿到Spring上下文ApplicationContext context = SpringApplication.run(SpringIoC3Application.class, args);//拿到Spring上下文对象UserController bean = context.getBean(UserController.class);//使用对象bean.sayHi();}
}

        执行结果:

(4)解决方案四:加@Resource注解

这里和上面的三方案代码改变的只有UserController类,其他都不变,UserController类的代码如下:

@Controller
public class UserController {@Resource(name = "userInfo2")@Autowiredprivate UserInfo userInfo;public void sayHi() {System.out.println(userInfo.toString());System.out.println("hello, controller");}
}

        运行结果如下:

        但是这个注解不是Spring的而是JDK本身自带的,JDK早期也有这样的注解所以Spring不推荐使用这个注解,因为不是自己开发的,如果出现啥问题,不好处理,是有着不可控因素的原因;还有使用自家的东西也肯定会更放心一些

4、@Autowired 与 @Resource 的区别(常见面试题)

1、@Autowired 是 Spring框架提供的注解,而@Resource是JDK提供的注解

2、@Autowired默认是按照类型注入,而@Resource是按照名称注入相比于 @Autowired 来说,@Resource 支持更多的参数设置;例如 name 设置,根据名称获取 Bean


六、Spring IoC&DI 的总结

1、Spring,Spring Boot 和 Spring MVC的关系以及区别

(1)Spring

        简单来说,Spring是一个开发应用框架那是什么样的框架呢?有这么几个标签:轻量级、一站式、模块化,其目的是用于简化企业级应用程序开发

Spring的主要功能管理对象,以及对象之间的依赖关系,面向切面编程、数据库事务管理、数据访问、web框架支撑等等

但是Spring具备高度可开发性,并不强制依赖Spring,开发者可以自由选择Spring的部分或者全部,Spring可以无缝继承第三方框架,比如数据访问框架(Hibernate、JPA等等),web框架(如:Struts、JSF等等)

(2)Spring MVC

        Spring MVC是Spring的一个子框架,Spring诞生之后,大家觉得很好用,于是按照MVC模式设计了一个MVC框架(一些用Spring解耦的组件),主要用于开发WEB应用和网络接口,所以Spring MVC是一个Web框架

Spring MVC基于Spring进行开发的,天生的与Spring框架集成。可以让我们更简洁的进行Web层开发,支持灵活的URL到页面控制器的映射,提供了强大的约定大于配置的契约式编程支持,非常容易与其他视图框架集成,如 Velocity、FreeMarker等等。

(3)Spring Boot

        Spring Boot 是对Spring的一个封装,为了简化Spring一样的开发而出现的,中小型企业,没有成本研究自己的框架,使用Spring Boot 可以更加快速的搭建框架,降低开发成本,让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和一些底层的实现

Spring Boot是脚手架,插拔式搭建项目,可以快速的集成其他框架进来

比如想使用Spring Boot开发Web项目,只需要引入Spring MVC框架即可,Web开发的工作是Spring MVC完成的,而不是Spring Boot,想完成数据访问,只需要引入Mybatis框架即可

Spring Boot只是辅助简化项目开发的,让开发变得更加简单,甚至不需要额外的web服务器,直接生成jar包执行即可。

(4)总结

        Spring MVC和Spring Boot都属于SpringSpring MVC是基于Spring的一个MVC框架,而Spring Boot是基于Spring的一套快速开发整合包

例如之前写的图书管理系统代码中,整体框架是通过SpringBoot搭建的IoC,DI功能是Spring提供的,而Web相关功能是Spring MVC提供的。

        因为这三个专注的领域不同,所以解决的问题也不一样,总的来说,Spring就像一个大家族,有众多衍生产品,但它们的基础都是Spring,上面三者的关系如下图:

2、bean的命名

(1)五大注解存储的bean

1、类名前面两位字母均为大写,则bean名称为该类名本身(特殊情况)

2、不是上面的特殊情况,其他的类名,首字母小写,驼峰形式命名

3、通过 value 属性设置bean名 ,例如:@Controller (value = "user")

(2)@Bean注解存储的bean

1、bean名称为方法名

2、通过name属性设置bean名,例如:@Bean (name = {"u1", "user1"})

3、常见面试题

(1)三种注入方式的优缺点(参考上面)

(2)常见注解有哪些,分别是什么作用?

web url映射@RequestMapping

参数接收和接口响应@RequestParam、@RequestBody、@ResponseBody

bean的存储:@Controller、@Service、@Repository、@Component、@Configuration、@Bean

bean的获取@Autowired、@Qualifier、@Resource

(3)@Autowired 和 @Resource 的区别(参考上面)

(4)说下你对Spring、Spring MVC、Spring Boot的理解(参考上面)


都看到这了,点个赞再走吧,谢谢谢谢谢

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

python数据分析-老龄化分析

一、研究背景介绍和分析安排 中国作为世界上人口最多的国家,其人口结构的变化对国内外经济都有着深远的影响。近年来,中国的老龄人口比例不断上升,这一变化引起了广泛的社会关注和政策讨论。老龄化带来的挑战包括劳动力市场紧缩、养老金负担…

Innodb实现的索引

概念 一种用于提高数据库查询性能的有序的数据结构。通过使用索引,数据库引擎可以快速定位到存储表中的特定数据,而不必逐行遍历整个表。在处理大量数据的时候可以显著加快数据检索的速度。 通过索引列队数据进行排序,降低数据排序的成本&a…

英语学习笔记4——Is this your ...?

Is this your …? 词汇 Vocabulary suit /sut/ n. 西装,正装 suit 的配套: shirt n. 衬衫tie n. 领带,领结belt n. 腰带trousers n. 裤子shoes n. 鞋子 school /skuːl/ n. 学校 所有学校 搭配:middle school 初中    hig…

C++笔记:类与对象(三)->多态

多态 虚函数 先来看一段代码&#xff1a; #include<iostream> using namespace std;class Animal { public :void run() {cout << "I dont know how to run" << endl;} };class Cat : public Animal{ public :void run() {cout << "I …

Elsevier旗下双1区TOP刊,8.8分影响因子加上超低自引率,各指标领跑计算机类SCI

【SciencePub学术】 今天小编给大家带来了一本计算机类的高分优刊解读&#xff0c;隶属于Elsevier出版社&#xff0c;JCR1区&#xff0c;中科院1区TOP&#xff0c;影响因子高达8.7&#xff0c;领域相符的学者可考虑&#xff01; APPLIED SOFT COMPUTING 1 期刊概况 【期刊简…

SD-WAN对云服务的优化

在云服务日益普及的当下&#xff0c;SD-WAN技术正成为众多企业优化网络连接的首选方案。其通过优化云集成和连接&#xff0c;以及增强应用程序性能&#xff0c;为企业带来了前所未有的业务效益。这种革新性的云连接方式极大地促进了企业对全球劳动力和潜在客户的触达能力。 软件…

【设计模式实战】用三种设计模式去优化if-else屎山代码!!!

优化前提 【设计模式】之策略模式【设计模式】之工厂模式&#xff08;三种&#xff09;【设计模式】之模板方法模式 前言 我们之前也学习了不少设计模式&#xff0c;今天给大家介绍一个案例&#xff0c;帮助大家更加熟悉设计模式&#xff0c;并能够在自己写项目的时候能够下意…

PXE远程部署CentOS系统

文章目录 在局域网内搭建PXE服务器PXE 启动组件PXE的优点实验一、搭建PXE服务器&#xff0c;实现远程部署CentOS系统环境准备server关闭防火墙安装组件准备 Linux 内核、初始化镜像文件及PXE引导文件配置启用TFTP 服务配置启动DHCP服务准备CentOS 7 安装源配置启动菜单文件 Cli…

centos7.9系统rabbitmq3.8.5升级为3.8.35版本

说明 本文仅适用rabbitmq为RPM安装方式。 升级准备 查看环境当前版本&#xff1a; # cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) # rabbitmqctl status Status of node rabbitmq01 ... RuntimeOS PID: 19333 OS: Linux Uptime (seconds): 58 Is under …

解决本地启动项目,用IP地址访问失败问题

解决方法&#xff1a;看看index.html页面有没有 这个标签&#xff0c;将它注释掉

Go 语言基础之指针、复合类型【数组、切片、指针、map、struct】

1、数组 特别需要注意的是&#xff1a;在 Go 语言中&#xff0c;数组长度也是数组类型的一部分&#xff01;所以尽管元素类型相同但是长度不同的两个数组&#xff0c;它们的类型并不相同。 1.1、数组的初始化 1.1.1、通过初始化列表{}来设置值 var arr [3]int // int类型的数…

获取波形极值与间距并显示

获取并显示波形的极值与极值间距 1、流程 1、通过signal.find_peaks获取极大值 2、获取极大值下标 3、获取极大值对应的值 4、获取极大值的下标间距(就是隔多远有一个极大值) 5、获取极大值间距的标准差、方差、均值、最大值 6、图形展示波形图并标记极大值2、效果图 3、示…

专项技能训练五《云计算网络技术与应用》实训8-1:建立基于OpenvSwitch的GRE隧道

文章目录 建立基于OpenvSwitch的GRE隧道1. 使用VMware安装2个CentOS 7虚拟机&#xff0c;安装时记得都开启CPU虚拟化&#xff0c;第一台命名为“Docker”&#xff0c;第二台命名为“KVM”。2. 安装完虚拟机后&#xff0c;进入虚拟机&#xff0c;修改网络配置&#xff08;onboot…

软件架构的艺术:探索演化之路上的18大黄金原则

实际工作表明&#xff0c;一步到位的设计往往不切实际&#xff0c;而演化原则指导我们逐步优化架构&#xff0c;以灵活响应业务和技术的变化。这不仅降低了技术债务和重构风险&#xff0c;还确保了软件的稳定性和可扩展性。同时&#xff0c;架构的持续演进促进了团队协作&#…

新华三VRRP配置

新华三VRRP配置 配置步骤 (1).基础配置&#xff1a; CORE1&#xff1a; [CORE1]vlan 10 //创建vlan10 [CORE1-vlan10]int vlan 10 //进入vlanif 10 [CORE1-Vlan-interface10]ip add 192.168.10.1 24 //配置ip [CORE1-Vlan-interface10]int g1/0/2 //进入接口 [C…

常见错误以及如何纠正它们

团队和关键结果目标 (OKR) 之间的关系是深刻且至关重要的。总而言之&#xff0c;一切都应该是相互关联的。正如《团队的智慧》一书中所强调的&#xff1a; 在团队中&#xff0c;没有什么比每个成员对共同目标和一组相关绩效目标的承诺更重要的了&#xff0c;而团队对此负有共同…

通过管理系统进行升级怎么选?

现在通过系统来做办公效率提升的又很多&#xff0c;但怎么选&#xff0c;确实很关键。 我们是在去年年初的时候进行企业系统化的。当时刚摘下口罩&#xff0c;领导也是意识到团队办公的不便&#xff0c;数据管理的混乱&#xff0c;业务流转的低效等原因&#xff0c;开始寻找各…

CUDA、CUDNN、Pytorch三者之间的关系

这个东西嘛&#xff0c;我一开始真的是一头雾水&#xff0c;安装起来真是麻烦死了。但是随着要复现的项目越来越多&#xff0c;我也不得不去学会他们是什么&#xff0c;以及他们之间的关系。 首先&#xff0c;一台电脑里面允许有多种版本的cuda存在&#xff0c;然后cuda分为run…

大数据API技术分享:使用API接口采集淘宝数据(商品详情丨关键词搜索丨店铺所有商品)

使用API接口采集淘宝数据&#xff08;商品详情、关键词搜索、店铺所有商品&#xff09;是大数据领域常见的应用场景。以下是一些关于如何使用API接口进行这些操作的技术分享&#xff1a; 1. 获取API权限 首先&#xff0c;你需要在淘宝开放平台注册成为开发者&#xff0c;并创建…

从简单逻辑到复杂计算:感知机的进化与其在现代深度学习和人工智能中的应用(下)

文章目录 第一章&#xff1a;感知机的局限性1.1 异或门的挑战1.2 线性与非线性问题 第二章&#xff1a;多层感知机2.1 已有门电路的组合2.2 实现异或门 第三章&#xff1a;从与非门到计算机 文章文上下两节 从简单逻辑到复杂计算&#xff1a;感知机的进化与其在现代深度学习和人…