JAVA基础知识点总结

JAVA 基础

1、Java中有三大变量

	实例变量:在堆中。
	静态变量:在方法区。
	局部变量:在栈中。

	以上三大变量中:
		局部变量永远都不会存在线程安全问题。
		因为局部变量不共享。(一个线程一个栈。)
		局部变量在栈中。所以局部变量永远都不会共享。
	
	实例变量在堆中,堆只有1个。
	静态变量在方法区中,方法区只有1个。
	堆和方法区都是多线程共享的,所以可能存在线程安全问题。

	局部变量+常量:不会有线程安全问题。
	成员变量:可能会有线程安全问题。
	
	如果使用局部变量的话:建议使用:StringBuilder。因为局部变量不存在线程安全问题。
	选择StringBuilder。StringBuffer效率比较低。

JVM

1、关于JDK中自带的类加载器

什么是类加载器?
		专门负责加载类的命令/工具。
		ClassLoader
		
JDK中自带了3个类加载器
		启动类加载器:rt.jar
		扩展类加载器:ext/*.jar
		应用类加载器:classpath
	
假设有这样一段代码:
		String s = "abc";
		
		代码在开始执行之前,会将所需要类全部加载到JVM当中。
		通过类加载器加载,看到以上代码类加载器会找String.class
		文件,找到就加载,那么是怎么进行加载的呢?

			首先通过“启动类加载器”加载。
				注意:启动类加载器专门加载:C:\Program Files\Java\jdk1.8.0_101\jre\lib\rt.jar
				rt.jar中都是JDK最核心的类库。
			
			如果通过“启动类加载器”加载不到的时候,
			会通过"扩展类加载器"加载。
				注意:扩展类加载器专门加载:C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\*.jar

	
			如果“扩展类加载器”没有加载到,那么
			会通过“应用类加载器”加载。
				注意:应用类加载器专门加载:classpath中的类。
	
java中为了保证类加载的安全,使用了双亲委派机制。
		优先从启动类加载器中加载,这个称为“父”
		“父”无法加载到,再从扩展类加载器中加载,这个称为“母”。双亲委派。
		如果都加载不到,才会考虑从应用类加载器中加载。直到加载到为止。	

集合

Set 接口

1、java中什么时候需要重写equals和hashCode方法,以及为什么重写?

/*因为Object中默认的equals方法,内部还是使用==来比较对象在内存中的地址,所以结果位false*/
/*如果重写了equals方法,那么如果两个对象的属性值相同,那么程序会在第三步判断中返回true,
* hashCode()方法,它是一个本地方法,底层是运用对象的内存地址通过哈希函数来计算的。
* 问题:为什么重写equals时,一定需要重写hashCode()方法?
* 因为重写了equals()之后,判断两个属性值相同的对象时,会返回true,如果没有重写hashCode(),
* 那么程序还是按照默认的使用内存地址的方法去计算,那么一定会返回false,
* java中规定:两个对象的equals()相同,hashCode一定相同。hashCode相同,但equals不一定相同
* 所以在重写equals时,一定需要重写hashCode。*/
/*什么时候需要重写类的equals()和hashCode()方法?
* 1.当我们需要重新定义两个对象是否相等的条件时,需要进行重写。比如通常情况下,我们认为两个不同对象的某些属性值相同时,
* 就认为这两个对象是相同的。
* 例如:我们在HashMap中添加元素时,我们认为当key相同时,两个元素就相同,但是默认的Object中的equals(),只是单纯的比较两个元素  的内存地址是否相同,不能满足我们的要求,所以需要重写。
* 2.当我们自定义一个类时,想要把它的实例保存在集合时,就需要重写equals()和hashCode()方法。*/

美团JAVA一面面经
2、Comparable 和 Comparator 的区别?

//Comparable 是默认的比较接口, Comparable 和需要比较的对象紧密结合到一起
//Comparator 可以分离比较规则,所以它更具灵活性
一个类实现了 Camparable 接口则表明这个类的对象之间是可以相互比较的,
这个类对象组成的集合就可以直接使用 sort 方法排序。
Comparator 可以看成一种算法的实现,将算法和数据分离, Comparator 也可以在下面两种环境下使用:
1、类的没有考虑到比较问题而没有实现 Comparable,可以通过 Comparator 来实现排序而不必改变对象本身
2、可以使用多种排序标准,比如升序、降序等

详解Java中Comparable和Comparator接口的区别

3、什么是序列化和反序列化?

对象流可以将 Java 对象转换成二进制写入磁盘,这个过程通常叫做序列化,
并且还可以从磁盘读出完整的 Java 对象,而这个过程叫做反序列化。
对象流主要包括: ObjectInputStream 和 ObjectOutputStream

多线程并发

1、什么时候数据在多线程并发的环境下会存在安全问题呢?

三个条件:
			条件1:多线程并发。
			条件2:有共享数据。
			条件3:共享数据有修改的行为。

		满足以上3个条件之后,就会存在线程安全问题。

2、怎么解决线程安全问题呢?

		使用“线程同步机制”
当多线程并发的环境下,有共享数据,并且这个数据还会被修改,
此时就存在线程安全问题,怎么解决这个问题?
			线程排队执行。(不能并发)用排队执行解决线程安全问题。
			这种机制被称为:线程同步机制。

			专业术语叫做:线程同步,实际上就是线程不能并发了,线程必须排队执行。		
		线程同步就是线程排队了,线程排队了就会牺牲一部分效率,没办法,数据安全
		第一位,只有数据安全了,我们才可以谈效率。
线程同步这块,涉及到这两个专业术语:

		异步编程模型:
			线程t1和线程t2,各自执行各自的,t1不管t2,t2不管t1,谁也不需要等谁,
			这种编程模型叫做:异步编程模型。
			其实就是:多线程并发(效率较高。)

			异步就是并发。

		同步编程模型:
			线程t1和线程t2,在线程t1执行的时候,必须等待t2线程执行结束,
			或者说在t2线程执行的时候,必须等待t1线程执行结束,
			两个线程之间发生了等待关系,这就是同步编程模型。
			效率较低。线程排队执行。

			同步就是排队。

聊一聊,我们以后开发中应该怎么解决线程安全问题?

	是一上来就选择线程同步吗?synchronized
		不是,synchronized会让程序的执行效率降低,用户体验不好。
		系统的用户吞吐量降低。用户体验差。在不得已的情况下再选择
		线程同步机制。
	
	第一种方案:尽量使用局部变量代替“实例变量和静态变量”。

	第二种方案:如果必须是实例变量,那么可以考虑创建多个对象,这样
	实例变量的内存就不共享了。(一个线程对应1个对象,100个线程对应100个对象,
	对象不共享,就没有数据安全问题了。)

	第三种方案:如果不能使用局部变量,对象也不能创建多个,这个时候
	就只能选择synchronized了。线程同步机制。

JAVA WEB

1、多个Servlet之间调用规则:

 1.前提条件:
	某些来自于浏览器发送请求,往往需要服务端中多个Servlet协同处理。 但是浏览器一次只能访问一个Servlet,
	导致用户需要手动通过浏览器发起多次请求才能得到服务。这样增加用户获得服务难度,导致用户放弃访问当前网站。

2.提高用户使用感受规则:
	无论本次请求涉及到多少个Servlet,用户只需要【手动】通知浏览器发起 一次请求即可

3.多个Servlet之间调用规则:
	1)重定向解决方案
	2)请求转发解决方案

2、多个Servlet之间数据共享实现方案

数据共享:OneServlet工作完毕后,将产生数据交给TwoServlet来使用

Servlet规范中提供四种数据共享方案
	1.ServletContext接口 【全局作用域对象】
		介绍:如果两个Servlet来自于同一个网站。彼此之间通过网站的 ServletContext 实例对象实现数据共享
		原理:每一个网站都存在一个全局作用域对象。这个全局作用域对象【相当于】一个Map.
			  在这个网站中OneServlet可以将一个数据存入到全局作用域对象,当前网站中其他
			  Servlet此时都可以从全局作用域对象得到这个数据进行使用。
		生命周期:*****全局作用域对象生命周期贯穿网站整个运行期间*****
				 1)在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象
                 2)在Http服务器运行期间时,一个网站只有一个全局作用域对象
				 3)在Http服务器运行期间,全局作用域对象一直处于存活状态
				 4)在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理
	OneServlet{
				 
				    public void doGet(HttpServletRequest request,HttpServletResponse response){
				     
                                              //1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
					       ServletContext application = request.getServletContext();
                                              //2.将数据添加到全局作用域对象作为【共享数据】
					       application.setAttribute("key1",数据)
				    
				    }
				 
				 }

TwoServlet{
				 
				   public void doGet(HttpServletRequest request,HttpServletResponse response){
				   
				        //1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
					ServletContext application = request.getServletContext();
					//2.从全局作用域对象得到指定关键字对应数据
		                	Object 数据 =  application.getAttribute("key1");
				   
				   }
				 
				 }
	2.Cookie类
		介绍: 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于Cookie对象进行数据共享
					Cookie存放当前用户的私人数据,在共享数据过程中提高服务质量
					在现实生活场景中,Cookie相当于用户在服务端得到【会员卡】
		原理:用户通过浏览器第一次向MyWeb网站发送请求申请OneServlet。
		   			OneServlet在运行期间创建一个Cookie存储与当前用户相关数据
		    		OneServlet工作完毕后,【将Cookie写入到响应头】交还给当前浏览器。
		    		浏览器收到响应响应包之后,将cookie存储在浏览器的缓存
		    		一段时间之后,用户通过【同一个浏览器】再次向【myWeb网站】发送请求申请TwoServlet时。
                   【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头】发送过去
		    		此时TwoServlet在运行时,就可以通过读取请求头中cookie中信息,得到OneServlet提供的共享数据
		生命周期:在默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉
						在手动设置情况下,可以要求浏览器将接收的Cookie存放在客户端计算机上硬盘上,同时需要指定Cookie在硬盘上存活时间。
						在存活时间范围内,关闭浏览器关闭客户端计算机,关闭服务器,都不会导致Cookie被销毁。
						在存活时间到达时,Cookie自动从硬盘上被删除
		OneServlet{
			    public void doGet(HttpServletRequest request,HttpServletResponse resp){
			    
			            //1.创建一个cookie对象,保存共享数据(当前用户数据)
				    Cookie card = new Cookie("key1","abc");
				    Cookie card1= new Cookie("key2","efg");
				    ****cookie相当于一个map
				    ****一个cookie中只能存放一个键值对
				    ****这个键值对的key与value只能是String
				    ****键值对中key不能是中文
				    //2.【发卡】将cookie写入到响应头,交给浏览器
				    resp.addCookie(card);
				    resp.addCookie(card1)
			    }
			
			}

			浏览器/用户      <---------响应包 【200】
			                                   【cookie: key1=abc; key2=eft】
							   【】
							   【处理结果】

                        浏览器向myWeb网站发送请求访问TwoServlet---->请求包 【url:/myWeb/two method:get】
			                                                     【
									        请求参数:xxxx
										Cookie   key1=abc;key2=efg
									      】
									      【】
									      【】
TwoServlet{
			 
			    public void doGet(HttpServletRequest request,HttpServletResponse resp){
			    
			         //1.调用请求对象从请求头得到浏览器返回的Cookie
                                  Cookie  cookieArray[] = request.getCookies();
                                 //2.循环遍历数据得到每一个cookie的key 与 value
				  for(Cookie card:cookieArray){
				          String key =   card.getName(); 读取key  "key1"
					  Strign value = card.getValue();读取value "abc"
					  提供较好的服务。。。。。。。。
				  }
			    }
			 }
	3.HttpSession接口【会话作用域对象】
		介绍:如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务
					此时借助于HttpSession对象进行数据共享
		Http服务器如何将用户与HttpSession关联起来:cookie
		与Cookie的区别:下一题
		生命周期: 用户与HttpSession关联时使用的Cookie只能存放在浏览器缓存中.
			  			在浏览器关闭时,意味着用户与他的HttpSession关系被切断
			  			由于Tomcat无法检测浏览器何时关闭,因此在浏览器关闭时并不会导致Tomcat将浏览器关联的HttpSession进行销毁
                        为了解决这个问题,Tomcat为每一个HttpSession对象设置【空闲时间】
			    		这个空闲时间默认30分钟,如果当前HttpSession对象空闲时间达到30分钟
			    		此时Tomcat认为用户已经放弃了自己的HttpSession,此时Tomcat就会销毁掉这个HttpSession
	OneServlet{
			      
			         public void doGet(HttpServletRequest request,HttpServletResponse response){
				 
				        //1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
					     HttpSession   session = request.getSession();
                                        //2.将数据添加到用户私人储物柜
					    session.setAttribute("key1",共享数据)
				 
				 }
			      
			      }

			      浏览器访问/myWeb中TwoServlet

TwoServlet{
			      
			        public void doGet(HttpServletRequest request,HttpServletResponse response){
				       //1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
				        HttpSession   session = request.getSession();
                                       //2.从会话作用域对象得到OneServlet提供的共享数据
				        Object 共享数据 = session.getAttribute("key1");
				}
			      
			      }
	4.HttpServletRequest接口【请求作用域对象】
		介绍:在同一个网站中,如果两个Servlet之间通过【请求转发】方式进行调用,
			     	彼此之间共享同一个请求协议包。而一个请求协议包只对应一个请求对象
			     	因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个Servlet之间实现数据共享
	 OneServlet{
				 
				   public void doGet(HttpServletRequest req,HttpServletResponse response){
				   
				          //1.将数据添加到【请求作用域对象】中attribute属性
					      req.setAttribute("key1",数据); //数据类型可以任意类型Object
                                          //2.向Tomcat申请调用TwoServlet
				             req.getRequestDispatcher("/two").forward(req,response)
				   }
				 
				 }
				 TwoServlet{
				    public void doGet(HttpServletRequest req,HttpServletResponse response){
                                            
					    //从当前请求对象得到OneServlet写入到共享数据
					    Object 数据 = req.getAttribute("key1");
				    }
				 
				 
				 }

3、HttpSession 与 Cookie 区别

1)存储位置:  一个在天上,一个在地下
  		Cookie:存放在客户端计算机(浏览器内存/硬盘)
  		HttpSession:存放在服务端计算机内存

2)数据类型:
  		Cookie对象存储共享数据类型只能是String
  		HttpSession对象可以存储任意类型的共享数据Object

3) 数据数量:
  		一个Cookie对象只能存储一个共享数据
  		HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据

4)参照物:
  		Cookie相当于客户在服务端【会员卡】
  		HttpSession相当于客户在服务端【私人保险柜】
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值