容器(可以用来管理所有的组件(类))

核心关注:IOC和AOP

1.IOC

Inversion(反转) Of Control:控制反转
控制:资源的获取方式
1.主动式(要什么资源自己创建)
Person{
Book book=new Book();
Dog dog=new Dog();
//复杂对象的创建时比较庞大的工程
}
2.被动式:资源的获取不是自己创建,而是交给一个容器创建和设置
Person{
Book book;
public void test(){
book.read();
}
}
容器:管理所有的组件(有功能的类),主动的new资源改为被动的接受资源

1.1 DI(Dependency Injection)依赖注入

容器能知道哪个组件(类)运行的时候,需要另外一个组件(类);
容器通过反射的形式,将容器中准备好的Book对象注入(利用反射给属性赋值)到Person中
IOC只是思想,而DI是具体的实现
代码实现:
1.实体类
public class Person {
private String name;
private Integer age;
private String gender;
private String email;
public Person() {
System.out.println("person的构造器!");
}
public void setName(String name) {
System.out.println("设置pserson的name");
this.name = name;
}
public void setAge(Integer age) {
System.out.println("设置person的age");
this.age = age;
}
public void setGender(String gender) {
System.out.println("设置person的gender");
this.gender = gender;
}
public void setEmail(String email) {
System.out.println("设置person的email");
this.email = email;
}
....
...get()
}
2.spring的配置文件ioc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--注册person对象,spring会自动创建这个person对象-->
<bean class="com.Person" id="person01">
<property name="age" value="18"></property>------------->name是bean中的属性,通过set方法反射注入
<property name="email" value="244594537@qq.com"/>
<property name="gender" value="男"/>
<property name="name" value="吴孟达"/>
</bean>
</beans>
3.测试类:
public class Test {
public static void main(String[] args) {
System.out.println("启动spring容器....");
ApplicationContext ioc=new ClassPathXmlApplicationContext("ioc.xml");--------->启动spring的配置文件
System.out.println("spring容器启动成功!");
Person person= (Person) ioc.getBean("person01");----------->此处的person01为spring配置文件中的bean的id
System.out.println(person);
}
}
输出:
启动spring容器....
person的构造器!
设置person的age
设置person的email
设置person的gender
设置pserson的name
spring容器启动成功!
Person{name='吴孟达', age=18, gender='男', email='244594537@qq.com'} 结论:------>发现其执行顺序为:
1.<bean...>元素驱动spring容器调用构造器创建对象
2.<property...>元素驱动spring执行setter方法
如果一个实体类中引用了其他实体类,容器加载的执行顺序
1.第一种情况:范围大的(person引用book)在范围小的前面
spring配置文件内容:
<bean id="person01" class="entity.Person">
<property name="age" value="18"></property>
<property name="name" value="吴孟达"></property>
<property name="book" ref="book"/>
</bean>
<bean id="book" class="entity.Book">
<property name="name" value="java分析"/>
<property name="price" value="32"/>
</bean>
实体类信息:
。。。
测试类信息:
public static void main(String[] args) {
System.out.println("加载spring....");
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功!");
Person person= (Person) ac.getBean("person01");
System.out.println(person.toString());
}
输出:
加载spring....
person实例化!
Book实例化!
Book执行set name方法
Book执行set price方法
person执行set age方法
person执行set name方法
spring容器启动成功!
发现执行顺序为:
1.先实例化两个对象
2.在执行小的set方法
3.再执行大的set方法 第二种情况:小范围的在上
spring配置文件内容:
<bean id="book" class="entity.Book">
<property name="name" value="java分析"/>
<property name="price" value="32"/>
</bean>
<bean id="person01" class="entity.Person">
<property name="age" value="18"></property>
<property name="name" value="吴孟达"></property>
<property name="book" ref="book"/>
</bean>
输出:
Book实例化!
Book执行set name方法
Book执行set price方法
person实例化!
person执行set age方法
person执行set name方法
spring容器启动成功!
执行顺序为:
1.小范围对象实例化
2.小范围对象set方法
3.大范围对象实例化
4.大范围对象set方法

2.源码解析

1.
以此为示例:
<bean id="book" class="entity.Book"></bean>
实际上<bean.../>元素默认一反射的方式来调用该类的无参构造器
底层简单源码如下:
String idStr=...;//解析<bean。。。。/>元素的id属性得到该字段的字符串值为"book"
String classStr=...;//解析class属性得到该字段的值为:entity.Book
Class clazz=Class.forName(classStr);
Object object=clazz.newInstance();//通过反射示例化对象
container.put(idstr,obj);//将对象放入容器给中,container为spring容器 2.
<bean id="person01" class="entity.Person">
<property name="book" ref="book"/>
</bean>
底层的简单源码如下:
String nameStr=...;解析<property.../>元素的name属性得到该字符串的值为book
String refStr=..;解析<property.../>元素的ref属性得到该字符串的值为book
String setterName-"set"+nameStr.subString(0,1).toUpperCase()+name.subString(1);//生成将要调用的setter方法】
Object paramBean=container.get(refStr);//从容器中取到refStr的bean,作为传入参数
Method setter=clazz.getMethod(setterName,parmBean.getClass())//此处的clazz和1的对应起来
setter.incoke(obj,parmBean);//此处的obj和1的对应起来

3.组件在spring容器中是单例的

public static void main(String[] args) {
System.out.println("加载spring....");
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功!");
Person person1= (Person) ac.getBean("person01");
Person person2= (Person) ac.getBean("person01");
System.out.println(person1==person2);------------------------->此时输出为true;
}

4.使用构造器为bean的属性赋值

spring配置文件为:
<bean id="book" class="entity.Book">
<property name="name" value="java分析"/>
<property name="price" value="32"/>
</bean>
<bean id="person01" class="entity.Person">-------------------------------->此处有两个person的bean:这一个使用set方法给属性赋值,调用的是无参构造器
<property name="age" value="18"></property>
<property name="name" value="吴孟达"></property>
<property name="book" ref="book"/>
</bean>
<bean id="person02" class="entity.Person">------------------------------>这里调用的是有参构造器来进行属性赋值
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="book" ref="book"></constructor-arg>
<constructor-arg name="name" value="吴孟达02"></constructor-arg>
</bean>
person类的代码:
public class Person {
private String name;
private Integer age;
private Book book;
public Person() {
System.out.println("person执行无参构造器");
}
public Person(String name, Integer age, Book book) {
this.name = name;
this.age = age;
this.book = book;
System.out.println("person执行有参构造器");
}
get/set方法
}
测试类方法:
public static void main(String[] args) {
System.out.println("加载spring....");
ApplicationContext ac=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功!");
Person person= (Person) ac.getBean("person02");
System.out.println(person.toString());
}
输出:
加载spring...
Book实例化!
Book执行set name方法
Book执行set price方法
person执行无参构造器-------------->调用无参构造器实例化对象,然后调用set方法赋值
person执行set age方法
person执行set name方法
person执行有参构造器-------------->调用有参构造器,并且直接赋值
spring容器启动成功!
Person{name='吴孟达02', age=18, book=Book{name='java分析', price=32}}

5.使用p名称空间为bean属性赋值

1.在spring的xml文件中加入这一句:xmlns:p="http://www.springframework.org/schema/p"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"----------------------------------->加入这一句
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="book" class="entity.Book">
<property name="name" value="java分析"/>
<property name="price" value="32"/>
</bean>
<bean id="person03" class="entity.Person" p:age="18" p:name="吴孟达03" p:book-ref="book"></bean>------>此时可以通过p标签进行赋值
</beans>

6.复杂赋值

1.给属性赋值null
<bean id="person04" class="entity.Person">
<property name="name">
<null></null>---------------------------->使用null标签进行赋值:不能使用<property name="name" value="null">这是付了一个null的字符串
</property>
</bean> 2.属性是引用时
2.1引用外部bean
<bean id="book" class="entity.Book">
<property name="name" value="java分析"/>
<property name="price" value="32"/>
</bean>
<bean id="person04" class="entity.Person">
<property name="name">
<null></null>
</property>
<property name="book" ref="book"></property>------------->如果外边已经有了像引用的Book bean,则使用ref引用:这里意思是:book=ioc.getBean("book")
</bean>
测试代码:
ApplicationContext ioc=new ClassPathXmlApplicationContext("ioc.xml");
Person person= (Person) ioc.getBean("person04");
System.out.println(ioc.getBean("book")==person.getBook());------------->此时输出为true
2.2内部引用
<bean id="person04" class="entity.Person">
<property name="name">
<null></null>
</property>
<property name="book">
<!--对象我们可以使用bean标签创建 book=new Book();引用内部bean-->
<bean class="entity.Book">---------------------------------------->此处需要注意的是:内部bean不能直接通过ioc容器获取:
<property name="name" value="java"></property> ----->如<bean id="bookInner" class="entity.Book">内部bean加上id
<property name="price" value="25"></property> ------>ioc.getBean("bookInner")会获取出错!
</bean>
</property>
</bean>
测试代码为:
ApplicationContext ioc=new ClassPathXmlApplicationContext("ioc.xml");
Person person= (Person) ioc.getBean("person04");
System.out.println(ioc.getBean("book")==person.getBook());------------->此时输出为false 3.为list属性赋值
为psrson新增属性
private List<Book> library;
如何为library赋值
<property name="library">
<!--library=new ArrayLiast<Book>-->
<list>-------------------------------->使用过list标签
<bean class="entity.Book" p:name="java" p:price="14"></bean>------>1.用bean标签创建list元素
<ref bean="book"></ref>-------------------------------------------->2.用ref标签引入外部bean
</list>
</property> 4.为map赋值
为person新增一个属性
private Map map;
springxml中的配置
<property name="map">
<map>-------------------------------------------->使用map标签:map=new HashMap<>();
<entry key="key01" value="张三"></entry>
<entry key="key02" value="18"></entry>
<entry key="book01" value-ref="book"></entry>----->可以使用value-ref引入外部bean
<entry key="key04">
<bean class="entity.Person" p:name="吴孟达" p:age="18" p:book-ref="book"></bean>------>也可以使用该方式引入内部bean
</entry>
<entry key="key05">---->map中嵌套map
<map> </map>
</entry>
</map>
</property> 5.为Properties赋值
person新增一个属性:
private Properties properties;
spring的配置文件中:
<property name="properties">
<!--properties=new Properties();所有的k=v都是String-->
<props>
<!--k=v都是string,值直接写在标签中-->
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property> 6.使用util名称空间创建集合类型的bean
使用场景:如果相同的map或者list在多处都有引用
可以将map或list单独拿出来做个bean
使用步骤
1.在spring的配置文件中加入:xmlns:util="http://www.springframework.org/schema/util"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"---------------------->在spring的配置文件中加入这行
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
。。。。。
</bean>
2.
<!--相当于new LinkedHashMap<>()-->
<util:map id="mymap">
<!--往map中添加元素-->
<entry key="key01" value="张三"></entry>
<entry key="key02" value="18"></entry>
<entry key="book01" value-ref="book"></entry>
<entry key="key04">
<bean class="entity.Person" p:name="吴孟达" p:age="18" p:book-ref="book"></bean>
</entry>
<entry key="key05">
<map></map>
</entry>
</util:map>
3.其他地方的使用
<property name="map" ref="mymap"></property>----->直接根据引用获取即可
也可以在代码中直接获取
Map<String,Object> map= (Map<String, Object>) ioc.getBean("mymap"); 7.util:list的使用和list标签类似
<util:list id="mylist">
<bean class="entity.Person" p:book="西游" p:name="吴孟达"></bean>
<ref bean="mymap"></ref>
<value>12</value>
</util:list>

8.级联属性:属性的属性
<bean id="book" class="entity.Book">
<property name="name" value="java分析"/>
<property name="price" value="32"/>
</bean>
<bean id="person05" class="entity.Person">
<property name="book" ref="book"></property>
<property name="book.price" value="1000"></property>
----->这里通过book.price直接更改:person的book属性的price属性:但这里注意的是这里一改,容器中的book的bean的price属性改为1000
</bean> 9.通过继承实现bean属性的重用
<bean id="person01" class="entity.Person">
<property name="age" value="18"></property>
<property name="name" value="吴孟达"></property>
<property name="book" ref="book"/>
</bean>
这里需要一个personbean,其他属性都一样,只有age属性变为19,则可以这样
<bean id="person06" class="entity.Person" parent="person01">--------->使用parent属性,指定需要继承属性的bean id,这里的继承只是当前bean的配置信息继承,并不是真正的类继承
<property name="name" value="刘丹"></property>
</bean>
结论:
1. 这里的person01和pserson06在容器中是不同的组件(对象)
2.这两个组件的属性都相同,只有name属性值不同
3.因为指定了要继承配置信息的类,所以上述还可以这样写
<bean id="person06" parent="person01">-------------------------->省略了class,因为配置信息继承于person01,所以class配置值可以继承person01的class配置值值
<property name="name" value="刘丹"></property>
</bean>
4.父类的信息不会因为子类而更改!
10.专门建立一个供其他bean继承的bean
<bean id="person01" class="entity.Person" abstract="true">----------------------->加入:abstract="true"
<property name="age" value="18"></property>
<property name="name" value="吴孟达"></property>
<property name="book" ref="book"/>
</bean>
abstract="true"这个bean的配置是一个抽象的,不能获取他的实例,只能被别人继承
此时:
ioc.getBean("person01");-------------------->此时获取会报错,因为这个是被其他bean继承的

7.bean的作用域

1.单例:scope="singleton"
<bean id="person05" class="entity.Person" scope="singleton">
<property name="book" ref="book"></property>
<property name="book.price" value="1000"></property>
</bean>
2.多例:scope="prototype"
<bean id="person05" class="entity.Person" scope="prototype">
<property name="book" ref="book"></property>
<property name="book.price" value="1000"></property>
</bean>
结论:
1.scope="singleton"单例模式:默认
1.1在容器启动完成前就已经创建好对象,保存在容器中
1.2任何获取都是获取之前创建好的对象
2.scope="prototype"多例模式
2.1容器启动默认不会创建多例的bean
2.2每次获取的时候创建这个bean(ioc.getBean("person05"))
2.3每次获取都会创建一个新的对象

8.bean的生命周期(自定义初始化方法和销毁方法)

1.当是单例模式
1.person实体类
public class Person {
//person的无参构造器
public Person() {
System.out.println("person的无参构造器方法...");
}
//自定义初始化方法
public void initMethod(){
System.out.println("person的初始化方法");
}
//自定义对象销毁方法
public void destroyMethod(){
System.out.println("person的销毁方法");
}
}
2.spring的配置文件
<bean id="person" class="entity.Person"
init-method="initMethod"--------------------------->指定自定义的初始化方法
destroy-method="destroyMethod"--------------------->指定自定义的销毁方法
>
</bean>
3.测试类
public static void main(String[] args) {
System.out.println("spring容器启动...");
ConfigurableApplicationContext ioc=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功!");
System.out.println("关闭spring容器...");
ioc.close();---------------------------------------->调用容器的停止方法
System.out.println("关闭spring容器成功!");
}
输出:
spring容器启动...
person的无参构造器方法...
person的初始化方法
spring容器启动成功!
关闭spring容器...
person的销毁方法
关闭spring容器成功! 2.当是多例模式
2.1ioc的配置文件
<bean id="person" class="entity.Person"
scope="prototype"---------------------------->多例模式
init-method="initMethod"
destroy-method="destroyMethod"
>
</bean>
测试代码:
public static void main(String[] args) {
System.out.println("spring容器启动...");
ConfigurableApplicationContext ioc=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功!");
System.out.println("关闭spring容器...");
ioc.close();
System.out.println("关闭spring容器成功!");
}
输出:
spring容器启动...
spring容器启动成功!
关闭spring容器...
关闭spring容器成功!
因为多例模式不是容器启动的时候创创建,而是在ioc.getBean("id")时候创建该对象! 2.2当测试代码为:
public static void main(String[] args) {
System.out.println("spring容器启动...");
ConfigurableApplicationContext ioc=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功!");
ioc.getBean("person");------------------------>多例模式获取bean对象
System.out.println("关闭spring容器...");
ioc.close();
System.out.println("关闭spring容器成功!");
}
输出:
spring容器启动...
spring容器启动成功!
person的无参构造器方法...
person的初始化方法
关闭spring容器...
关闭spring容器成功! 结论:
1.当是单例模式时:Bean的生命周期
(容器启动)构造器方法---->初始化方法----->(容器关闭)销毁方法
2.多实例
获取bean(构造器------>初始化方法---->容器关闭(不会调用销毁方法))

9.Bean的后置处理器

1.自定义一个类实现BeanPostProcessor接口
public class MyBeanPostProcess implements BeanPostProcessor {
/**
* 自定义的初始化方法之前调用
* Object o是容器创建的bean
* String s是spring配置文件中配置的id
*/
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("bean的后置处理器Befor...方法");
System.out.println(s+":"+o);
return o;----->注意:这里不能return null,要不会报错
}
//自定义初始化方法之后执行
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("bean的后置处理器After...方法");
System.out.println(s+":"+o);
return o;------------------------->注意:这里如果return null;则ioc.getBean也是为null;
}
}
2.在spring配置文件中配置后置处理器
<!--实体类配置-->
<bean id="person01" class="entity.Person"
init-method="initMethod"----------------------->perosn类的自定义初始化方法(person实例化时后会调用)
destroy-method="destroyMethod">----------------->person类的自定义销毁方法(spring容器销毁前会调用)
<property name="age" value="18"></property>
<property name="name" value="吴孟达"></property>
</bean>
<!--后置处理器配置-->
<bean id="myBeanPostProcess" class="Test.MyBeanPostProcess"></bean>
3.测试代码如下:
public static void main(String[] args) {
System.out.println("加载spring....");
ApplicationContext ioc=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功!");
Object bean= ioc.getBean("person01");
System.out.println("容器获取的bean:"+bean);
}
4.输出:
person执行无参构造器
person执行set age方法
person执行set name方法
bean的后置处理器Befor...方法
person01:Person{name='吴孟达', age=18, book=null}
person自定义的初始化方法
bean的后置处理器After...方法
person01:Person{name='吴孟达', age=18, book=null}
spring容器启动成功!
容器获取的bean:Person{name='吴孟达', age=18, book=null}
结论:
发现带后置处理器的执行流程如下:

执行顺序:

  • 1.bean实例化
  • 2.执行bean的后置处理器的postProcessBeforeInitialization方法
  • 3.执行自定义的初始化方法
  • 4.执行bean后置处理器的postProcessAfterInitialization方法

1.sprng 简介的更多相关文章

  1. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  2. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  3. Cassandra简介

    在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...

  4. REST简介

    一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...

  5. Microservice架构模式简介

    在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...

  6. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  7. HTTPS简介

    一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...

  8. 【Machine Learning】机器学习及其基础概念简介

    机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  9. Cesium简介以及离线部署运行

    Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...

随机推荐

  1. 你如何确保 main()方法所在的线程是 Java 程序最后结束 的线程?

    我们可以使用 Thread 类的 join()方法来确保所有程序创建的线程在 main()方法退出前结束.

  2. 什么是消费者驱动的合同(CDC)?

    这基本上是用于开发微服务的模式,以便它们可以被外部系统使用.当我们处理 微服务时,有一个特定的提供者构建它,并且有一个或多个使用微服务的消费者. 通常,提供程序在 XML 文档中指定接口.但在消费者驱 ...

  3. 什么是微服务架构中的 DRY?

    DRY 代表不要重复自己.它基本上促进了重用代码的概念.这导致开发和共享库, 这反过来导致紧密耦合.

  4. Leetcode刷题之螺旋矩阵

    矩阵之螺旋矩阵 总体思路: 注意遍历顺序 每次遍历一圈时候不要多加元素 Leetcode54螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素. ...

  5. 8.5_线性控制器设计_轨迹跟踪(Follow a Desired Path)

    平衡点时所有的导数都为0 simulink中建立状态方程模型

  6. React 可视化开发工具 shadow-widget 的非可视开发方法

    Shadow Widget 提倡在可视设计器中开发用户界面,输出转义标签,而非 JSX.许多童鞋可能不知道 SW 同样支持用 JSX 设计界面,开发体验比原生 React 编程好出很多,本文就介绍这方 ...

  7. C#枚举-通过值获取名字,通过名称获取值

    public enum ProtoType { Move = 1, Enter = 2, Leave = 3, Attack, Die, } print("ProtoType.Move:&q ...

  8. 获取bootstrap模态框点击的对应项(e.relatedTarget.dataset)

    //获取绑定的自定义属性值<ul> <li data-toggle="modal" data-index="电表1111" data-targ ...

  9. 如何写好一份晋升PPT(附PPT模板)

    又到了每年晋升述职的时间,在过去的5.6年里,我以评委身份参与了大量的晋升述职(主要是前端,也包括客户端和测试),也辅导了许多(100+)组内外的同学,指导他们书写和完善PPT.过程中我发现大家有许多 ...

  10. 第十三届蓝桥杯省赛C/C++ B组

    @(第十三届蓝桥杯省赛C/C++B组) A顺子日期 答案是1478 B顺子日期 答案14(如果012算的话) C刷题统计 数据范围1e18,所以不能直接暴力,先取余,再暴力剩下的 #include&l ...