zoukankan      html  css  js  c++  java
  • 面试题2

    1.spring依赖注入的原理

    链接:https://www.cnblogs.com/mthoutai/p/7278427.html

    假设我们去看Spring的源代码可能涉及的类和接口相当多,不易掌握。在此我用自己的代码和方式来帮助我们Spring依赖注入的过程。 
    当我们启动Spring容器的时候他会运行以下几个过程: 

    (1、载入Xml配置文件(readXML(String filename))在Spring这个由ApplicationContext类完毕 
    这一步会解析Xml属性。把bean的属性存放到BeanDefinition类中 
    代码例如以下:

     1 /**
     2      * 读取xml配置文件
     3      * @param filename
     4      */
     5     private void readXML(String filename) {
     6            SAXReader saxReader = new SAXReader();   
     7             Document document=null;   
     8             try{
     9              URL xmlpath = this.getClass().getClassLoader().getResource(filename);
    10              document = saxReader.read(xmlpath);
    11              Map<String,String> nsMap = new HashMap<String,String>();
    12              nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间
    13              XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
    14              xsub.setNamespaceURIs(nsMap);//设置命名空间
    15              List<Element> beans = xsub.selectNodes(document);//获取文档下全部bean节点 
    16              for(Element element: beans){
    17                 String id = element.attributeValue("id");//获取id属性值
    18                 String clazz = element.attributeValue("class"); //获取class属性值        
    19                 BeanDefinition beanDefine = new BeanDefinition(id, clazz);
    20                 XPath propertysub =  element.createXPath("ns:property");
    21                 propertysub.setNamespaceURIs(nsMap);//设置命名空间
    22                 List<Element> propertys = propertysub.selectNodes(element);
    23                 for(Element property : propertys){                  
    24                     String propertyName = property.attributeValue("name");
    25                     String propertyref = property.attributeValue("ref");
    26                     PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref);
    27                     beanDefine.getPropertys().add(propertyDefinition);
    28                 }
    29                 beanDefines.add(beanDefine);
    30              } 
    31             }catch(Exception e){   
    32                 e.printStackTrace();
    33             }
    34     }

    2、Bean的实例化 
    在配置文件以bean的id为key。BeanDefinition为value放到Map中

     1 /**
     2      * 完毕bean的实例化
     3      */
     4     private void instanceBeans() {
     5         for(BeanDefinition beanDefinition : beanDefines){
     6             try {
     7                 if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim()))
     8                     sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
     9             } catch (Exception e) {
    10                 e.printStackTrace();
    11             }
    12         }
    13 
    14     }

    3、为Bean的输入注入值。完毕依赖注入

     1 /**
     2      * 为bean对象的属性注入值
     3      */
     4     private void injectObject() {
     5         for(BeanDefinition beanDefinition : beanDefines){
     6             Object bean = sigletons.get(beanDefinition.getId());
     7             if(bean!=null){
     8                 try {
     9                     PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
    10                     for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){
    11                         for(PropertyDescriptor properdesc : ps){
    12                             if(propertyDefinition.getName().equals(properdesc.getName())){
    13                                 Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private
    14                                 if(setter!=null){
    15                                     Object value = sigletons.get(propertyDefinition.getRef());
    16                                     setter.setAccessible(true);
    17                                     setter.invoke(bean, value);//把引用对象注入到属性
    18                                 }
    19                                 break;
    20                             }
    21                         }
    22                     }
    23                 } catch (Exception e) {
    24                 }
    25             }
    26         }
    27     }

    事实上Spring依赖注入的过程就是这么简单,再就是各种细节了。比方懒载入、单例等的额外处理了。

    2.linux脚本

    之前写过bash shell脚本 。略。

    3.集群搭建

    一般都是下载相关的包,解压,部署依赖环境,配置环境变量。略

    4.常用spring注解

    @Component

    作用: 用于把当前类对象存入spring容器中

    属性: value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写

    1 @Component
    2 public class AccountDaoImpl implements IAccountDao {
    3     public void saveAccount() {
    4         System.out.println("保存了账户1111111111111");
    5     }
    6 }

    在bean.xml中配置 

    <context:component-scan base-package="com.itheima"></context:component-scan>

    测试代码

    1 public static void main(String[] args) {
    2      ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    3      IAccountDao dao = ac.getBean("accountDaoImpl",IAccountDao.class);
    4      System.out.println(dao);
    5      dao.saveAccount();
    6      ac.close();
    7  }

    由Component衍生而来的注解:

    Controller:一般用在表现层

    Service:   一般用在业务层

    Repository:一般用在持久层

    @Autowired

    按照类型注入,有多个接口的实现会报错

    自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功

    如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错;

    如果Ioc容器中有多个类型匹配时:先按照类型匹配,如果找到多个类型bean对象,再按照变量名作为bean的id去匹配,如果id不匹配,报错

    Autowired出现位置: 可以是变量上,也可以是方法上

    细节:在使用注解注入时,set方法就不是必须的了。

    @Qualifier

    用于注入数据的注解

    但是在给方法参数注入时可以的

    属性:value:用于指定注入bean的id

     

    @Resource

    作用:直接按照bean的id注入。它可以独立使用

    属性:name:用于指定bean的id

    注意: @Resource`是由JDK提供的注解,在JDK1.9之后移除到扩展模块之中.

    所以如果想使用`@Resource`注解注入数据,请使用1.8及以下版本JDK

     

     

    @Value

    作用:用于注入基本类型和String类型的数据

    属性:value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)SpEL的写法:${表达式}

     

    @Scope

    指定bean的作用范围。

    属性:

        value:指定范围的值。 取值:`singleton` `prototype` `request` `session` `globalsession`

    5.数据库创建索引

     链接:https://blog.csdn.net/tomorrow_fine/article/details/78337735

     1 --创建一个普通索引
     2 create table index1 (
     3 id int, 
     4 name VARCHAR(20),
     5 sex boolean,
     6 INDEX(id)
     7 
     8 );
     9 --查看索引是否被使用
    10 EXPLAIN SELECT * from index1 where id =1 ;
    11 
    12 --创建一个唯一性索引
    13 create table index2(
    14 id int unique,
    15 name varchar(20),
    16 unique index index2_id(id ASC)
    17 );
    18 --查看表结构
    19 SHOW CREATE table index2
    20 
    21 --创建全文索引
    22 create table index3(
    23 id int,
    24 info varchar(20),
    25 FULLTEXT index index3_info(info)
    26 
    27 )ENGINE=MyISAM;
    28 
    29 SHOW CREATE table index3;
    30 
    31 --创建单列索引
    32 CREATE TABLE index4(
    33 id INT,
    34 subject VARCHAR(30),    
    35 INDEX index4_st(subject(10))
    36 );
    37 show create table index4;
    38 
    39 --创建多列索引
    40 CREATE TABLE index5(id INT,
    41 name VARCHAR(20),
    42 sex CHAR(4),
    43 INDEX index5_ns(name,sex)
    44 
    45 );
    46 
    47 --创建空间索引
    48 CREATE TABLE index6(id INT,
    49 space GEOMETRY NOT NULL,
    50 SPATIAL INDEX index6_sp(space)
    51 )ENGINE=MyISAM;

    6.创建视图

    链接:http://www.w3school.com.cn/sql/sql_view.asp

     创建视图语法:

    1 CREATE VIEW view_name AS
    2 SELECT column_name(s)
    3 FROM table_name
    4 WHERE condition

    在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。

    视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。

    注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。

    注释:视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。

    7. 抽象类和接口的区别?

    链接:https://www.cnblogs.com/yongjiapei/p/5494894.html

    1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

    2、抽象类要被子类继承,接口要被类实现。

    3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现

    4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。

    5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。

    6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果

    7、抽象类里可以没有抽象方法

    8、如果一个类里有抽象方法,那么这个类只能是抽象类

    9、抽象方法要被实现,所以不能是静态的,也不能是私有的。

    10、接口可继承接口,并可多继承接口,但类只能单根继承。

  • 相关阅读:
    一句代码实“.NET技术”现批量数据绑定[上篇] 狼人:
    目录搜索Unity与本地库交互
    微软脱机实验五十微软应用程序虚拟化之五APPV 5.1脱机使用应用程序
    文件编码H264编解码器性能测试
    串字符串KMP hdu3613Best Reward
    等待时间clientNYOJ 179 LK's problem
    tag备份Oracle Rman技术总结(一)——备份
    任务队列ThreadPoolExecutor线程池的使用与理解
    数量queuepoj1149 PIGS
    android手机Android屏幕分辨率、密度的正确获取
  • 原文地址:https://www.cnblogs.com/battlecry/p/10397456.html
Copyright © 2011-2022 走看看