1.字节和字符的区别?(InputStream、OutputStream Reader, Writer)
当时学Java的时候没搞懂字节和字符的区别,今天看文件输入输出流的时候觉得是时候彻底把这两个概念弄懂。
首先得知道byte的概念和作用:
byte即字节的意思,是java中的基本数据类型,用来申明字节型的变量,一个字节包含8个位,所以,byte
类型的取值范围是-128到127。
通常在读取非文本文件时(如图片,声音,可执行文件)需要用字节数组来保存文件的内容,在下载文件时,
也是用byte数组作临时的缓冲器接收文件内容。所以说byte在文件操作时是必不可少的。不管是对文件写入还是
读取都要用到。
在某些程序中(尤其是和硬件有关的程序)会将某些数据存储到字节类型的变量中,比如00110010,其中每个
位都代表一个参数,然后以位运算的方式对参数进行取值和赋值操作。
机器只知道字节,而字符却是语义上的单位,它是有编码的,一个字符可能编码成1个2个甚至3个4个字节。这
跟字符集编码有关系,英文字母和数字是单字节,但汉字这些自然语言中的字符是多字节的。一个字节只能表示
255个字符,不可能用于全球那么多种自然语言的处理,因此肯定需要多字节的存储方式。
那么在文件的输入输出中,InputStream、OutputStream它们是处理字节流的,就是说假设所有东西都是二进
制的字节;而 Reader, Writer 则是字符流,它涉及到字符集的问题;按照ANSI编码标准,标点符号、数字、大小
写字母都占一个字节,汉字占2个字节。按照UNICODE标准所有字符都占2个字节。
以上就是我对字节与字符的理解。
2.设计模式怎么分类,每一类都有哪些?
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
3.知道哪些服务器?答:Apache,Tomcat。问:区别
Apache与Tomcat都是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可以做为独立的Web服务器运行。Apache是Web服务器而Tomcat是Java应用服务器。
Apache:是C语言实现的,专门用来提供HTTP服务。
特性:简单、速度快、性能稳定、可配置(代理)
1、主要用于解析静态文本,并发性能高,侧重于HTTP服务;
2、支持静态页(HTML),不支持动态请求如:CGI、Servlet/JSP、PHP、ASP等;
3、具有很强的可扩展性,可以通过插件支持PHP,还可以单向Apache连接Tomcat实现连通;
4、Apache是世界使用排名第一的Web服务器。
Tomcat:是apache开发的一个符合JavaEE的Servlet规范的JSP服务器(Servlet容器),是 Apache 的扩展。
特性:免费的Java应用服务器
1、主要用于解析JSP/Servlet,侧重于Servlet引擎;
2、支持静态页,但效率没有Apache高;支持Servlet、JSP请求;
3、Tomcat本身也内置了一个HTTP服务器用于支持静态内容,可以通过Tomcat的配置管理工具实现与Apache整合。
Apache + Tomcat:
两者整合后优点:
如果请是静态网页则由Apache处理,并将结果返回;如果是动态请求,Apache会将解析工作转发给Tomcat处理,Tomcat处理后将结果通过Apache返回。这样可以达到分工合作,实现负载远衡,提高系统的性能。
总结:
打个比方:Apache是一辆卡车,上面可以装一些东西如html等。但是不能装水(JSP),要装水必须要有容器(桶),Tomcat就是一个桶(装像JSP这样的水),而这个桶也可以不放在卡车上。
4.设计模式怎么用到项目中?
享元模式----数据库连接池
桥接模式---java只给出了数据库api接口,而各大数据库厂商去做实现
5.什么硬件条件可以实现多线程,什么情况下多线程才能发挥作用,
6.mysql索引底层是什么,b树和hash应用场景?
关系型数据库中,索引大多采用B/B+树来作为存储结构,而全文搜索引擎的索引则主要采用hash的存储结构,这两种数据结构有什么区别?
hash结构的特点:检索效率非常高,索引的检索可以一次到位,O(1)。B树需要从根节点到枝节点,最后才能到叶节点进行多次I/O操作,所以hash的效率远远高于B树的效率。
那么为什么数据库索引还是用B树结构呢?
1、hash索引仅满足“=”、“IN”和“<=>”查询,不能使用范围查询
因为hash索引比较的是经常hash运算之后的hash值,因此只能进行等值的过滤,不能基于范围的查找,因为经过hash算法处理后的hash值的大小关系,并不能保证与处理前的hash大小关系对应。
2、hash索引无法被用来进行数据的排序操作
由于hash索引中存放的都是经过hash计算之后的值,而hash值的大小关系不一定与hash计算之前的值一样,所以数据库无法利用hash索引中的值进行排序操作。
3、对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。所以那种索引使用的就是btree索引
4、Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。
(因此:键值重复率低的适合用B树索引)
hash相当于把key通过hash函数计算,得到key的hash值,再用这个hash值做指针,查找hash表中是否存在key,如果存在就返回 key所对应的value,选定一个好的hash函数很重要,好的hash函数可以使计算出的hash值分布均匀,降低冲突,只有冲突减小了,才会降低 hash表的查找时间。
b-tree完全基于key的比较,和二叉树相同的道理,相当于建个排序后的数据集,使用二分法查找算法,实际上也非常快,而且受数据量增长影
线程同步有哪几种方式,解释一下Volatile
1. 使用同步关键字synchronized
synchronized主要有两种使用方式
1.1 同步方法
使用synchronized修饰方法
使用模板:
//同步方法
public synchronized void methodName(...){...}
//同步静态方法
public synchronized static void methodName(...){...}
注意:当使用synchronized修饰静态方法时,线程此时获得的锁对象是类的Class对象(堆内存中只有唯一一个Class对象,因为Class对象是在类加载时产生的,而类加载只执行一次),因此会锁住整个类,其他线程无法访问该类的同步静态方法,但是可以访问非同步的方法
1.2 同步代码块
使用synchronized修饰代码块
使用模板:
synchronized(object){...}
1
注意
1. 同步通常会导致线程堵塞,使得程序执行效率低,
因此应该尽量缩小同步范围。
2. 基于第1点,通常没必要同步整个方法,
只需要同步关键代码块(操作了共享变量的区域
2. 使用关键字volatile修饰共享变量实现伪同步
1. volatile为所修饰的共享变量提供了一种免锁机制,
并没有为共享变量上锁。
2. 使用volatile;
相当于告诉JVM某个共享变量随时可能被其他线程修改,
需要线程到内存中去读取这个共享变量的值,
而不是从缓存中读取
3. volatile仅保证可见性;
volatile所修饰的共享变量的值被修改时,会被立即更新到内存中
4. volatile不保证原子性
5. volatile不能修饰final变量
基于第2点,volatile修饰的变量随时可能会被修改,
而final修饰的变量是不会被修改,
因此volatile不能修饰final变量
为什么说实现的是伪同步
主要基于以上的第3,4点原因,volatile保证了可见性,相对于没有用volatile修饰的共享变量,大大提高了线程读取到最新数据的可能性,但是volatile不保证原子性,说明线程读到的最新数据可能并不是真正意义上的最新