Servlet
1、Servlet的生命周期
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。
- Servlet 初始化后调用 init () 方法。
- Servlet 调用 service() 方法来处理客户端的请求。
- Servlet 销毁前调用 destroy() 方法。
- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
2、Servlet的九大内置对象
- 4个域对象:
- request请求对象--接收通过HTTP协议传送到服务器的数据
- session会话对象--用于保存用户信息
- application应用程序对象--将信息保存在服务器中
- pageContext页面上下文对象--取得任何范围的参数
- 2个输出对象:
- response响应对象--将JSP处理过的对象传回客户端
- out输出对象--在Web浏览器内输出信息
- 3个打酱油:
- config配置对象--取得服务器的配置信息
- page页面对象--代表JSP本身
- exception例外对象--显示异常
3、监听器、过滤器、拦截器区别(应用场景)
- 监听器(Listener)
- 是一个实现特定接口的普通Java程序,这个程序专门用于监听一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行
- Servlet规范中的一员,实现了ServletContextListener接口
- 依赖web容器存在,在web.xml中配置,在事件触发时调用,主要监听对应事件的发生
- SpringMVC监听器主要的作用就是Spring容器启动的时候加载一些数据,最常用的功能就是开发权限系统的时候,当监听器启动的时候,从数据库加载权限url
- *写一个监听器>?
- 编写一个类实现xxListener接口
- 在web.xml中对xxxLitener进行配置(也可以用注解)
- 由web服务器调用监听器的方法
- 过滤器(Filter)
- Servlet规范中的一员,Servlet的“加强版”,对用户请求进行预处理,然后交给Servlet处理并产生响应,最后Filter再对服务器响应进行后处理
- 作用:拦截Servlet请求
- 任何过滤器都要实现Javax.Servlet.Filter接口
- 基于函数回调来实现
- 过滤器依赖Servlet容器存在,在Web.xml中配置,会在请求还未进入Servlet之前或出Servlet之后调用
- 系统级别的过滤
- 过滤器对几乎所有的请求起作用
- 过滤器只能在容器初始化时被调用一次
- 过滤器Filter:处于客户端与被请求资源之间,目的是重用代码。用于设置字符编码、URL级别的权限控制,敏感词汇的过滤
- 拦截器(Interceptor)
- 在面向切面编程中应用
- 基于Java反射机制来实现(JDK实现的动态代理)
- 非系统级别,没有过滤器强大,但是更有针对性
- 拦截器依赖Web框架(Spring、Struts),在Web框架的配置文件中配置,在请求出Servlet之后,进入对应的Controller之前调用,或在出Controller之后,进入对应Servlet之前调用
- 执行顺序:
监听器 > 过滤器 > 拦截器 > Servlet执行 > 拦截器 > 过滤器 > 监听器
4、什么是反射,反射的优点、缺点?
Java的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法,并且对于任意一个对象,都能够调用它的任意一个方法,这种动态获取信息以及动态调用对象方法的功能称为Java的反射机制。
反射就是把java类中的各种成分映射成一个个的Java对象
- 反射中,可把方法视为对象
- 用方法对象 来调用 方法
- 运行时期,动态创建对象
反射有什么用
1,在运行时判断任意一个对象所属的类;
2,在运行时构造任意一个类的对象;
3,在运行时判断任意一个类所具有的成员变量和方法;
4,在运行时调用任意一个对象的方法;
5,生成动态代理。
优点:
反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;
缺点:
1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。 2、使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。至于执行效率的话,还可以,因为它是一种强类型语言,执行效率不错。不过,建议将反射过后,保存进 cache中。 3、安全问题,反射技术要求程序必须在一个没有安全限制的环境中运行。 4、成员的内部暴露,代码有功能上的错误,降低可移植性。反射代码破坏了抽象性
5、Java创建对象的几种方式
- 通过new创建对象
- 反射创建对象
- clone创建对象
- 序列化创建对象
6、Http常见状态码
- 400:服务器不理解请求的语法
- 404:服务器找不到请求的网页
- 403:服务器拒绝请求
- 500:服务器遇到错误,无法完成请求。
- 502:服务器作为网关或代理,从上游服务器收到无效响应
- 503:服务器目前无法使用
7、String和StringBuffer和StringBuilder的区别
结构 | 是否可变 | 线程安全 | 效率 | 拼接 | |
---|---|---|---|---|---|
String | 字符串常量 | 不可变 | 低 | 两个不同的空间 | |
StringBuffer | 字符串变量 | 可变 | 安全 | 中 | 字符串后直接追加 |
StringBuild | 字符串变量 | 可变 | 不安全 | 高 | 字符串后直接追加 |
字符串有大量修改 → 单线程 → 选择StringBuilder
字符串有大量修改 → 多线程 → 选择StringBuffer
字符串很少修改,被多个对象引用 → 选择String
8、String为什么是final修饰的
- 为了实现字符串连接池
- 只有当字符串是不可变的,字符串池才有可能实现;
- 如果字符串是可变的,那么会引起很严重的安全问题;
- 为了线程安全
- 因为字符串是不可变的,所以是多线程安全的,同+;
- 一个字符串实例可以被多个线程共享;
- 类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载;
- 为了实现String可以创建HashCode不可变性
- 因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。
9、什么是代码重构?
- 代码重构(Code refactoring)重构就是在不改变软件系统外部行为的前提下,对它的内部结构进行改善。
- 特点:使代码更易为人所理解。通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性
10、描述面向对象设计的7大原则
开闭原则
要对扩展开放,对修改关闭;里氏替换原则
不要破坏继承体系;依赖倒置原则
面向接口编程;单一职责原则
实现类要职责单一;接口隔离原则
设计接口的时候要精简单一;迪米特法则
最少只是原则-要降低耦合度;合成复用原则
要优先使用组合或者聚合关系复用,少用继承关系复用。
双亲委派模型?
是什么:加载器在加载过程中,先把类交由父类加载器进行加载,父类加载器没找到才由自身加载。其实就是一种类加载器的层次关系。自定义类-->应用程序类-->扩展类-->启动类加载器
存在意义:为了防止内存中存在多份同样的字节码(安全)
如何打破双亲委派模型:自定义ClassLoader,重写loadClass方法
打破案例:Tomcat
强引用、软引用、弱引用、虚引用?
强:传统“引用”,GC不回收;
软:还有用,但非必要对象,内存不够时回收;
弱:同样描述非必要对象,但比软引用弱一点,无论内存是否足够都会回收;
虚:最弱引用,唯一目的:该对象被回收时收到一个系统通知。
Java代码性能优化?
- 尽量指定类、方法的final修饰符
- 尽量重用对象
- 尽量使用局部变量
- 及时关闭流
- 尽量采用懒加载策略
- 不要在循环中使用try-catch
- 及时清理不需要的会话
- 同步代码块代替同步方法
- 对等比较时字符串常量写在equals前面
Java代码精简优化?
- 利用Lombok注解
- 利用泛型
- 利用三元表达式
- for-each代替for
- 利用Lambda表达式
- 利用return关键字
- 利用设计模式
- 删除冗余代码
Java中的锁?
- 轻量级锁、重量级锁
- 悲观锁、乐观锁
- 自旋锁、非自旋锁
- 公平锁、非公平锁
- 共享锁、独占锁
本文作者:Ritchie里其
本文链接:https://www.cnblogs.com/wang-zeyu/p/16667028.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步