java 基础知识 JVM 面向对象的理解? AJAX 的 原理? 1 . tcp连接有几次握手? 有几次释放? 2.数据库中sql的转换: 3 . SpringMVC 的工作原理? 4.mybatis的原理实现? 5.hibernate 的实现原理? 在项目中有几个地方可以设置编码格式? 在Java种常用的 包 类 和接口? get请求的最大的长度
基本类型类型以及对象的引用变量是存储在栈内存中 ;而对象本身的值或者说 new 创建的对象和数组是存储在堆内存中。
java 基本数据类型传递参数时是值传递 ;引用类型传递参数时是引用传递 。
在 Java 应用程序中永远不会传递对象,而只传递对象引用。因此是按引用传递对象。
String 类有一个内置的构造函数 String(character_array),它可以将字符数组初始化成一个字符串。split() 根据指定的规则或分隔符来分隔字符串,并返回数组
clone( ) 方法调用时会生成多个对象的拷贝。 类只有在实现 Cloneable 接口才可以实现克隆。
面向对象的理解?
面向对象其实就是有 封装 继承 多态三个方面,
封装是面向对象最基本的原则, 是把一个对象的属性和行为(数据)集合成一个整体,就是隐藏对象内部的实现方式,告诉别人这个方法是什么需求,但是实现方法的过程不会让调用者知道 是隐藏起来的,增加了安全性 。
继承 是面向对象的重要特征, 是众多类中派生出新的类。 就是子类继承父类。 实现是父类的所有方法和属性, 可以在原有的基础上增加新增需求,调高了代码的复用性,
多态 封装和继承是给多态提供的。 在执行期间根据需求来判断对象的实际类型, 从而调用相应的方法来实现。
继承:
中是单继承多实现, 可以多重继承。 子类是不能继承父类的构造器的, 它只有调用,如果父类的构造器带有参数,则必须在子类的构造器中显示的通过supper 关键字调用父类中的构造器并配以适当的参数列表。 如果父类的构造器没有参数,子类的构造器中就不用使用supper关键字,系统会自动调用父类的无参构造器。
子类继承父类。 如果使用supper 关键字如果有参数就调用父类有参数的。 如果没有参数就调用没有无参的构造方法,
如果没有使用supper关键字, 就调用父类无参构造方法。
如果final 关键字声明的类不能被继承,或者是修饰的方法 该方法不能被子类重写。
重写: 规则
使用final修饰的方法不能被重写, 使用static 修饰的方法不能被重写。使用private 修饰的方法不能被重写,构造方法不能被重写,如果不是继承一个类,不能被重写这个类中的方法,
重写的方法名参数必须一样,返回值类型可以不一致, java5 之前的版本必须一致, java7之后的版本可以不一致。
访问的权限不能比父类还要低,父类的成员方法只能被它的子类重写。
重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
当子类想调用父类的关键字的时候可以使用supper关键字:
class Animal{ public void move(){ System.out.println("动物可以移动"); } } class Dog extends Animal{ public void move(){ super.move(); // 应用super类的方法 System.out.println("狗可以跑和走"); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); // Dog 对象 b.move(); //执行 Dog类的方法 } } 以上实例编译运行结果如下: 动物可以移动 狗可以跑和走
重载:
规则:
重载是发生在一个类中, 方法名相同 参类型不同,参数个数不同,返回的类型可以相同也可以不同。
每个重载的方法都必须是有一个独一无二的参数类型列表。 最常用的地方就是构造器的重载。
被重载的方法可以改变访问修饰符,
被重载的方法可声明更加广的检查异常,
方法可以在同一个类中或者是在一个子类中被重载,
无法以返回值类型作为重载函数的区分标准。
方法重载和重写都是java的多态性的不同表现,重写是父类与子类之间的多态性的表现,重载是一个类的多态性表现。
java的多态;
多态就是同一个行为具有不同表现形式或者是形态能力。多态就是同一个接口,使用不同的实例实现不同的操作等。
多态存在的条件:必须是继承 ,重写 , 父类引用子类的对象。
多态的优点:消除了类型之间的耦合关系,可替换性,可扩展性,接口性, 灵活性, 简化性。
多态实现的方法: 方法一重写 方法二 接口。方法三 抽象类和抽象方法。
抽象类: 抽象类不能实例化类之外, 其余的和普通的类都一样。
抽象类是存在继承的关系的。
如果一个类包含了抽象的方法,那么这个类就是抽象类。
任何子类必须重写父类的抽象方法, 或者是声明自身为抽象类。
抽象类中不一定包含抽象方法, 但是有抽象的方法的类就是抽象类。
抽象类中的抽象方法只是声明不包含方法体,
构造方法, 类方法, 不能声明为抽象方法,
封装: 是把代码装到一个地方保护起来。 像一个保护屏障一样, 不让外部的代码随意访问等,
优点:
良好的封装可以减少耦合,可以用内部的成员变量进行精确的控制,类内部的结构可以自由的修改,隐藏信息实现细节。 比如常用的创建一个 实体类。
接口: 接口是支持多继承的。 接口中还可以声明变量 隐式加上public static final 修饰。
java中有局部变量 和 成员变量 和类变量, 局部变量是在方法或者构造方法里面。 成员变量是在类中定义的变量, 类变量是在方法外 类中定义的变量但是必须用static 来修饰。
java的两大数据类型: 内置数据类型 和 引用数据类型。
transient 修饰符
public transient int limit = 55; // 不会持久化 public int b; // 持久化
volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
在不同的线程中 读取到相同的值。
Calendar 的类
比date 类的 更加强大的类使用 calendar 类。而且在实现方式上也比date更加复杂的多功能也多。
Calendar c = Calendar.getInstance();//默认是当前日期
Calendar c1 = Calendar.getInstance(); // 获得年份 int year = c1.get(Calendar.YEAR); // 获得月份 int month = c1.get(Calendar.MONTH) + 1; // 获得日期 int date = c1.get(Calendar.DATE); // 获得小时 int hour = c1.get(Calendar.HOUR_OF_DAY); // 获得分钟 int minute = c1.get(Calendar.MINUTE); // 获得秒 int second = c1.get(Calendar.SECOND); // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推) int day = c1.get(Calendar.DAY_OF_WEEK);
FileInputStream
该流用于从文件读取数据,它的对象可以用关键字 new 来创建。
使用 文件输入流和 输出流 fileinputStream
InputStream f = new FileInputStream("D://java/hello") 相当于: File f = new File("D://java/hello") InputStream out = new FileInputStream(f);
FileOutputStream
创建一个文件并向该文件写数据
OutputStream f = new FileOutputStream("C:/java/hello") 相当于: File f = new File("C:/java/hello"); OutputStream f = new FileOutputStream(f);
使用的方法:
public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。 protected void finalize()throws IOException {} 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。 public void write(int w)throws IOException{} 这个方法把指定的字节写到输出流中。 public void write(int w)throws IOException{} 这个方法把指定的字节写到输出流中。
创建一个文件写数据并读出来;
1 //文件名 :fileStreamTest2.java 2 import java.io.*; 3 4 public class fileStreamTest2 { 5 public static void main(String[] args) throws IOException { 6 7 File f = new File("a.txt"); 8 FileOutputStream fop = new FileOutputStream(f); 9 // 构建FileOutputStream对象,文件不存在会自动新建 10 11 OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8"); 12 // 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk 13 14 writer.append("中文输入"); 15 // 写入到缓冲区 16 17 writer.append(" "); 18 // 换行 19 20 writer.append("English"); 21 // 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入 22 23 writer.close(); 24 // 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉 25 26 fop.close(); 27 // 关闭输出流,释放系统资源 28 29 FileInputStream fip = new FileInputStream(f); 30 // 构建FileInputStream对象 31 32 InputStreamReader reader = new InputStreamReader(fip, "UTF-8"); 33 // 构建InputStreamReader对象,编码与写入相同 34 35 StringBuffer sb = new StringBuffer(); 36 while (reader.ready()) { 37 sb.append((char) reader.read()); 38 // 转成char加到StringBuffer对象中 39 } 40 System.out.println(sb.toString()); 41 reader.close(); 42 // 关闭读取流 43 44 fip.close(); 45 // 关闭输入流,释放系统资源 46 47 } 48 }
File f = new File(); f.isDirectory 是判断是否 是一个文件夹或者是文件,true是文件夹,目录, false 是文件
Canner
我们可以通过 Scanner 类来获取用户的输入。
public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 从键盘接收数据 // next方式接收字符串 System.out.println("next方式接收:"); // 判断是否还有输入 if (scan.hasNext()) { String str1 = scan.next(); // 如果用户输出的有空格,就以空格结尾,空格后面的内容就输出不出来了。 //String Str2 = scan.nextLine(); // 使用输入空格也能输出 出来。 最好还是采用使用nextLine 方法。 System.out.println("输入的数据为:" + str1); } scan.close(); }
java 异常
有 检查性异常 运行异常,错误
在java开发中遇到的异常有哪些:
空指针,数组下标越界,io异常,一个整数除以0时 抛出的异常,用非法索引访问数组抛出的异常,试图将一个错误的类型对象存到一个对象数组中抛出的异常,线程没有处于请求操作所要求适当的状态抛出异常,当不支持请求时抛出异常 等等。
还有自定义异常。
java中集合狂框架图:
collection > List set 存储元素的集合
Map 存储键/值对映射
List 有 ArrayList LinkedList Vector
set 有 HashSet TreeSet LinkedHashSet
Map 有 HashMap LinkedHashMap Hashtable TreeMap
Set 检索效率低。 删除和插入的效率高。 插入和删除不会引起元素的位置改变 实现的方式有 hashSet TreeSet
List 和数组类似,可以动态的增加长度,根据实际存储的长度自动增加list的长度,查找的效率高, 删除和插入的效率低因为会引起其他元素位置的改变 实现的方式有 ArrayList LinkedList Vector
LinkedList 是允许空元素的,主要创建链表数组结构,该类没有同步方法,如果多个线程同时访问一个list, 那么必须自己实现访问同步, 解决的方法是在创建list 的时候构造一个同步的List
List list=Collections.synchronizedList(newLinkedList(...));
ArrayList 是底层是数组结构 , 实现可改变大小的数组, 该类也是非同步的, 在多线程不要使用,ArrayList的增长当前的长度的50%,插入删除效率低, 查询效率高。
Vector 该类和ArrayList是非常相似的。但是该类是同步的,可以在多线程中使用,该类默认增长的长度是原来的2倍。
HashSet 不允许出现的重复的元素,不能保证集合中元素的顺序, 最多有一个空元素。
LinkedHashSet 具有可预知迭代顺序的set接口的哈希表和链接列表实现。
TreeSet 可以实现排序功能。
HashMap 存储的内容的兼职对的映射。根据键hashcode 值存储数据,具有很快的访问速度,最多允许一条记录 键为null, 不支持线程同步,
TreeMap 继承了AbstractMap ,并且是一颗树,
LinkedHashMap 继承与HashMap , 使用元素的自然顺序对元素进行排序
List 和set 遍历 Iterator<String> ite=list.iterator(); while(ite.hasNext())//判断下一个元素之后有值 { System.out.println(ite.next()); } map 遍历 方式: //第一种:普遍使用,二次取值 System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //第二种 System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第三种:推荐,尤其是容量大时 System.out.println("通过Map.entrySet遍历key和value"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第四种 System.out.println("通过Map.values()遍历所有的value,但不能遍历key"); for (String v : map.values()) { System.out.println("value= " + v); }
序列化
序列化的文件是 .ser 文件
如果有一个属性不是可序列化的,则该属性必须注明是短暂的。 就是使用 transient 修饰。 public transient int SSN;
Employee 实现 java.io.Serializable接口。
public static void main(String [] args) { Employee e = new Employee(); e.name = "Reyan Ali"; e.address = "Phokka Kuan, Ambehta Peer"; e.SSN = 11122333; e.number = 101; try { FileOutputStream fileOut = new FileOutputStream("/tmp/employee.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(e); out.close(); fileOut.close(); System.out.printf("Serialized data is saved in /tmp/employee.ser"); }catch(IOException i) { i.printStackTrace(); } }
反序列化
使用 ObjectInputStream 是进行 .ser 文件进行反序列化。
public static void main(String [] args) { Employee e = null; try { FileInputStream fileIn = new FileInputStream("/tmp/employee.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); e = (Employee) in.readObject(); in.close(); fileIn.close(); }catch(IOException i) { i.printStackTrace(); return; }catch(ClassNotFoundException c) { System.out.println("Employee class not found"); c.printStackTrace(); return; } System.out.println("Deserialized Employee..."); System.out.println("Name: " + e.name); System.out.println("Address: " + e.address); System.out.println("SSN: " + e.SSN); System.out.println("Number: " + e.number); }
AJAX 的 原理?
就是使用xmlHttpRequest 对象向服务器发送异步请求, 服务器获取数据 , 然后使用JavaScript 来更新页面。
1 . tcp连接有几次握手? 有几次释放?
(1) 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。
(2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。
(3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手
简单说来是 “先关读,后关写”,一共需要四个阶段。以客户机发起关闭连接为例:
1.服务器读通道关闭
2.客户机写通道关闭
3.客户机读通道关闭
4.服务器写通道关闭
2.数据库中sql的转换:
行转列的需求如下, 主要思路是分组后使用case进行条件判断处理 可以发现,行转列时其实是先group by,然后将每个组中的行转为列,使用case-when + 聚合函数。
列转行的需求是 主要思路也是分组后使用case 或者 先使用union拼接 使用 order by ,
3 . SpringMVC 的工作原理?
- 用户发送请求到前端控制器dispatcherservlet.
- dispatchersevlet接受到请求调用HandlerMapping处理器映射器。
- 处理映射器找到了具体的处理器(根据配xml置文件和java代码的注解)进行查找,dispatcherservlet 调用handlerAdapter处理器适配器,
- HandlerAdapter 经过适配且的处理器(controller)执行完成后返回modelAndview
- controller将返回的modelAndView 返回给dispatcherservlet,
- dispatchservlet 将modelAndView 传给ViewResolver视图解析器。
- dispatchservlet将view 进行渲染到页面上,响应用户。
4.mybatis的原理实现?
mybatis应用程序根据xml配置文件创建sqlsessionFactory, sqlSessionFactroy是根据两个地方 一个是配置文件,一个是java代码的注解,然后获取到sqlSession 。sqlSession包含了sql中的所有方法和属性,通过sqlsession的实例运行映射sql语句,对数据库进行增删改查和提交事务的操作,关闭sqlSession。
5.hibernate 的实现原理?
- 读取并解析配置
- 创建sqlsessionFactory
- 打开 session
- 打开事务
- 持久化操作
- 关闭事务
- 关闭session
- 关闭sessionFactory
在项目中有几个地方可以设置编码格式?
1 在配置文件中 application.properties中设置
#编码格式 spring.http.encoding.force=true spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true server.tomcat.uri-encoding=UTF-8
2 可以在自己配置的过滤器中:
@WebFilter(urlPatterns = "/*",filterName = "CharacterEncodingFilter") public class CharacterEncodingFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); filterChain.doFilter(request , response); } @Override public void destroy() { } }
3 使用java配置写一个字符编码配置类
/** * 中文乱码解决 */ @Configuration public class CharsetConfig extends WebMvcConfigurerAdapter { @Bean public HttpMessageConverter<String> responseBodyConverter() { StringHttpMessageConverter converter = new StringHttpMessageConverter( Charset.forName("UTF-8")); return converter; } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { super.configureMessageConverters(converters); converters.add(responseBodyConverter()); } @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorPathExtension(false); } }
在Java种常用的 包 类 和接口?
包: 类
java.lang , java提供的基础类。 Object 、 Math、String、StringBuffer、System、Thread等,
java.util 该包提供了包含集合框架、遗留的集合类、事件模型、日期和时间实施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。
java.io 该包通过文件系统、数据流和序列化提供系统的输入与输出。
java.net 该包提供实现网络应用与开发的类。
Java.sql 该包提供了使用Java语言访问并处理存储在数据源
java.text 提供了与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。
public void close() throws IOException{}
关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
存储键/值对映射
get请求的最大的长度
IE 浏览器是 2k 谷歌浏览器是8千多个字符 火狐浏览器支持最大的是 10w左右个字符