1.nginx代理主要处理什么问题?
2.你对面向对象的理解?
封装:将对象的属性特征包装到一个程序单元中,吧实现细节隐藏起来通过公用的方法来展现类对外提供的功能,提高类的内聚选哪个,降低对象之间的耦合性。
继承:对原有的类进行拓展,值从已有的类中派生新的类,新的类能够吸收已有类的数据属性和行为并能够扩展新的功能。
多态:是由继承的基础上,指的是允许不同类的对象对同一条消息做出响应,根据对象创建实列的不同调用不同的方法,也就是说,同一种类型的对象执行同一个方法是可以表示出不同的行为特征,说白了就是:同一种事物的不同的表现形式。
抽象:就是忽略一个主题中与当前目标无关的哪些方面,以便更充分地注意与当前目标有关的方面,抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节,抽象类包括两个方面,一是过程的抽象,二是数据的抽象。
3.springboot的了解?
springboot是spring中的一个子工程,用一些固定的方法来构建生产级别的spring应用,springboot推崇约定大于配置的方式以便于尽可能快熟的启动并运行程序,其实springboot被称为搭建程序脚手架,其最主要的作用就是帮我们快熟的构建庞大的spring项目,并且尽可能减少一切xml位置,做到开箱即用,迅速上手,让我们可以关注与业务而非配置。
4.springboot中经常用的注解?
@springbootApplication其中包含:
@confinguration与springbootconfinguration作用相同,都是用来声明当前类是配置,这里表明是springboot主类使用的配置类,
@componentscan用来扫描被这些注解标识的类,最终生成IOC容器的bean,默认扫描范围是@componentscan注解所在配置类包及子包的类。
@EnableAutoConfinuration是springboot实现自动化配置的核心注解通过这个注解把spring应用,所需的bean注入到容器中
@repository持久层注入spring容器
@service业务层
@controller控制层
@Component普通pojo注入spring容器,
@ResponseBody的作用其实是将java对象转为json格式的数据
@RestController这个注解就是@controller+RespnseBody的组合。
@Autowircd默认按类型装配,如果发现找到多个bean则按照name方式对比,如果还有多个,就会出现异常
@Qualifier spring的注解按名字诸如一般当出现两个及以上bean时不知道要注入哪个结合@Autowircd使用
@Resurce默认按名字注入,要是()中加入了name属性注入找不到name那么就会报错,若没有name属性,就根据属性名称注入,如果匹配不成功则按照类型匹配,要是匹配还是不成功就报错。
5.你遇到过的异常有哪些?
6.数据库中表是怎么连接的?
内连接、自连接、外连接(左、右、全)、交叉连接
内连接:只有两个元素表相匹配的才能在结果集中显示。
外连接:
左外连接:左边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。
右外连接:右边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。
全外连接:连接的表中不匹配的数据全部会显示出来。
交叉连接: 笛卡尔效应,显示的结果是链接表数的乘积。
7.数据库三大范式?
第一范式:每个列都不可以再拆分。
第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分
第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键
8.java中的关键字?
1)48个关键字:abstract、assert、boolean、break、byte、case、catch、char、class、continue、default、do、double、else、enum、extends、final、finally、float、for、if、implements、import、int、interface、instanceof、long、native、new、package、private、protected、public、return、short、static、strictfp、super、switch、synchronized、this、throw、throws、transient、try、void、volatile、while。
2)2个保留字(现在没用以后可能用到作为关键字):goto、const。
3)3个特殊直接量:true、false、null。
9.RabbitMQ 有了解多少?
主要是:解耦、异步、削峰。
解耦:A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃…A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。如果使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。
就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦。
异步:A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求。如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms。
[
](https://blog.csdn.net/ThinkWon/article/details/104588612)
削峰:减少高峰时期对服务器压力。
消息队列有什么优缺点?RabbitMQ有什么优缺点?
优点上面已经说了,就是在特殊场景下有其对应的好处,解耦、异步、削峰。
缺点有以下几个:
系统可用性降低
本来系统运行好好的,现在你非要加入个消息队列进去,那消息队列挂了,你的系统不是呵呵了。因此,系统可用性会降低;
系统复杂度提高
加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂性增大。
一致性问题
A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。
所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用,还是得用的。
你们公司生产环境用的是什么消息中间件?
这个首先你可以说下你们公司选用的是什么消息中间件,比如用的是RabbitMQ,然后可以初步给一些你对不同MQ中间件技术的选型分析。
举个例子:比如说ActiveMQ是老牌的消息中间件,国内很多公司过去运用的还是非常广泛的,功能很强大。
但是问题在于没法确认ActiveMQ可以支撑互联网公司的高并发、高负载以及高吞吐的复杂场景,在国内互联网公司落地较少。而且使用较多的是一些传统企业,用ActiveMQ做异步调用和系统解耦。
然后你可以说说RabbitMQ,他的好处在于可以支撑高并发、高吞吐、性能很高,同时有非常完善便捷的后台管理界面可以使用。
另外,他还支持集群化、高可用部署架构、消息高可靠支持,功能较为完善。
而且经过调研,国内各大互联网公司落地大规模RabbitMQ集群支撑自身业务的case较多,国内各种中小型互联网公司使用RabbitMQ的实践也比较多。
除此之外,RabbitMQ的开源社区很活跃,较高频率的迭代版本,来修复发现的bug以及进行各种优化,因此综合考虑过后,公司采取了RabbitMQ。
但是RabbitMQ也有一点缺陷,就是他自身是基于erlang语言开发的,所以导致较为难以分析里面的源码,也较难进行深层次的源码定制和改造,毕竟需要较为扎实的erlang语言功底才可以。
然后可以聊聊RocketMQ,是阿里开源的,经过阿里的生产环境的超高并发、高吞吐的考验,性能卓越,同时还支持分布式事务等特殊场景。
而且RocketMQ是基于Java语言开发的,适合深入阅读源码,有需要可以站在源码层面解决线上生产问题,包括源码的二次开发和改造。
另外就是Kafka。Kafka提供的消息中间件的功能明显较少一些,相对上述几款MQ中间件要少很多。
但是Kafka的优势在于专为超高吞吐量的实时日志采集、实时数据同步、实时数据计算等场景来设计。
因此Kafka在大数据领域中配合实时计算技术(比如Spark Streaming、Storm、Flink)使用的较多。但是在传统的MQ中间件使用场景中较少采用。
[
](https://blog.csdn.net/ThinkWon/article/details/104588612)
10.你写过最长的SQL语句有多少行?
11.你觉得你最擅长的是什么优势在哪里?
12.如果说你表现的不好你要怎么说服我?
中移物联面试总结
1.你项目中主要用到的技术有哪些?
2.springboot常用的注解?
3.springboot的运行原理?
Spring Boot运行原理
实际上Spring Boot并不是要替代Spring框架,我们知道在JDK1.5推出注解功能以后,Spring框架实现了大量的注解来替代原有的基于XML的配置,主要用于配置管理、Bean的注入以及AOP等相关功能的实现。然而,随着Spring注解的数量越来越多,并且被大量的使用,尤其是相同的多个注解会被大量重复地用到各个类或者方法中。这样就导致了繁琐的配置及大量冗余的代码。
到这里你也许就会想到既然这么多Spring注解很繁琐,那么可不可以将其组合一下呢?通过定义一些新的注解,将功能进行分类,不同的Spring注解通过新的注解定义进行一定的组合,这样对于大部分通用场景下,只需要引入一个新的注解,就自动包含了与之相关的其他Spring注解?没错!Spring Boot说到底就是这么个玩意!
但是,要实现注解的组合并不是简单的把多个注解牵强的叠加在一起,这里涉及到一些编程语言上的实现,例如要组合一个注解,那么该注解是否支持注解到别的注解上呢(略微有点拗口)?还有如果组合注解后,因为注解的背后还涉及到Spring容器上下文的初始化以及Bean注入相关的逻辑,如果一个A注解涉及的Bean,涉及到另外一个B注解涉及到的Bean的初始化;也就意味着A注解的Bean初始化,需要在B注解的Bean初始化完成后才能进行注入,否则就会导致Bean依赖注入的失败。
Spring Boot框架本质上就是通过组合注解的方式实现了诸多Spring注解的组合,从而极大地简化了Spring框架本身的繁琐配置,实现快速的集成和开发。只是要这样实现,也需要一定的基础条件!
元注解
说到底Spring Boot框架是在Spring框架的基础上做了一层二次封装,最重要的特点就是Spring Boot框架定义了一些新的注解来实行一些Spring注解的组合,而Spring注解则是基于JDK1.5+后的注解功能的支持来完成的。
关于JDK的注解如果想要注解到别的注解上,就需要将其定义为元注解,所谓的元注解,就是可以注解到其他注解上的注解,被注解的注解就是我们上面说到的组合注解。而Spring框架的很多注解都是可以作为元注解的,并且Spring框架本身也实现了很多组合注解,例如我们常用的注解@Configuration就是一个这样的组合注解。因此,有了这样一个条件Spring Boot的实现才有了基础条件!
条件注解@Conditional
Spring 4提供了一个通用的基于条件的注解@Conditional。该注解可以根据满足某一个特定条件与否来决定是否创建某个特定的Bean,例如,某个依赖包jar在一个类路径的时候,自动配置一个或多个Bean时,可以通过注解@Conditional注解来实现只有某个Bean被创建时才会创建另外一个Bean,这样就可以依据特定的条件来控制Bean的创建行为,这样的话我们就可以利用这样一个特性来实现一些自动的配置。
而这一点对于Spring Boot实现自动配置来说是一个核心的基础能力,从本质上来说Spring Boot之所以可以实现自动注解配置很大程度上也是基于这一能力。在Spring Boot中以@Conditional为元注解又重新定义了一组针对不同场景的组合条件注解,它们分别是:
@ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
@ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
@ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。
@ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
@ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
@ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
@ConditionalOnExpression:基于SpEL表达式的条件判断。
@ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
@ConditionalOnResource:当类路径下有指定的资源时触发实例化。
@ConditionalOnJndi:在JNDI存在的条件下触发实例化。
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。
4.springboot与springmvc的区别在哪里?
5.你对springboot了解多少?
(有了)
6.springboot中有几种配置文件?
7.springboot能不能兼容老项目?
8.springboot主要是用来做什么的?
9.IOC是什么?
IOC就是控制反转(就是将原本由程序代码直接操作的对象的调用权交给容器),目的是为了减低计算机代码的耦合度,所谓的耦合度就是代码中的逻辑关系不要太紧密,避免后面改的人会因为不懂业务逻辑导致改错代码;除此之外也避免我们每次创建新的对象,减少对应的代码量。我们实际代码过程中最常见的方式是依赖注入(DI Dependency Injection),所谓依赖注入就是通过构造注入或者set进行注入。依赖查找(DL Dependency Lookup)这是通过名称和类型查找bean。
[
](https://blog.csdn.net/u012994320/article/details/88583627)
10.AOP是什么?
AOP分为五大部分:
(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知。
(2)JointPoint(连接点):程序执行中明确的点,一般是方法的调用。
(3)Advice(通知):AOP在特定的切入点上做出的增强处理,有before,after,afterRunning,afterThrowing,around;
(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式;
(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强,Spring的AOP可以使用JDK代理,也可以使用CGLIB代理,前者基于接口,后者是基于子类。
- 接口和抽象类的区别
- 什么时候使用接口?什么时候使用抽象?如何选择Java接口还是抽象类
- 谈谈你用的最熟悉的集合
- list的实现方法和实现类有哪些
- arraylist和linkedlist有什么区别
- hashmap和hashtable有什么区别
- 有没有看过hashmap的底层源码
- 有没有做过多线程开发
- 一张千万数据的表中有一些个人信息(姓名,身份证),如何能高效通过身份证查询一个人出来(索引,IO)
- 一张千万数据的表有人身份证数据重复了,如何只显示一条数据(去重,分组)
- 一张千万数据的表如何把重复数据全部显示出来(having)
- spring bean的生命周期
- spring如何解决循环依赖问题(三级缓存)
- 在用rabbitmq中是作为一个生产者还是消费者
- 假设一个订单给到你消费,你的代码里面可能有bug读取到这条记录的时候,程序执行报错,订单也丢失了,如何解决这个问题(消费ack机制)
- spring bean 生命周期
通过构造方法实例化 Bean 对象。
通过 setter 方法设置对象的属性。
通过Aware,也就是他的子类BeanNameAware,调用Bean的setBeanName()方法传递Bean的ID(XML里面注册的ID),setBeanName方法是在bean初始化时调用的,通过这个方法可以得到BeanFactory和 Bean 在 XML 里面注册的ID。
如果说 Bean 实现了 BeanFactoryAware,那么工厂调用setBeanFactory(BeanFactory var1) 传入的参数也是自身。
把 Bean 实例传递给 BeanPostProcessor 中的 postProcessBeforeInitialization 前置方法。
完成 Bean 的初始化
把 Bean 实例传递给 BeanPostProcessor 中的 postProcessAfterInitialization 后置方法。
此时 Bean 已经能够正常时候,在最后的时候调用 DisposableBean 中的 destroy 方法进行销毁处理
- spring mvc工作流程
用户向服务器发送请求,请求被spring前段控制器捕获。
dispatcherservicet(分发器)(第死霸(r))对请求的URL进行一个解析,得到请求资源后根据URL,调用handlermapping(映射器)获得handler(处理器)配置的相关对象,以处理器执行链对象形式返回。分发器获得的handler,选择一个合适的handleradapter(er哒t),提取request的模型数据,填充handler参数,开始执行handler,handler执行完成后,向分发器返回一个model and view(模型视图)对象,根据模型视图,选择一个合适的view resolver(视图解析器)(瑞造味)返回给分发器,视图解析器结合模型和视图,来渲染视图最后将渲染结果返回给客户端
get和post的区别?
URL可见性(重点):
get,参数在URL是可见的,而post,URL参数不可见的
数据传输上(重点):
get,通过拼接URL进行传递参数,post通过body提传输参数。
缓存性(可说):
后退页面的反应(可说):
get请求页面后退时,不产生影响,post请求页面后退时,会重新提交请求
传输数据的大小(可说):
get一般传输数据大小不超过2k~4k(根据浏览器不同,限制不一样,但相差不大)
post请求传输数据大小根据php.ini配置文件设定,也可以无限大。
安全性(重点):
这个也是最不好分析的,原则上post肯定要比get安全,毕竟传输参数时url不可见,但也挡不住部分人闲的没事在那抓包玩。安全性个人觉得是没多大区别的,防君子不防小人就是这个道理。对传递的参数进行加密,其实都一样。
数据包(可说):
GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
Linux的常用命令?
目录切换:cd
cd / 切换到根目录
cd /usr 切换到根目录下的usr目录
cd ../ 切换到上一级目录 或者 cd ..
cd ~ 切换到home目录
cd - 切换到上次访问的目录
目录查看:
命令:ls [-al]
ls 查看当前目录下的所有目录和文件
ls -a 查看当前目录下的所有目录和文件(包括隐藏的文件)
ls -l 或 ll 列表查看当前目录下的所有目录和文件(列表查看,显示更多信息)
ls /dir 查看指定目录下的所有目录和文件 如:ls /usr
[
](https://blog.csdn.net/qq_23329167/article/details/83856430)
目录操作【增,删,改,查】
创建目录【增】 mkdir
命令:mkdir 目录
mkdir aaa 在当前目录下创建一个名为aaa的目录
mkdir /usr/aaa 在指定目录下创建一个名为aaa的目录
删除目录或文件【删】rm
命令:rm [-rf] 目录
删除文件:
rm 文件 删除当前目录下的文件
rm -f 文件 删除当前目录的的文件(不询问)
删除目录:
rm -r aaa 递归删除当前目录下的aaa目录
rm -rf aaa 递归删除当前目录下的aaa目录(不询问)
全部删除:
rm -rf 将当前目录下的所有目录和文件全部删除
rm -rf / 【自杀命令!慎用!慎用!慎用!】将根目录下的所有文件全部删除
[
](https://blog.csdn.net/qq_23329167/article/details/83856430)
注意:rm不仅可以删除目录,也可以删除其他文件或压缩包,为了方便大家的记忆,无论删除任何目录或文件,都直接使用 rm -rf 目录/文件/压缩包
目录修改【改】mv 和 cp
一、重命名目录
命令:mv 当前目录 新目录
例如:mv aaa bbb 将目录aaa改为bbb
注意:mv的语法不仅可以对目录进行重命名而且也可以对各种文件,压缩包等进行 重命名的操作
二、剪切目录
命令:mv 目录名称 目录的新位置
示例:将/usr/tmp目录下的aaa目录剪切到 /usr目录下面 mv /usr/tmp/aaa /usr
注意:mv语法不仅可以对目录进行剪切操作,对文件和压缩包等都可执行剪切操作
三、拷贝目录
命令:cp -r 目录名称 目录拷贝的目标位置 -r代表递归
示例:将/usr/tmp目录下的aaa目录复制到 /usr目录下面 cp /usr/tmp/aaa /usr
注意:cp命令不仅可以拷贝目录还可以拷贝文件,压缩包等,拷贝文件和压缩包时不 用写-r递归
[
](https://blog.csdn.net/qq_23329167/article/details/83856430)
搜索目录【查】find
命令:find 目录 参数 文件名称
示例:find /usr/tmp -name ‘a*’ 查找/usr/tmp目录下的所有以a开头的目录或文件
文件操作【增,删,改,查】
新建文件【增】touch
命令:touch 文件名
示例:在当前目录创建一个名为aa.txt的文件 touch aa.txt
删除文件 【删】 rm
命令:rm -rf 文件名
修改文件【改】 vi或vim
【vi编辑器的3种模式】
基本上vi可以分为三种状态,分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:
1) 命令行模式command mode)
控制屏幕光标的移动,字符、字或行的删除,查找,移动复制某区段及进入Insert mode下,或者到 last line mode。
命令行模式下的常用命令:
【1】控制光标移动:↑,↓,j
【2】删除当前行:dd
【3】查找:/字符
【4】进入编辑模式:i o a
【5】进入底行模式::
2) 编辑模式(Insert mode)
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。
编辑模式下常用命令:
【1】ESC 退出编辑模式到命令行模式;
3) 底行模式(last line mode)
将文件保存或退出vi,也可以设置编辑环境,如寻找字符串、列出行号……等。
底行模式下常用命令:
【1】退出编辑: :q
【2】强制退出: :q!
【3】保存并退出: :wq
[
](https://blog.csdn.net/qq_23329167/article/details/83856430)
打开文件
命令:vi 文件名
示例:打开当前目录下的aa.txt文件 vi aa.txt 或者 vim aa.txt
注意:使用vi编辑器打开文件后,并不能编辑,因为此时处于命令模式,点击键盘i/a/o进入编辑模式。
编辑文件
使用vi编辑器打开文件后点击按键:i ,a或者o即可进入编辑模式。
i:在光标所在字符前开始插入
a:在光标所在字符后开始插入
o:在光标所在行的下面另起一新行插入
保存或者取消编辑
保存文件:
第一步:ESC 进入命令行模式
第二步:: 进入底行模式
第三步:wq 保存并退出编辑
取消编辑:
第一步:ESC 进入命令行模式
第二步:: 进入底行模式
第三步:q! 撤销本次修改并退出编辑
[
](https://blog.csdn.net/qq_23329167/article/details/83856430)
文件的查看【查】
文件的查看命令:cat/more/less/tail
cat:看最后一屏
示例:使用cat查看/etc/sudo.conf文件,只能显示最后一屏内容
cat sudo.conf
more:百分比显示
示例:使用more查看/etc/sudo.conf文件,可以显示百分比,回车可以向下一行,空格可以向下一页,q可以退出查看
more sudo.conf
less:翻页查看
示例:使用less查看/etc/sudo.conf文件,可以使用键盘上的PgUp和PgDn向上 和向下翻页,q结束查看
less sudo.conf
{}和${}的区别?
编译工程
- #{} 是 占位符 :动态解析 -> 预编译 -> 执行
- ${} 是 拼接符 :动态解析 -> 编译 -> 执行
是否自动加引号
- #{} 对应的变量会自动加上单引号
- ${} 对应的变量不会加上单引号
安全性
- #{} 能防止sql 注入
- ${} 不能防止sql 注入
Mybatis默认值不同
- #{} 默认值 arg0、arg1、arg2 或 0、 1
- ${} 默认值param1、param2、param3
mysql表示怎样的连接方式?
mysql的数据是怎么传递给前段的?
git你是怎么上传代码的?
你使用git是怎样和你团队合作的?
数组是怎样获取数据的?
数组是怎么创建的?
数据和集合有什么区别?
数据库优化知道吗?讲一下思路
1.应尽量避免在 where 子句中对字段进行 null 值判断
2.避免在where子句中使用!=或<>操作符
3.避免在where子句中使用or来连接条件
4.避免在where中对字段进行表达式操作
5.索引不宜太多,一般5个以内
6.尽量使用数值替代字符串类型
7.尽可能的使用 varchar 代替 char
8.查询SQL尽量不要使用select *,而是具体字段
9.避免频繁创建和删除临时表,以减少系统表资源的消耗。
10.查询尽量避免返回大量数据
11.对查询进行优化,应尽量避免全表扫描,应考虑在 where 及 order by 的列上建立索引
你的项目有有效的生产吗?