- 类的加载过程。
虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制。
- 声明关键字(类的修饰符,作用域,可访问权限)。
对于类中成员(成员变量,成员方法)的访问,可以使用的访问权限修饰符有4种:
1.public:公共访问权限
任意类均访问,实际就是没有限制访问权限
2.protected:受保护的访问权限
a. 在定义成员变量的类体中可以访问到
b. 同包中的其他类类体中
c. 不同包的中,在有一部分类中,无法访问到具有protected权限的成员,子类可以访问到。
3.default(默认权限,隐式定义)
a. 定义成员变量的类体中
b. 同包中的其他类可见
c. 非同包的其他类不可见
4.private(最小的访问权)
仅对同类中的其他成员可见
a. 在定义该成员的类体中可以访问
b. 同包中的其他类访问不到
c. 非同包的其他类中也访问不到
- ArrayList LinkedList。
- ArrayList 基于动态数组实现的非线程安全的集合;LinkedList 基于双向链表实现的非线程安全的集合。
- 扩容问题:ArrayList 使用数组实现,无参构造函数默认初始化长度为 10,数组扩容是会将原数组中的元素重新拷贝到新数组中,长度为原来的 1.5 倍(扩容代价高);LinkedList 不存在扩容问题,新增元素放到集合尾部,修改相应的指针节点即可。
- LinkedList 比 ArrayList 更占内存,因为 LinkedList 为每一个节点存储了两个引用节点,一个指向前一个元素,一个指向下一个元素。
- 对于随机 index 访问的 get 和 set 方法,一般 ArrayList 的速度要优于 LinkedList。因为 ArrayList 直接通过数组下标直接找到元素;LinkedList 要移动指针遍历每个元素直到找到为止。
- 新增和删除元素,一般 LinkedList 的速度要优于 ArrayList。因为 ArrayList 在新增和删除元素时,可能扩容和复制数组;LinkedList 实例化对象需要时间外,只需要修改节点指针即可。
- LinkedList 集合不支持高效的随机访问(RandomAccess)
- ArrayList 的空间浪费主要体现在在list列表的结尾预留一定的容量空间;LinkedList 的空间花费则体现在它的每一个元素都需要消耗存储指针节点对象的空间。
- 接口和抽象类有什么区别?
- 抽象类可以有构造方法;接口中不能有构造方法。
- 抽象类中可以有普通成员变量;接口中没有普通成员变量。
- 抽象类中可以包含非抽象普通方法;JDK1.8 以前接口中的所有方法默认都是抽象的,JDK1.8 开始方法可以有 default 实现和 static 方法。
- 抽象类中的抽象方法的访问权限可以是 public、protected 和 default;接口中的抽象方法只能是 public 类型的,并且默认即为 public abstract 类型。
- 抽象类中可以包含静态方法;JDK1.8 前接口中不能包含静态方法,JDK1.8 及以后可以包含已实现的静态方法。
- final
- final 语义是不可改变的。
- 被 final 修饰的类,不能够被继承
- 被 final 修饰的成员变量必须要初始化,赋初值后不能再重新赋值(可以调用对象方法修改属性值)。对基本类型来说是其值不可变;对引用变量来说其引用不可变,即不能再指向其他的对象
- 被 final 修饰的方法不能重写
- 接口和接口用哪个关键字。
继承:如果多个类的某个部分的功能相同,那么可以抽象出一个类出来,把他们相同的部分都放到父类中,让他们都继承这个类。
实现:如果多个类处理的目标都是一样的,但是处理的方法不同,那么就可以定义一个接口,让他们实现这个接口,各自通过自己的处理方法来处理那个目标。
也可以理解为继承是通过部分相同的功能,产生不同的结果。而实现则是通过不同的方法来实现同一个结果。
继承和实现的区别:
1、数量不同:java只支持接口的多继承,不支持“继承”的多继承,继承在java中具有单根性,子类只能继承一个父类。总结就是:单继承,多实现。
2、修饰不同:继承:extends;实现:mplements
3、属性不同:在接口中只能定义全局变量和无实现的方法。而在继承中可以定义属性方法,变量,常量等。
4、调用不同:当接口被类实现时,在类中一定要实现接口中的抽象方法;而继承想调用哪个方法就调用哪个方法。
GET - 从指定的资源请求数据。
POST - 向指定的资源提交要被处理的数据
GET方法
请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:
/test/demo_form.asp?name1=value1&name2=value2
请求可被缓存
请求保留在浏览器历史记录中
请求可被收藏为书签
请求不应在处理敏感数据时使用
请求有长度限制
请求只应当用于取回数据
POST方法
请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
比较 GET 与 POST
方法 | GET | POST |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符) | 无限制。 |
对数据类型的限制 | 只允许 ASCII 字符 | 没有限制。也允许二进制数据。 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
可见性 | 数据在 URL 中对所有人都是可见的。 | 数据不会显示在 URL 中。 |
- java设计模式 工厂模式和简单工厂模式。
- 工厂模式:Spring 使用工厂模式,通过 BeanFactory 来创建对象
- 单例模式:Bean 默认就是单例模式
- 策略模式:Resource 的实现类,针对不同的资源文件,实现了不同方式的资源获取策略
- 代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码提升
- 模板方法模式:父类生成代码骨架,具体实现延迟到子类,如 JdbcTemplate、RestTemplate
- 适配器模式:Spring AOP 中的 Advice 使用到了适配器模式,Spring MVC 中用到了适配器模式适配 Controller
- 观察者模式:Spring 事件驱动模型就是观察者模式
JAVA设计模式总结之23种设计模式 - pony1223 - 博客园 (cnblogs.com)
- java8与java7版本之间的区别。
1、lambda表达式,java8版本引入的一个新特性。lambda表达式容许将功能看成方法参数或代码看成数据。lambda标识还能够更简洁的方式表示只有一个方法的接口(函数式接口)的实例。
2、方法引用,为已命名的方法提供了易于阅读的lambda表达式
3、默认方法,支持将新功能添加到类库中的接口,并确保与基于这些接口的旧版本的代码的二进制兼容性。
4、重复注解,支持在同一声明或类型上屡次应用同一注解类型。
5、类型注解,支持在任何使用类型的地方应用注解,而不单单限于声明。此特性与可插入型系统一块儿使用时,可加强对代码的类型检查jav
- 怎么接受可变参数。
在Java5 中提供了变长参数(varargs),也就是在方法定义中可以使用个数不确定的参数,对于同一方法可以使用不同个数的参数调用,例如print("hello");print("hello","lisi");print("hello","张三", "alexia");下面介绍如何定义可变长参数 以及如何使用可变长参数。
1. 可变长参数的定义
使用...表示可变长参数,例如
print(String... args){
...
}
在具有可变长参数的方法中可以把参数当成数组使用,例如可以循环输出所有的参数值。
print(String... args){
for(String temp:args)
System.out.println(temp);
}
- char和varchar。
- 在建立数据库表结构的时候,为了给一个String类型的数据定义一个数据库的数据库类型,一般参考的都是char或者varchar,这两种选择有时候让人很纠结,今天想总结一下它们两者的区别,明确一下两者的区别。
- 首先明确的是,char的长度是不可变的,而varchar的长度是可变的,也就是说,定义一个char[10]和varchar[10],如果存进去的是‘csdn’,那么char所占的长度依然为10,除了字符‘csdn’外,后面跟六个空格,而varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的。
- 尽管如此,char的存取数度还是要比varchar要快得多,因为其长度固定,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率,而varchar是以空间效率为首位的。
- 再者,char的存储方式是,对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节;而varchar的存储方式是,对每个英文字符占用2个字节,汉字也占用2个字节。
- 两者的存储数据都非unicode的字符数据。
- Java得反射。
Java 反射,就是在运行状态中
获取任意类的名称、package 信息、所有属性、方法、注解、类型、类加载器、modifiers(public、static)、父类、现实接口等
获取任意对象的属性,并且能改变对象的属性
调用任意对象的方法
判断任意一个对象所属的类
实例化任意一个类的对象
Java 的动态就体现在反射。通过反射我们可以实现动态装配,降低代码的耦合度;动态代理等。反射的过度使用会严重消耗系统资源。
JDK 中 java.lang.Class 类,就是为了实现反射提供的核心类之一。
一个 jvm 中一种 Class 只会被加载一次。
- Spring 如何自定义注解?
/**
* 自定义注解,继承自 @Component
*
* @author ConstXiong
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Component
public @interface CustomComponent {
String value() default "";
}
/**
* 自定义 ComponentScan
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@ComponentScan
public @interface CustomComponentScan {
/**
* 别名
*/
@AliasFor(annotation=ComponentScan.class,value="basePackages")
String[] v() default {};
}
/**
* 测试 Spring 自定义注解
*
* @author ConstXiong
*/
@CustomComponentScan(v="constxiong")
public class Test {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class);
System.out.println(context.getBean("u", User.class));
}
}
- 管理项目代码:git 常用命令。
- git branch 查看本地所有分支
git status 查看当前状态
git commit 提交
git branch -a 查看所有的分支
git branch -r 查看远程所有分支
git commit -am "init" 提交并且加注释
git remote add origin git@192.168.1.119:ndshow
git push origin master 将文件给推到服务器上
git remote show origin 显示远程库origin里的资源
git push origin master:develop
git push origin master:hb-dev 将本地库与服务器上的库进行关联
git checkout --track origin/dev 切换到远程dev分支
git branch -D master develop 删除本地库develop
git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支
git remote show 查看远程库
git add .
git rm 文件名(包括路径) 从git中删除指定文件
git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来
git config --list 看所有用户
git ls-files 看已经被提交的
git rm [file name] 删除一个文件
git commit -a 提交当前repos的所有的改变
git add [file name] 添加一个文件到git index
git commit -v 当你用-v参数的时候可以看commit的差异
git commit -m "This is the message describing the commit" 添加commit信息
git commit -a -a是代表add,把所有的change加到git index里然后再commit
git commit -a -v 一般提交命令
git log 看你commit的日志
git diff 查看尚未暂存的更新
git rm a.a 移除文件(从暂存区和工作区中删除)
git rm --cached a.a 移除文件(只从暂存区中删除)
git commit -m "remove" 移除文件(从Git中删除)
git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)
git diff --cached 或 $ git diff --staged 查看尚未提交的更新
git stash push 将文件给push到一个临时空间中
git stash pop 将文件从临时空间pop下来
---------------------------------------------------------
git remote add origin git@github.com:username/Hello-World.git
git push origin master 将本地项目给提交到服务器中
-----------------------------------------------------------
git pull 本地与服务器端同步
-----------------------------------------------------------------
git push (远程仓库名) (分支名) 将本地分支推送到服务器上去。
git push origin serverfix:awesomebranch
------------------------------------------------------------------
git fetch 相当于是从远程获取最新版本到本地,不会自动merge
git commit -a -m "log_message" (-a是提交所有改动,-m是加入log信息) 本地修改同步至服务器端 :
git branch branch_0.1 master 从主分支master创建branch_0.1分支
- Linux 基本命令。
常用指令
ls 显示文件或目录
-l 列出文件详细信息l(list)
-a 列出当前目录下所有文件及目录,包括隐藏的a(all)
mkdir 创建目录
-p 创建目录,若无父目录,则创建p(parent)
cd 切换目录
touch 创建空文件
echo 创建带有内容的文件。
cat 查看文件内容
cp 拷贝
mv 移动或重命名
rm 删除文件
-r 递归删除,可删除子目录及文件
-f 强制删除
find 在文件系统中搜索某文件
wc 统计文本中行数、字数、字符数
grep 在文本文件中查找某个字符串
rmdir 删除空目录
tree 树形结构显示目录,需要安装tree包
pwd 显示当前目录
ln 创建链接文件
more、less 分页显示文本文件内容
head、tail 显示文件头、尾内容
ctrl+alt+F1 命令行全屏模式
stat 显示指定文件的详细信息,比ls更详细
who 显示在线登陆用户
whoami 显示当前操作用户
hostname 显示主机名
uname 显示系统信息
top 动态显示当前耗费资源最多进程信息
ps 显示瞬间进程状态 ps -aux
du 查看目录大小 du -h /home带有单位显示目录信息
df 查看磁盘大小 df -h 带有单位显示磁盘信息
ifconfig 查看网络情况
ping 测试网络连通
netstat 显示网络状态信息
man 命令不会用了,找男人 如:man ls
clear 清屏
alias 对命令重命名 如:alias showmeit="ps -aux" ,另外解除使用unaliax showmeit
kill 杀死进程,可以先用ps 或 top命令查看进程的id,然后再用kill命令杀死进程。
gzip:
bzip2:
tar: 打包压缩
-c 归档文件
-x 压缩文件
-z gzip压缩文件
-j bzip2压缩文件
-v 显示压缩或解压缩过程 v(view)
-f 使用档名
例:
tar -cvf /home/abc.tar /home/abc 只打包,不压缩
tar -zcvf /home/abc.tar.gz /home/abc 打包,并用gzip压缩
tar -jcvf /home/abc.tar.bz2 /home/abc 打包,并用bzip2压缩
当然,如果想解压缩,就直接替换上面的命令 tar -cvf / tar -zcvf / tar -jcvf 中的“c” 换成“x” 就可以了。
shutdown
-r 关机重启
-h 关机不重启
now 立刻关机
halt 关机
reboot 重启
将一个命令的标准输出作为另一个命令的标准输入。也就是把几个命令组合起来使用,后一个命令除以前一个命令的结果。
例:grep -r "close" /home/* | more 在home目录下所有文件中查找,包括close的文件,并分页输出。
dpkg (Debian Package)管理工具,软件包名以.deb后缀。这种方法适合系统不能联网的情况下。
比如安装tree命令的安装包,先将tree.deb传到Linux系统中。再使用如下命令安装。
sudo dpkg -i tree_1.5.3-1_i386.deb 安装软件
sudo dpkg -r tree 卸载软件
注:将tree.deb传到Linux系统中,有多种方式。VMwareTool,使用挂载方式;使用winSCP工具等;
APT(Advanced Packaging Tool)高级软件工具。这种方法适合系统能够连接互联网的情况。
依然以tree为例
sudo apt-get install tree 安装tree
sudo apt-get remove tree 卸载tree
sudo apt-get update 更新软件
sudo apt-get upgrade
将.rpm文件转为.deb文件
.rpm为RedHat使用的软件格式。在Ubuntu下不能直接使用,所以需要转换一下。
sudo alien abc.rpm
vim三种模式:命令模式、插入模式、编辑模式。使用ESC或i或:来切换模式。
命令模式下:
:q 退出
:q! 强制退出
:wq 保存并退出
:set number 显示行号
:set nonumber 隐藏行号
/apache 在文档中查找apache 按n跳到下一个,shift+n上一个
yyp 复制光标所在行,并粘贴
h(左移一个字符←)、j(下一行↓)、k(上一行↑)、l(右移一个字符→)
/etc/passwd 存储用户账号
/etc/group 存储组账号
/etc/shadow 存储用户账号的密码
/etc/gshadow 存储用户组账号的密码
useradd 用户名
userdel 用户名
adduser 用户名
groupadd 组名
groupdel 组名
passwd root 给root设置密码
su root
su - root
/etc/profile 系统环境变量
bash_profile 用户环境变量
.bashrc 用户环境变量
su user 切换用户,加载配置文件.bashrc
su - user 切换用户,加载配置文件/etc/profile ,加载bash_profile
更改文件的用户及用户组
sudo chown [-R] owner[:group] {File|Directory}
例如:还以jdk-7u21-linux-i586.tar.gz为例。属于用户hadoop,组hadoop
要想切换此文件所属的用户及组。可以使用命令。
sudo chown root:root jdk-7u21-linux-i586.tar.gz
三种基本权限
R 读 数值表示为4
W 写 数值表示为2
X 可执行 数值表示为1
如图所示,jdk-7u21-linux-i586.tar.gz文件的权限为-rw-rw-r--
-rw-rw-r--一共十个字符,分成四段。
第一个字符“-”表示普通文件;这个位置还可能会出现“l”链接;“d”表示目录
第二三四个字符“rw-”表示当前所属用户的权限。 所以用数值表示为4+2=6
第五六七个字符“rw-”表示当前所属组的权限。 所以用数值表示为4+2=6
第八九十个字符“r--”表示其他用户权限。 所以用数值表示为2
所以操作此文件的权限用数值表示为662
更改权限
chmod命令使用数字修改文件权限
Linux 系统中,文件的基本权限由 9 个字符组成,以 rwxrw-r-x 为例,我们可以使用数字来代表各个权限,各个权限与数字的对应关系如下:
r --> 4
w --> 2
x --> 1
由于这 9 个字符分属 3 类用户,因此每种用户身份包含 3 个权限(r、w、x),通过将 3 个权限对应的数字累加,最终得到的值即可作为每种用户所具有的权限。
拿 rwxrw-r-x 来说,所有者、所属组和其他人分别对应的权限值为:
所有者 = rwx = 4+2+1 = 7
所属组 = rw- = 4+2 = 6
其他人 = r-x = 4+1 = 5
所以,此权限对应的权限值就是 765。
使用数字修改文件权限的 chmod 命令基本格式为:
[root@localhost ~]# chmod [-R] 权限值 文件名
-R(注意是大写)选项表示连同子目录中的所有文件,也都修改设定的权限。
例如,使用如下命令,即可完成对 .bashrc 目录文件的权限修改:
[root@localhost ~]# ls -al .bashrc
-rw-r--r--. 1 root root 176 Sep 22 2004 .bashrc
[root@localhost ~]# chmod 777 .bashrc
[root@localhost ~]# ls -al .bashrc
-rwxrwxrwx. 1 root root 176 Sep 22 2004 .bashrc
再举个例子,通常我们以 Vim 编辑 Shell 文件批处理文件后,文件权限通常是 rw-rw-r--(644),那么,如果要将该文件变成可执行文件,并且不让其他人修改此文件,则只需将此文件的权限该为 rwxr-xr-x(755)即可。
chmod命令使用字母修改文件权限
既然文件的基本权限就是 3 种用户身份(所有者、所属组和其他人)搭配 3 种权限(rwx),chmod 命令中用 u、g、o 分别代表 3 种身份,还用 a 表示全部的身份(all 的缩写)。另外,chmod 命令仍使用 r、w、x 分别表示读、写、执行权限。
使用字母修改文件权限的 chmod 命令,其基本格式如图 1 所示。
图 1 chmod 命令基本格式
例如,如果我们要设定 .bashrc 文件的权限为 rwxr-xr-x,则可执行如下命令:
[root@localhost ~]# chmod u=rwx,go=rx .bashrc
[root@localhost ~]# ls -al .bashrc
-rwxr-xr-x. 1 root root 176 Sep 22 2004 .bashrc
再举个例子,如果想要增加 .bashrc 文件的每种用户都可做写操作的权限,可以使用如下命令:
[root@localhost ~]# ls -al .bashrc
-rwxr-xr-x. 1 root root 176 Sep 22 2004 .bashrc
[root@localhost ~]# chmod a+w .bashrc
[root@localhost ~]# ls -al .bashrc
-rwxrwxrwx. 1 root root 176 Sep 22 2004 .bashrc
- MQ 是什么?为什么使用?
MQ(Message Queue)消息队列,是 "先进先出" 的一种数据结构。
MQ 的作用:一般用来解决应用解耦,异步处理,流量削峰等问题,实现高性能,高可用,可伸缩和最终一致性架构。
应用解耦:
当 A 系统生产关键数据,发送数据给多个其他系统消费,此时 A 系统和其他系统产生了严重的耦合,如果将 A 系统产生的数据放到 MQ 当中,其他系统去 MQ 获取消费数据,此时各系统独立运行只与 MQ 交互,添加新系统消费 A 系统的数据也不需要去修改 A 系统的代码,达到了解耦的效果。
异步处理:
互联网类企业对用户的直接操作,一般要求每个请求在 200ms 以内完成。对于一个系统调用多个系统,不使用 MQ 的情况下,它执行完返回的耗时是调用完所有系统所需时间的总和;使用 MQ 进行优化后,执行的耗时则是执行主系统的耗时加上发送数据到消息队列的耗时,大幅度提升系统性能和用户体验。
流量削峰:
MySQL 每秒最高并发请求在 2000 左右,用户访问量高峰期的时候涌入的大量请求,会将 MySQL 打死,然后系统就挂掉,但过了高峰期,请求量可能远低于 2000,这种情况去增加服务器就不值得,如果使用 MQ 的情况,将用户的请求全部放到 MQ 中,让系统去消费用户的请求,不要超过系统所能承受的最大请求数量,保证系统不会再高峰期挂掉,高峰期过后系统还是按照最大请求数量处理完请求。
- 索引及索引的常用命令
1、索引的底层实现原理和优化
B+树,经过优化的B+树,主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此InnoDB建议为大部分表使用默认自增的主键作为主索引。
3、什么情况下设置了索引但无法使用
以“%”开头的LIKE语句,模糊匹配
OR语句前后没有同时使用索引
数据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型)
4、简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。
普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。也就是说, 唯一索引可以保证数据记录的唯一性。
主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字PRIMARY KEY 来创建。
索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引,这就是联合索引。
索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件。
5、 对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题:
a)、索引的目的是什么?
快速访问数据表中的特定信息,提高检索速度
创建唯一性索引,保证数据库表中每一行数据的唯一性。
加速表和表之间的连接
使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间
b)、索引对数据库系统的负面影响是什么?
负面影响:
创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。
c)、为数据表建立索引的原则有哪些?
在最频繁使用的、用以缩小查询范围的字段上建立索引。
在频繁使用的、需要排序的字段上建立索引
d)、 什么情况下不宜建立索引?
对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等
6、你怎么看到为表格定义的所有索引?
索引是通过以下方式为表格定义的:
SHOW INDEX FROM <tablename>;
7、实现索引的方式? 索引的原理? 索引的代价? 索引的类型?
实现索引的方式有两种:针对一张表的某些字段创建具体的索引,如对oracle: create index 索引名称 on 表名(字段名);在创建表时为字段建立主键约束或者唯一约束,系统将自动为其建立索引。
索引的原理:根据建立索引的字段建立索引表,存放字段值以及对应记录的物理地址,从而在搜索的时候根据字段值搜索索引表的到物理地址直接访问记录。
引入索引虽然提高了查询速度,但本身占用一定的系统存储容量和系统处理时间,需要根据实际情况进行具体的分析.
索引的类型有:B树索引,位图索引,函数索引等。
8、聚簇索引和普通索引在不同的SQL语句中哪个效率更高?(聚簇索引和普通索引的区别)
概念类:
聚合函数? Session的定义和用法? Oracle的存储过程 ? 什么是构造函数?
9、怎样创建一个一个索引,索引使用的原则,有什么优点和缺点
创建标准索引: CREATE INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名;
创建唯一索引: CREATE unique INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名;
创建组合索引: CREATE INDEX 索引名 ON 表名 (列名1,列名2) TABLESPACE 表空间名;
创建反向键索引: CREATE INDEX 索引名 ON 表名 (列名) reverse TABLESPACE 表空间名;
索引使用原则:
索引字段建议建立NOT NULL约束
经常与其他表进行连接的表,在连接字段上应该建立索引;
经常出现在Where子句中的字段且过滤性很强的,特别是大表的字段,应该建立索引;
可选择性高的关键字 ,应该建立索引;
可选择性低的关键字,但数据的值分布差异很大时,选择性数据比较少时仍然可以利用索引提高效率
复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:
A、正确选择复合索引中的第一个字段,一般是选择性较好的且在where子句中常用的字段上;
B、复合索引的几个字段经常同时以AND方式出现在Where子句中可以建立复合索引;否则单字段索引;
C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
频繁DML的表,不要建立太多的索引;
不要将那些频繁修改的列作为索引列;
索引的优缺点:
有点:
1. 创建唯一性索引,保证数据库表中每一行数据的唯一性
2. 大大加快数据的检索速度,这也是创建索引的最主要的原因
3. 加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4. 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
缺点:
1. 索引创建在表上,不能创建在视图上
2. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
3. 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
4. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
10、索引的实现方式
都是 B+树索引, Innodb 是索引组织表, myisam 是堆表, 索引组织表和堆表的区别要熟悉
11、Oracle索引分为哪几类,说出唯一索引和位图索引的概念。
Oracle索引有B树索引,位图索引,函数索引,簇索引等。
唯一索引也是B树索引的一种,它要求被索引的字段值不可以重复。在创建的时候使用B树算法创建。
位图索引并不是采用象唯一索引那样存储(索引字段值,记录ROWID)来创建索引段的,而是为每一个唯一的字段值创建一个位图,位图中使用位元来对应一个记录的ROWID。位元到ROWID是通过映射的到的。
12、如何写 sql 能够有效的使用到复合索引。
由于复合索引的组合索引,类似多个木板拼接在一起,如果中间断了就无法用了,所以要能用到复合索引,首先开头(第一列)要用上,比如index(a,b) 这种,我们可以select table tname where a=XX 用到第一列索引 如果想用第二列 可以 and b=XX 或者and b like‘TTT%’
13、当数据表中A、B字段做了组合索引,那么单独使用A或单独使用B会有索引效果吗?(使用like查询如何有索引效果)
看A、B两字段做组合索引的时候,谁在前面,谁在后面,如果A在前,那么单独使用A会有索引效果,单独使用B则没有,反之亦然。同理,使用like模糊查询时,如果只是使用前面%,那么有索引效果,如果使用双%号匹配,那么则无索引效果
14、数据库索引的实现(B+树介绍、和B树、R树区别)
http://blog.youkuaiyun.com/kennyrose/article/details/7532032
http://www.xuebuyuan.com/2216918.html
15、索引的使用注意事项
https://www.cnblogs.com/zlingh/p/3883716.html
16、MYsql 的索引原理,索引的类型有哪些,如何创建合理的索引,索引如何优化。
索引是通过复杂的算法,提高数据查询性能的手段。从磁盘io到内存io的转变
普通索引,主键,唯一,单列/多列索引建索引的几大原则
1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录
4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
17、聚集索引和非聚集索引的区别。
“聚簇”就是索引和记录紧密在一起。
非聚簇索引 索引文件和数据文件分开存放,索引文件的叶子页只保存了主键值,要定位记录还要去查找相应的数据块。
18、数据库中 BTREE 和 B+tree 区别。
B+是btree的变种,本质都是btree,btree+与B-Tree相比,B+Tree有以下不同点:
每个节点的指针上限为2d而不是2d+1。
内节点不存储data,只存储key;叶子节点不存储指针。
Btree 怎么分裂的,什么时候分裂,为什么是平衡的。
Key 超过1024才分裂B树为甚会分裂? 因为随着数据的增多,一个结点的key满了,为了保持B树的特性,就会产生分裂,就向红黑树和AVL树为了保持树的性质需要进行旋转一样!
19、索引对性能的影响
1.添加索引后查询速度会变快
mysql中索引是存储引擎层面用于快速查询找到记录的一种数据结构,索引对性能的影响非常重要,特别是表中数据量很大的时候,正确的索引会极大的提高查询效率。简单理解索引,就相当于一本砖头厚书的目录部分,通过目录可以快速查找到想要找的内容具体所在的页码。在经常需要搜索的列上创建索引,可以加快搜索的速度。如果表中数据少的话,没必要用索引,如果表中数据很多的话,还是有索引比较好。
通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
- abstract,final 能组合使用吗?static final能组合使用吗?
abstract、private、static、final混合使用情况
qq_42246889 2019-08-09 20:14:53 153 收藏 1
版权
1.abstract与private一起使用,相互矛盾
abstract修饰的方法是要给子类重写,private修饰的方法只能本类访问。
2.abstract与static一起使用,无意义
abstact修饰的方法是抽象的,没有实体。而static修饰的方法,类是可以直接调用,调用抽象方法是没有意义的。
3.abstract与final一起使用,相互矛盾
final修饰方法不让子类重写,而abstract修饰的方法就是为了让子类重写。
4、static不能修饰普通类,可以修饰内部类
final(修饰类、属性、方法)
final修饰类位于访问限定符和class之间,且不允许被继承
final修饰方法位于方法访问限定符和方法的返回值之间,且不允许被重写,但是允许重载
final修饰属性位于属性访问限定符和属性的类型之间
static(不能修饰普通类,可以修饰内部类)
静态的,可以修饰属性 方法 代码
静态属性的值只有一个,并且被所有的本类的对象共享
abstract(可以有抽象方法,也可以有普通方法)
抽象的,修饰方法和类,不允许修饰属性
抽象类存在的意义是被继承,通常作为父类出现
- try catch finally 对返回值的影响
无论发生异常与否,finally语句块一定在return之前执行。
以下结论基于如下前提:try的return语句在发生异常语句之后、方法有返回值。
① 当finally语句块中存在return语句时,此时无论是否发生异常,都以该return语句为准,其他的return语句将不起作用。
② 当发生异常时,try存在return语句,catch存在return语句,以catch中的return语句为准,此时在finally语句块中的修改将不起作用。
③ 当发生异常时,try存在return语句,catch不存在return语句,方法在最后存在return语句,以该return语句为准,此时在catch和finally的修改会起作用。
④ 不发生异常时,try存在return语句,不管是catch存在return语句还是方法最后存在return语句,都以try中的return语句为准,此时在catch、finally中的修改将不起作用。