(参考文章来源均在文中标出,侵删歉)
(先写一部分,Java篇与SQL篇后面补充)
1. Web篇
-
在浏览器输入地址
http://www.baidu.com
并回车,整个过程发生了什么?(1) 首先,需要将
www.baidu.com
通过 DNS 解析获得百度的 IP 地址。具体步骤如下:- 浏览器首先查询浏览器的缓存,因为浏览器会按照一定的频率缓存 DNS 记录。
- 若浏览器无缓存,那么查询操作系统的 HOST 文件,查询是否有 DNS 记录。
- 若还没有命中域名,就请求本地域名服务器(LDNS),这台服务器一般在城市的某个角落,距离客户端不会很远。该服务器一般都会缓存域名查询结果,因此大部分域名解析都能在这里解析完成。
- 若LDNS还没有命中,就LDNS请求根服务器(Root Server)请求帮助,根服务器返回 LDNS 一个所查询域的主域名服务器(gTLD DNS,国际顶尖域名服务器,如 .com,.cn,.org等),这里访问的是
www.baidu.com
百度,即返回 .com 的主域名服务器。 - LDNS 继续访问 gTLD Server,查找这个域名对应的 Name Server 地址,即网站注册的域名服务器 BAIDU-DNS。
- LDNS 继续访问 BAIDU-DNS Server,根据映射关系表找到目标 IP 地址,返回给 LDNS。
- LDNS 拿到 IP 地址后,对这个域名和 IP 地址进行缓存,并将 IP 地址返回给请求客户端,即我们的浏览器,至此,DNS 域名解析过程结束,拿到域名对应的 IP 地址。
(2) 拿到百度的服务器地址后,浏览器开始向该 IP 地址发起 HTTP/HTTPS 会话请求,而 HTTP/HTTPS 协议皆基于 TCP 协议,因此,在进行 HTTP 请求之前,浏览器还需要与百度服务器进行三次握手,建立 TCP 连接。因此,步骤如下:
- 与服务器进行三次握手,建立 TCP 连接。
- 发出 HTTP/HTTPS 请求,由于我们访问的是
www.baidu.com
,因此请求的是百度首页。 - 服务器响应数据发送给客户端浏览器,即百度首页数据。
- 通过四次挥手,TCP 连接释放。
- 浏览器对首页数据进行解析渲染,将最终的页面效果展示给用户。[参考资料]
-
你常见的content-type有哪些?分别代表什么含义?
参考资料
Content-Type | 描述 |
---|---|
application/x-www-form-urlencoded | 浏览器的原生form表单;提交的数据按照 key1=val1&key2=val2 的方式进行编码,key和val都进行了URL转码 |
multipart/form-data | 常见的 POST 数据提交的方式 |
application/json | 消息主体是序列化后的 JSON 字符串 |
text/xml | 是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范 |
-
为什么建立HTTP连接需要三次握手,而断开却需要四次握手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。[参考资料]
连接和断开的比较详细过程可以看这篇文章。 -
get和post请求的区别有哪些?
看这篇文章:GET和POST两种基本请求方法的区别
2. Java篇
-
什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。 -
“static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
static所修饰的方法/变量可以直接通过类名访问,而不是先创建对象再对里面的静态方法/变量进行访问,当然这样也可以。
static所修饰的变量/代码块/方法在该类被加载时加载/运行(这里特指静态代码块,并且只执行一次)。同时,被static修饰的变量在堆只有一个副本,所有对象对该变量的操作都是在操作同一个变量,如果是实例变量的话,每个对象都有各自的副本,每个对象操作的都是各自的副本。
private只能够被自身类访问,子类不能访问private修饰的成员,所有不能override一个private方法
static方法是与类绑定的与任何实例都无关,随着类的加载而加载, static是编译时静态绑定的,override是运行时动态绑定的。形式上static可以override,但是实际上并不能被override。 -
是否可以在static环境中访问非static变量?
不能,因为static变量是属于类的,在类加载的时候就被初始化了,这时候非静态变量并没有加载,故静态变量不能访问。 -
Java支持的数据类型有哪些?什么是自动拆装箱?Java语言支持的8种基本数据类型是?
-
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
-
Java支持多继承么?
-
接口和抽象类的区别是什么?
-
什么是值传递和引用传递?
-
创建线程有几种不同的方式?你喜欢哪一种?为什么?
-
同步方法和同步代码块的区别是什么?
-
什么是死锁(deadlock)?
在一个进程集合中,若每个进程都在等待某些事件(指:释放资源)的发生,而这些事件又必须由这个进程集合中的某些进程来产生,就称该进程集合处于死锁状态。
出现死锁的系统必须同时满足下列四个必要条件:
(1)互斥:必须存在需要互斥使用的资源;
(2)占有等待:一定有占有资源而又等待其他资源的进程;
(3)非剥夺:系统中进程占有的资源未主动释放时不可以剥夺;
(4)循环等待:进程集合{P0, P1, ……, Pn},Pi等待Pi+1,Pn等待P0。
3. 数据库篇
表结构
Student(S#,Sname,Sage,Ssex) 学生表
Course(C#,Cname,T#) 课程表
SC(S#,C#,score) 成绩表
Teacher(T#,Tname) 教师表
3.1 Sql题
-
查询“001”课程比“002”课程成绩高的所有学生的学号;
-
查询平均成绩大于60分的同学的学号和平均成绩;
-
查询所有同学的学号、姓名、选课数、总成绩;
-
查询姓“李”的老师的个数;
-
查询没学过“叶平”老师课的同学的学号、姓名;
-
查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
-
查询学过“叶平”老师所教的所有课的同学的学号、姓名;
-
查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
-
查询所有课程成绩小于60分的同学的学号、姓名;
-
查询没有学全所有课的同学的学号、姓名;
3.2 Sql理论
-
什么是数据库事务,事务四大特性是什么?
数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。
数据库事务拥有以下四个特性,习惯上被称之为ACID特性:
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态,一致状态的含义是数据库中的数据应满足完整性约束。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。 -
什么是脏读、幻读、不可重复读?
脏读:一个事务正在访问数据,而其他事务正在更新该数据,但尚未 提交,此时会发生脏读问题,即第一个事务所读取的数据是“脏”的
幻读:当一个事务对某行执行了插入或删除操作时,由于该行在另外 的事务读取的范围内,从而导致两次读取多出了一行或者消失了一行
不可重复读:在一个事务内多次读同一数据,在该事务还没有结束时, 另外的事务也访问该数据并对其做修改,从而导致第一个事务两次读 取的数据不一样 -
mysql两个存储引擎innodb和myisam区别是什么?
MyISAM MySQL 5.0 之前的默认数据库引擎,最为常用。拥有较高的插入,查询速度,但不支持事务
InnoDB 事务型数据库的首选引擎,支持ACID事务,支持行级锁定, MySQL 5.5 起成为默认数据库引擎
4. Spring篇
- 说说你常用的Spring注解,并解释它的作用。
注解 | 描述 |
---|---|
@Required | @Required 注解应用于 bean 属性的 setter 方法。 |
@Autowired | @Autowired 注解可以应用到 bean 属性的 setter 方法,非 setter 方法,构造函数和属性。 |
@Qualifier | 通过指定确切的将被连线的 bean,@Autowired 和 @Qualifier 注解可以用来删除混乱。 |
JSR-250 Annotations | Spring 支持 JSR-250 的基础的注解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 注解。 |
-
说说Spring和Spring Boot的区别。
Spring Boot可以建立独立的Spring应用程序;
内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了;
无需再像Spring那样搞一堆繁琐的xml文件的配置;
可以自动配置(核心)Spring。SpringBoot将原有的XML配置改为Java配置,将bean注入改为使用注解注入的方式(@Autowire),并将多个xml、properties配置浓缩在一个appliaction.yml配置文件中。
提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能;
整合常用依赖(开发库,例如spring-webmvc、jackson-json、validation-api和tomcat等),提供的POM可以简化Maven的配置。当我们引入核心依赖时,SpringBoot会自引入其他依赖。
参考 -
说说什么是IOC和AOP。
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
5. Dubbo篇
-
dubbo是什么?
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。 -
如何声明并暴露一个dubbo服务?
(1)服务端
定义一个Service Interface:(HelloService.java)
package com.alibaba.hello.api;
public interface HelloService
{
String sayHello(String name);
}
接口的实现类:(HelloServiceImpl.java)
package com.alibaba.hello.impl;
import com.alibaba.hello.api.HelloService;
public class HelloServiceImpl implements HelloService{
public String sayHello(String name){
return "Hello" + name;
}
}
Spring配置:(provider.xml)
<?xmlversion="1.0"encoding="UTF-8"?>
<beans......>
<!--Applicationname-->
<dubbo:applicationname="hello-world-app"/>
<!--registryaddress,usedforservicetoregisteritself-->
<dubbo:registryaddress="multicast://224.5.6.7:1234"/>
<!--exposethisservicethroughdubboprotocol,throughport20880-->
<dubbo:protocolname="dubbo"port="20880"/>
<!--whichserviceinterfacedoweexpose?-->
<dubbo:serviceinterface="com.alibaba.hello.api.HelloService"ref="helloService"/>
<!--designateimplementation-->
<beanid="helloService"class="com.alibaba.hello.impl.HelloServiceImpl"/>
</beans>
测试代码:(Provider.java)
importorg.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider{
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(newString[]{"provider.xml"});
//启动成功,监听端口为20880System.in.read();//按任意键退出
}
}
(2)客户端
Spring配置文件:(consumer.xml)
<?xmlversion="1.0"encoding="UTF-8"?>
<beans xmlns=......>
<!--consumerapplicationname-->
<dubbo:applicationname="consumer-of-helloworld-app"/>
<!--registryaddress,usedforconsumertodiscoverservices-->
<dubbo:registryaddress="multicast://224.5.6.7:1234"/>
<!--whichservicetoconsume?-->
<dubbo:referenceid="helloService"interface="com.alibaba.hello.api.HelloService"/>
</beans>
客户端测试代码:(Consumer.java)
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.alibaba.hello.api.HelloService;
public class Consumer{
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(newString[]{"consumer.xml"});
HelloService helloService = (HelloService)context.getBean("helloService");
//getserviceinvocationproxyStringhello=helloService.sayHello("world");
//doinvoke!System.out.println(hello);
//cool,howareyou~
}
}
6. Zookeeper篇
- Zookeeper是什么?
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集,提供Java和C的接口。
ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。
7. 编程题
- 请用Java实现一个死锁。
public class DeadLock {
public static String obj1 = "obj1";
public static String obj2 = "obj2";
public static void main(String[] args){
Thread a = new Thread(new Lock1());
Thread b = new Thread(new Lock2());
a.start();
b.start();
}
}
class Lock1 implements Runnable{
@Override
public void run(){
try{
System.out.println("Lock1 running");
while(true){
synchronized(DeadLock.obj1){
System.out.println("Lock1 lock obj1");
Thread.sleep(3000);//获取obj1后先等一会儿,让Lock2有足够的时间锁住obj2
synchronized(DeadLock.obj2){
System.out.println("Lock1 lock obj2");
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
class Lock2 implements Runnable{
@Override
public void run(){
try{
System.out.println("Lock2 running");
while(true){
synchronized(DeadLock.obj2){
System.out.println("Lock2 lock obj2");
Thread.sleep(3000);
synchronized(DeadLock.obj1){
System.out.println("Lock2 lock obj1");
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
8. 发散题
-
JAVA中高访问量高并发的问题怎么解决?
(1)尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与数据库的交互,提高性能。
(2)用jprofiler等工具找出性能瓶颈,减少额外的开销。
(3)优化数据库查询语句,减少直接使用hibernate等工具的直接生成语句(仅耗时较长的查询做优化)。
(4)优化数据库结构,多做索引,提高查询效率。
(5)统计的功能尽量做缓存,或按每天一统计或定时统计相关报表,避免需要时进行统计的功能。
(6)能使用静态页面的地方尽量使用,减少容器的解析(尽量将动态内容生成静态html来显示)。
(7)解决以上问题后,使用服务器集群来解决单台的瓶颈问题。
(8)可以考虑分布式部署
(9)做负载均衡