发表于: 2020-06-25 23:06:33

1 1604


今天完成的事:

任务一深度思考

1.     Mybatis有哪些常用标签?怎么使用标签来完成动态查询?

 choose (when, otherwise)、

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为 true,就会执行 if 标签中的条件。MyBatis 提供了 choose 元素。if标签是与(and)的关系,而 choose 是或(or)的关系。

choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

<select id="selectByIdDynamic" resultMap="studentMap" parameterType="student">
   select *from student_task1
<where>
       <choose>
           <when test="name!=null">
               student_name like CONCAT(#{name},'%')
                </when>
           <when test="studentNumber!=null">
               AND student_number like CONCAT(#{studentNumber},'%')
                </when>
           <otherwise>
               AND school like CONCAT(#{school},'%')
           </otherwise>
       </choose>
   </where>
</select>

 if、

if标签可用在许多类型的sql语句中:

当where中的条件使用的if标签较多时,如果有一个条件不满足非空条件时,会直接导“WHERE AND”关键字多余的错误SQL。

<select id="selectByIdDynamic" resultMap="studentMap" parameterType="student">
   select *from student_task1
where
<if test="brother!=null and brother!='' ">
       brother like CONCAT(#{brother},'%')
</if>
    <if test="slogan!=null and brother!='' ">
         AND slogan like CONCAT(#{slogan},'%')
</if>
</select>

这时我们可以使用where动态语句来解决。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。

<select id="selectByIdDynamic" resultMap="studentMap" parameterType="student">
   select *from student_task1
<where>
    <if test="brother!=null and brother!='' ">
       brother like CONCAT(#{brother},'%')
</if>
    <if test="slogan!=null and brother!='' ">
         AND slogan like CONCAT(#{slogan},'%')
</if>
   </where>
</select>

set、

if + set 的更新语句

当update语句中没有使用if标签时,如果有一个参数为null,都会导致错误。

当在update语句中使用if标签时,如果前面的if没有执行,则或导致逗号多余错误。使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。

使用if+set标签修改后,如果某项为null则不进行更新,而是保持数据库原值

<update id="updateById" parameterType="student">
   update student_task1
<set>
       <if test="studentNumber!=null">student_number=#{studentNumber},</if>

       <if test="school!=null">school=#{school}</if>

</set>
   where id=#{id}
</update>



trim、

trim是更灵活的去处多余关键字的标签,他可以实践where和set的效果。

 if + trim代替where标签

有四个常用属性

prefix添加前缀
prefixOverrides删除前缀
suffix添加后缀
suffixOverrides删除后缀

下面的例子是如果有匹配上的子语句,就删除掉AND或者OR这个前缀。

<select id="selectByIdDynamic" resultMap="studentMap" parameterType="student">
   select *from student_task1
<trim prefix="WHERE" prefixOverrides="AND|OR">
       <if test="name!=null">
           student_name like CONCAT(#{name},'%')
</if>
       <if test="school!=null and school!=''">
           AND school=#{school}
</if>
   </trim>
</select>

 trim代替set

<update id="updateById" parameterType="student">
   update student_task1
<trim prefix="SET" suffixOverrides=",">
       <if test="studentNumber!=null">student_number=#{studentNumber},</if>
       <if test="school!=null">school=#{school},</if>
       <if test="qqNumber!=null">qq=#{qqNumber},</if>
       <if test="type!=null">study_type=#{type},</if>
       <if test="logLink!=null">log_link=#{logLink},</if>
       <if test="slogan!=null">slogan=#{slogan},</if>
       <if test="brother!=null">brother=#{brother},</if>
       <if test="enterTime!=null">enter_time=#{enterTime},</if>
       <if test="updateTime!=null">update_at=#{updateTime},</if>
       <if test="name!=null">student_name=#{name}</if>
   </trim>
   where id=#{id}

</update>

添加前缀,判断实体类的属性是否为空,符合条件的删除后缀" , "后台输出如下语句:

foreach

主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有 item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:

1.     如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

2.     如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

3.     如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key。

in条件就是where判断后的子查询

比如 

select * from student where Sname='张三bai';/*查询姓名叫张三的学生的信息*/

select * from student where Sname in('张三','李四');/*查询张三和李四的学生的信息*/

select * from student where Sname in(select Sname from sn where Sno='001');/*查询学号是001的学生信息*/


2.什么叫反射?反射的坏处是什么?有哪些反射的应用场景?

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

坏处:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。

做过的反射场景有JDBC原生代码注册驱动,spring和mybatis这两个框架就是通过反射来设计的。

3.什么是SVN,小乌龟是什么,SVN的文件版本号是怎么来的,哪些文件应该上传到SVN,哪些不该上传?Git和SVN的区别又是什么?

    Subversion(SVN) 是一个开源的版本控制系統, 也就是说 Subversion 管理着随时间改变的数据。 这些数据放置在一个中央资料档案库(repository) 中。 这个档案库很像一个普通的文件服务器, 不过它会记住每一次文件的变动。 这样你就可以把档案恢复到旧的版本, 或是浏览文件的变动历史。

进行svn操作需要记住很多操作命令,而且每次都要重复输入。小乌龟就是这样一个简化svn操作的软件。极大的方便了svn操作。

最核心的区别,svn是集中式管理的版本服务器,Git是分布式管理的版本服务器。svn有一个中心服务器管理保存所有文件的修订版本,而Git每一个终端就是一个仓库,客户端并不只提取最新版本的快照,而是把原始的代码仓库完整地镜像下来。每一次的提取操作,实际上都是一次对代码仓库的完整备份。

4.什么是AOP,适用于哪些场景,AOP的实现方案有哪些?    

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。

AOP使用场景

AOP用来封装横切关注点,具体可以在下面的场景中使用:

Authentication 权限

Caching 缓存

Context passing 内容传递

Error handling 错误处理

Lazy loading 懒加载

Debugging  调试

logging, tracing, profiling and monitoring 记录跟踪 优化 校准

Performance optimization 性能优化

Persistence  持久化

Resource pooling 资源池

Synchronization 同步

Transactions 事务

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

AOP相关概念

方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用spring的 Advisor或拦截器实现。

 

连接点(Joinpoint): 程序执行过程中明确的点,如方法的调用或特定的异常被抛出。

 

通知(Advice): 在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。Spring中定义了四个advice: BeforeAdvice, AfterAdvice, ThrowAdvice和DynamicIntroductionAdvice

切入点(Pointcut): 指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点:例如,使用正则表达式。 Spring定义了Pointcut接口,用来组合MethodMatcher和ClassFilter,可以通过名字很清楚的理解, MethodMatcher是用来检查目标类的方法是否可以被应用此通知,而ClassFilter是用来检查Pointcut是否应该应用到目标类上 

引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。Spring中要使用Introduction, 可有通过DelegatingIntroductionInterceptor来实现通知,通过DefaultIntroductionAdvisor来配置Advice和代理类要实现的接口

目标对象(Target Object): 包含连接点的对象。也被称作被通知或被代理对象。POJO

 

AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。

织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

5.Map,List,Array,Set之间的关系是什么,分别适用于哪些场景,集合大家族还有哪些常见的类?

  List,Set都是继承自Collection接口 ,Map和Collectioin接口同级

Array是数组,是List接口实现类ArrayList的底层数据结构。

应用场景:

List添加的元素是有序的可重复。

Set:添加的元素是无序的需要保持唯一性的。

Map:添加的元素是需要用键值对说明映射关系的。


6.Spring的IOC有几种方式?它们之间的差别是什么,应该选择Annonation还是应该选择XML? 

 Annonation和XML 

差别:

xml

优点:

服务器启动后,如果需要修改内容,修改xml不需要重启服务器

缺点:

1.当有成千上万的类的时候,需要配置xml的数据非常庞大,繁琐,有时候会忘记,运行的时候才发现忘了配置

2.大型项目配置文件过多,修改的时候找起来难

Annotation

优点:

配置一个注解就相等于xml配置好几个配置语句

缺点:

服务器启动后,如果需要修改内容,就要修改源码,必须要重启服务器

选择:

如果经常改动、修改,推荐使用xml。如果配置是一劳永逸的,选择annotation。

如果用上springboot,一般会选择annotation

7.JDBCTemplate和JDBC  

JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,

可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。

JdbcTemplate,就是模板,是Spring框架为我们提供的。

所以JDBCTemplate就是Spring对JDBC的封装,通俗点说就是Spring对jdbc的封装的模板。

区别:

jdbc需要每次进行数据库连接, 然后处理SQL语句,传值,关闭数据库。

甚至有时还可能会出现数据库忘记关闭导致连接被占用。

在以后的工作中,客户的需求肯定不是一成不变的,这就导致经常会改动数据库内容。

通过JDBCtemplate我们只需更改需要更改的那一部分内容就可以了,不需要进行全局修改。

Spring将替我们完成所有的JDBC底层细节处理工作。

8.Spring中的IOC是什么意思,为什么要用IOC而不是New来创建实例? 

控制反转,因为用A类如果要用B类的方法的话会造成耦合,一般一个项目会有很多个bean,使用new创建实例会造成指数级的耦合,后期想添加功能就得一层层的改非常麻烦。而IOC把创建实例的主动权交给spring,需要用这个实例的时候只需要通过配置文件注入实例就可以直接使用这个实例的方法,非常方便

9.为什么要使用Interface,而不是直接使用一个实体类来完成任务?Interface和Impl这种方式的好处是什么?

1. 接口首先是一种规范, 接口可以为不同类顺利交互提供标准。

2.接口是抽象的,可以根据子类的不同实际需求来实现。也就是可以有多种不同的实现方式,也就是实现了多态。 

“接口+实现”最常见的优势就是实现类和接口分离,在更换实现类的时候,不用更换接口功能.可以提高代码的复用性。

10.为什么要处理异常,Try/Catch应该在什么样的场景下使用,在真实的系统中,会出现网络中断,DB连接不上的错误吗?多久会发 生一次?

因为处理异常可以让程序先跳过错误的代码一直到执行结束,从而不影响到程序其他代码的运行。

应用场景:

以业务逻辑功能为单位,在最上层加Try-Catch机制。为什么要这样做呢?这主要是增加程序的健壮性,防止因抛出异常过多,导致程序崩溃。

底层代码,在可能出错的地方加Try-Catch机制,用Catch侦测具体的异常,然后就具体的异常,采取相应的解决方案。

底层代码,在需异常追踪时加Try-Catch机制,在Catch块中抛出自定义异常,调试时可迅速定位到错误代码段。

Try-Catch机制会将异常屏蔽掉,必须根据具体的应用场景,具体分析。

正常情况下mysql对于空闲的连接可能会8小时自动关闭。

11.日志应该怎么打,在什么位置,需要打印出来什么样的关键参数? 

     通常一个类只有一个 LOG 对象,如果有父类可以将 LOG 定义在父类中。

日志变量类型定义为门面接口(如 slf4j 的 Logger),实现类可以是log4j、logback等日志实现框架,不要把实现类定义为变量类型,否则日志切换不方便,也不符合抽象编程思想。

使用参数化形式{}占位,[]进行参数隔离

这样一看就知道[]里面是输出的动态参数,{}用来占位类似绑定变量,而且只有真正准备打印的时候才会处理参数,方便定位问题。

输出不同级别的日志:error,warn,info,debug 这四种里的参数

12.为什么需要单步调试?Debug的时候IDE是怎么找到源码的?

因为单步调试可以通过追踪值的变化情况可以精准的定位到bug。

     

添加断点打开debug模式,点击这个强制步入按钮就可以找到最底层的源码了。

13.可否远程连接到线上直接调试?真实的项目中,遇到问题的排查方案是什么?

 

在本地写代码时,如果程序出现问题了,在程序中打的各种log,可以帮助我们调试,找出问题,修改,测试,部署到服务器,再测试。但如果在真实项目中的呢,这样做虽然也可以,显然是不方便的。 

真实项目中通过远程连接进行调试,服务端执行代码,而本地通过远程连接,到服务器获取数据和运行结果的方法。方式有很多如web、ide等。

14.什么是贫血模型,什么是充血模型?为什么我们会强制要求使用贫血模型?

贫血模型:是指领域对象里只有get和set方法,或者包含少量的CRUD方法,所有的业务逻辑都不包含在内而是放在Business Logic层。

充血模型:层次结构和上面的差不多,不过大多业务逻辑和持久化放在Domain Object里面,

Business Logic(业务逻辑层)只是简单封装部分业务逻辑以及控制事务、权限等。


贫血模型在实体类中没有逻辑,更适合大型项目开发和合作开发,解耦也方便后期维护。

15.为什么不可以用Select * from table?  

   select * from table 查询的是这个表中的所有列,但是一般情况下我们只需要查询某一个或多个字段,而不需要所有字段都查询,这样会影响效率,所以在明确知道自己所需字段的情况下不推荐使用SELECT* FROM TABLE。

16.clean,install,package,deploy分别代表什么含义?  

   clean 可将根目录下生成的target文件移除,(清除所有编译结果或者打包结果 ),清理后编译。 

install 项目安装到本地仓库了,并且是jar和pom同时安装。 

package 项目打包到项目的target目录下。java项目生成 jar包, web项目生成war包    

deploy 是将jar包上传远程库的命令。

17.怎么样能让Maven跳过JUnit? 

   <plugin>

        <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-surefire-plugin</artifactId>

                <version>2.22.1</version>

             <configuration>

                   <skipTests>true</skipTests>

             </configuration>

     </plugin>

18.为什么要用Log4j来替代System.out.println?

因为项目上线测试的时候没有开发工具,所以也没有控制台,只能依靠日志文件了解项目信息。    

19.为什么DB的设计中要使用Long来替换掉Date类型?

    Long类型方便传输与增改,date是有点直观,而在数据库中的时间往往不会直接提取给用户,数据库中的时间用来保存数据创建修改的时间戳。如create_at、update_at这种不会被用户直接读取的字段,就可以用long来提高效率。

将date类型转换为long类型

1.有利于计算时间差

2.方便java与数据库之间的传输

3.编码实战可以通过long login_at = System.currentTimeMillis()获得当前时间的long类型 也可以通过Date date1=new Date()来获得当前时间,再用long time=date1.getTime()将其转化为long类型。然后在数据库中的相应字段设置类型为bigint即可,在数据库中取得数据后,可以在转为相应的时间格式。

20.自增ID有什么坏处?什么样的场景下不使用自增ID?

    自增id首先需要是表的主键,在删除一行记录后,id也随之删除,但之后添加的一行记录中的id会在被删除的id后+1,而不是保持id连续性。正是因为自增ID的缺点也就是无法在多个表中,或者多个数据库中保持ID主键唯一不重复,所以若是使用分布式数据库以及数据合并的情况下时不能使用自增ID的。

若是能够有其他的字段能作为主键保证唯一性,无需使用自增ID,在需要该字段保持连续性的时候,不会使用自增id

21.什么是DB的索引,多大的数据量下建索引会有性能的差别,什么样的情况下该对字段建索引?   

在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

在数据量达到几万时,性能差别就比较直观。

1、装载数据后再建立索引。

2、频繁搜索的列可以作为索引。

3、在联接属性上建立索引(主外键)。

4、经常排序分组的列。

5、删除不经常使用的索引。

6、指定索引块的参数,如果将来会在表上执行大量的insert操作,建立索引时设定较大的ptcfree。

7、指定索引所在的表空间,将表和索引放在不同的表空间上可以提高性能。

22.唯一索引和普通索引的区别是什么,什么时候需要建唯一索引。

唯一性索引unique index和一般索引normal index最大的区别就是在索引列上增加了一层唯一约束。添加唯一性索引的数据列可以为空,但是只要存在数据值,就必须是唯一的。

在需要数据保持唯一性的时候创建唯一索引

23.如果对学员QQ号做了一个唯一索引,在插入数据的时候,是否需要先判断这个QQ号已经存在了?  

不需要判断,因为唯一索引作用就是在插入数据的时候就跟数据库已经存在的值做对比,如果有重复值直接报错。

24.CreateAt和UpdateAt的意义分别是创建时间和修改时间,这两个时间应该在什么情况下赋值?是否应该开放给外部调用的接口?   

create_at是在插入时以当时的时间为值插入。 

update_at是在行一旦被修改的时候,以当时时间为值插入。 

这两个字段作为数据的属性,不应该调用给外部的接口。

25.修真类型应该是直接存储Varchar,还是应该存储int?   

修真类型用varchar不如用int查询效率高,但是用int需要对每个特定的值做一个对应修真类型的映射或定义。

26.varchar类型的长度怎么确定?有什么样的原则,和Text和LongText的区别是什么? 

创建表时或者对已存在的表格的类型为varchar的字段的修改时,在varchar后括号内的数字即能存放的最大长度,这个长度是字符个数而不是字节数。

varchar目前的mysql版本最高支持65535字节,按照不同编码规则,对应20000左右或30000个左右的中文字符。 

text的长度为存放最大长度为65,535个字符的字符串。 

longtext存放最大长度为4,294,967,295个字符的字符串。

27.怎么进行分页数据的查询,如何判断是否有下一页?   

使用mysql的limit

select * from tablename limit #{start},#{size}

start是从哪里开始显示

size是每页显示多少条记录

总记录数totalCount

select  count(1) from tablename 

总页数

totalPage=totalCount/pageSize

总记录数/显示记录数,会得到一个大于等于某数的结果,所以总页数就是向上取整得到的数字,只要大于这个数字,就没有有下一页了

28.maven是什么,和Ant有什么区别?   

Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。

1. Maven约定了目录结构,而Ant没有。

2. Maven是申明式的,用pom.xml文件;而Ant是程序式的,构建过程需要自定义,用builder.xml.

3. Maven是有生命周期的,而Ant没有。

4. Maven内置依赖管理和Repository来实现依赖的管理和统一存储;而Ant没有。Maven第一次install的时候会把依赖的jar包和构件从远处库(又叫中央库,http://repol.maven.org/maven2,统一存储maven可以解释的文件资源)下载到本地库(先从本地仓库找)。Maven还可以管理传递依赖。

5.Maven配置比较简单,有很多的约定、规范、标准,可以用较少的代码干更多的事;而Ant配置比较麻烦,需要配置整个构建的过程(但Ant配置灵活)。

明天的计划:给师兄审代码通过后学习使用github上传代码,写任务一总结。

遇见的问题:

收获:通过今天的深度思考,了解了一些java开发的理论知识:比如id自增有什么缺点、为什么要打日志、用接口和接口实现类有什么好处。



返回列表 返回列表
评论

    分享到