江西做网站的公司有哪些网站改标题
news/
2025/9/23 12:55:41/
文章来源:
江西做网站的公司有哪些,网站改标题,做网站虚拟主机要多大,wordpress 用户地图1、Struts2和SpringMVC的区别(1)设计理念#xff1a;前者为有状态的Action(均为多例)#xff0c;Action对象属性字段承载请求、响应#xff0c;后者一般为无状态的Controller#xff0c;请求直接封装到方法的参数中#xff1b;(2)集中访问点不同#xff1a;都属于前端控制…1、Struts2和SpringMVC的区别(1)设计理念前者为有状态的Action(均为多例)Action对象属性字段承载请求、响应后者一般为无状态的Controller请求直接封装到方法的参数中(2)集中访问点不同都属于前端控制器用于接收请求、处理请求和生成响应但集中访问点不同前者为Filter后者为Servlet(3)请求处理粒度不同前者一个Action对应一个请求上下文后者一个方法对应一个请求上下文因此更容易实现Rest(4)拦截器机制不同Struts2和SpringMVC的拦截器机制均是对AOP理念的应用但Struts2的interceptor机制是通过代理机制(ActionProxy)责任链模式实现的而SpringMVC的interceptor机制实现比较简单其通过循环的方式在handler处理请求前后分别调用preHandle()方法和postHandle()方法对请求和响应进行处理与Spring AOP、责任链模式等基本无关(5)对ajax的支持不同前者需要插件或者手动转化而后者集成了对Ajax请求的处理(HttpMessageConverter)(6)与Spring的整合前者需要插件后者无缝整合(子容器)(7)配置/效率后者几乎是零配置开发效率更高。2、Spring中IOC的理解(1)超级大工厂对象控制权由调用者移交给容器使得调用者不必关心对象的创建和管理专注于业务逻辑开发(2)优秀的解耦方式解耦对象间的依赖关系避免通过硬编码的方式耦合在一起(3)底层实现反射机制3、Spring中AOP的理解(1)一种新的模块化方式专门处理系统各模块中的交叉关注点问题将具有横切性质的系统级业务提取到切面中与核心业务逻辑分离(解耦)(2)便于系统的扩展符合开-闭原则(3)动态AOP的实现Java动态代理(接口代理)与cglib(类代理)具体由Bean后处理器生成代理(4)AOP理念实践Spring AOPJava Web FilterStruts2 Interceptor SpringMVC Interceptor…4、JVM 基础4.1内存模型(1)程序计数器线程私有CPU调度的基本单位用于保证线程切换(程序能够在多线程环境下连续执行)(2)栈(服务Java方法虚拟机栈、服务Native方法的本地方法栈)线程私有局部变量/引用栈深度(SOF)/无法申请内存(OOM)(3)堆(Java代码可及的Java堆和JVM自身使用的方法区):线程共享对象分配和回收主要区域OOM4.2垃圾回收机制(1)Stop-the-World JVM由于要执行GC而停止了应用程序的执行称之为Stop-the-World该情形会在任何一种GC算法中发生。当Stop-the-world发生时除了GC所需的线程以外所有线程都处于等待状态直到GC任务完成。事实上GC优化很多时候就是指减少Stop-the-world发生的时间从而使系统具有高吞吐 、低停顿的特点。(2)JAVA堆的回收关于Java对象的回收主要考虑以下两个问题哪些对象可以被回收、怎么回收(有哪些回收算法以及有哪些垃圾回收器)。①判断对象是否可被回收引用计数法(相互引用)、可达性算法(对象的引用链是否可达GCRoots)②垃圾回收算法标记-清除算法(内存碎片)、复制算法(垃圾回收较为频繁、对象存活率较低的新生代)、标记-整理算法(垃圾回收不频繁、对象存活率较高的老年代)、分代收集算法。③垃圾回收器串行收集器(新生代、老年代)、并行收集器(新生代、老年代)、并行清除收集器(并发新生代追求高吞吐)、CMS收集器(并发老年代标记-清除算法追求低停顿)、G1垃圾收集器(整个堆追求低停顿)附GC Roots一般包括虚拟机栈中引用的对象本地方法栈中引用的对象方法区中类静态属性引用的对象、方法区中常量引用的对象。附GC Roots一般包括虚拟机栈中引用的对象本地方法栈中引用的对象方法区中类静态属性引用的对象、方法区中常量引用的对象。分代收集算法的基本思想是不同的对象的生命周期(存活情况)是不一样的而不同生命周期的对象位于堆中不同的区域因此对堆内存不同区域采用不同的策略进行回收可以提高 JVM 的执行效率。Minor GC 发生频率较高不一定等 Eden区满了才触发Major GC在老年代满时触发对年轻代和老年代进行回收。(3)方法区回收①对常量池的回收。②对类型的卸载该类的所有实例被回收该类的ClassLoader被回收不存在对该类的Class对象的引用。4.3 OOM/SOF(1)OOM for Heap内存泄露(GC Roots的引用链对象的生命周期超出预期)或者内存溢出(调节JVM参数 -Xms-Xmx 等)(2)OOM for Stack一般在单线程程序中不会出现在多线程环境下无法申请到足够的内存去创建线程(3)SOF for Stack程序是否有深度递归。(4)OOM for Perm 用到像Spring等框架的时候常常会动态地生成大量的类导致永久代不够用而导致OutOfMemoryError: PermGen Space异常(调大 -XX:MaxPermSize)5、JVM 调优JVM 调优的主要目标是使系统具有高吞吐、低停顿的特点其优化手段应从两方面着手Java虚拟机和Java应用程序。前者指根据应用程序的设计通过虚拟机参数控制虚拟机逻辑内存分区的大小以使虚拟机的内存与程序对内存的需求相得益彰后者指优化程序算法降低GC负担提高GC回收成功率。以下是一些常用的JVM调优工具(1)Jconsole 与 Visual VMJConsole 与 Visual VM 都是JDK自带的 Java 性能分析器可以从命令行或在 GUI shell 中运行从而可以轻松使用 JConsole来监控 Java 应用程序性能和跟踪 Java 中的代码其可以从JAVA_HOME/bin/这个目录下找到。使用 Jconsole 监测死锁示例如下(1)JstackJDK自带的命令行工具可以查看某个Java进程内的线程堆栈信息主要用于线程Dump分析。(1)JPSjps位于jdk的bin目录下其作用是显示当前系统的java进程情况及其id。6、责任链(CoR)模式目的请求的发送者与请求的处理者解耦便于动态的重新组织链和分配责任。角色抽象处理者、具体处理者、客户端。UML: 传统责任链(CoR)模式的缺点在于具体处理角色存在着共同的实现责任链结构的行为行为即责任链的建立和指派包含在实现角色的类中并没有抽象出来这直接导致责任链的指派不够灵活。因此改进的CoR模式为使用AOP理念将责任链结构的实现用切面抽象出来使得各个对象只关注自身必须实现的功能性需求准确地分离出责任链模式中不同角色的共同行为例如改进后责任链(CoR)模式的应用是比较广泛的包括 Java Web Filter(链式调用)Struts2 Interceptor(Action代理)和SpringMVC等。7、单例模式 单例模式核心在于为整个系统提供一个唯一的实例为整个系统提供一个全局访问点。单例模式从实现上可以分为饿汉式单例和懒汉式单例两种前者天生就是线程安全的后者则需要考虑线程安全性常见的线程安全的懒汉式单例的实现有内部类式和双重检查式两种。下面给出单例模式几种常见的形式(1) 饿汉式单例(1) 懒汉式单例(1) 线程安全的懒汉式单例 —— 内部类方式内部类方式线程安全懒汉式单例的内在原理在于虚拟机会保证一个类的类构造器()在多线程环境中被正确的加锁、同步如果多个线程同时去初始化一个类那么只会有一个线程去执行这个类的类构造器()其他线程都需要阻塞等待直到活动线程执行()方法完毕。特别需要注意的是在这种情形下其他线程虽然会被阻塞但如果执行()方法的那条线程退出后其他线程在唤醒之后不会再次进入/执行()方法因为在同一个类加载器下一个类型只会被初始化一次。(4) 线程安全的懒汉式单例——双重检查方式8、类的生命周期及其初始化时机类的生命周期主要包括加载、链接、初始化、使用和卸载五个阶段如下图所示(1) 遇到new、getstatic、putstatic或invokestatic这四条字节码指令时注意newarray指令触发的只是数组类型本身的初始化而不会导致其相关类型的初始化比如new String[]只会直接触发String[]类的初始化也就是触发对类[Ljava.lang.String的初始化而直接不会触发String类的初始化时如果类没有进行过初始化则需要先对其进行初始化。生成这四条指令的最常见的Java代码场景是①使用new关键字实例化对象的时候②读取或设置一个类的静态字段(被final修饰已在编译器把结果放入常量池的静态字段除外)的时候③调用一个类的静态方法的时候。(2) 对类进行反射调用时使用java.lang.reflect包的方法对类进行反射调用的时候如果类没有进行过初始化则需要先触发其初始化。(3) 初始化子类时当初始化一个类时候如果发现其父类还没有进行过初始化则需要先触发其父类的初始化。(4) 虚拟机启动时当虚拟机启动时用户需要指定一个要执行的主类(包含main()方法的那个类)虚拟机会先初始化这个主类。(5) 当使用jdk1.7动态语言支持时如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄并且这个方法句柄所对应的类没有进行初始化则需要先出触发其初始化。9、类加载过程中各阶段的作用9.1加载(Loading)(1)通过一个类的全限定名来获取定义此类的二进制字节流(并没有指明要从一个Class文件中获取可以从其他渠道譬如网络、动态生成、数据库等)(2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构(3)在内存中(对于HotSpot虚拟机而言就是方法区)生成一个代表这个类的java.lang.Class对象作为方法区这个类的各种数据的访问入口9.2链接(Linking)(1)验证:验证是连接阶段的第一步这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求并且不会危害虚拟机自身的安全。(2)准备(Preparation)准备阶段是正式为类变量(static 成员变量)分配内存并设置类变量初始值(零值)的阶段这些变量所使用的内存都将在方法区中进行分配。(3)解析(Resolution)解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。9.3初始化 初始化阶段是执行类构造器()方法的过程。虚拟机会保证一个类的类构造器()在多线程环境中被正确的加锁、同步如果多个线程同时去初始化一个类那么只会有一个线程去执行这个类的类构造器()其他线程都需要阻塞等待直到活动线程执行()方法完毕。特别需要注意的是在这种情形下其他线程虽然会被阻塞但如果执行()方法的那条线程退出后其他线程在唤醒之后不会再次进入/执行()方法因为在同一个类加载器下一个类型只会被初始化一次。10、对象的创建过程在Java中创建一个对象常常需要经历如下几个过程父类的类构造器() - 子类的类构造器() - 父类的实例构造器(成员变量和实例代码块父类的构造函数) - 子类的实例构造器(成员变量和实例代码块子类的构造函数)。其中类构造器()由静态变量和静态语句块组成而类的实例构造器()类的实例变量/语句块以及其构造函数组成。11、双亲委派模型双亲委派模型很好地解决了类加载器的统一加载问题越基础的类由越上层的加载器进行加载进而保证Java类型体系中最基础的行为防止应用程序变得混乱。比如java.lang.Object 类总是由启动类加载器进行加载因此Object类在程序的各种类加载器环境中都是同一个类型(是否是同一类型由类加载器与类本身共同决定)。(1)BootStrap引导类加载器加载都是最基础的文(JRE/lib/rt.jar)(2)ExtClassLoader:引导类加载器加载都是最基础的文件(JRE/lib/ext/*.jar)(3)AppClassLoaderClassPath指定的所有jar或目录。12、异常机制Java体系中异常的组织分类如下图所示所有异常类型的根类为 Throwable具体包括两大类Error 与 Exception。其中Error是指程序无法处理的错误表示运行应用程序中较严重问题Exception是指程序本身可以处理的错误具体可分为运行时异常(派生于 RuntimeException 的异常)和其他异常。此外从异常是否必须需要被处理的角度来看异常又可分为不受检查异常和受检查异常两种情况(1)不受检查异常派生于 Error 或 RuntimeException 的所有异常。(2)受检查异常除去不受检查异常的所有异常。finally子句在对应的try子句执行的前提下finally 子句总会被执行。并且finally子句 总是在诸如return、break、throw和continue等控制转移语句之前执行。13、六大设计原则(1)单一职责原则高内聚一个类只做它该做的事情(2)接口隔离原则接口小而专避免大而全(3)依赖倒置原则依赖抽象而非实现面向接口编程(4)里氏替换原则子类可以扩展父类的功能但不能改变父类原有的功能(5)开闭原则Open for Extension, Closed for Modification例如AOP代理模式适配器模式就是其经典应用(6)迪米特法则高内聚低耦合14、代理模式 根据代理类的创建时机和创建方式的不同我们可以将代理模式分为静态代理和动态代理两种形式其中在程序运行前就已经存在的编译好的代理类是为静态代理在程序运行期间根据需要动态的创建代理类及其实例来完成具体的功能是为动态代理。其中代理对象的作用如下(1) 代理对象存在的价值主要用于拦截对真实业务对象的访问(2) 代理对象应该具有和目标对象(真实业务对象)相同的方法即实现共同的接口或继承于同一个类(3) 代理对象应该是目标对象的增强否则我们就没有必要使用代理了。 JDK 动态代理是动态代理模式的经典实现主要包括三个角色对象Subject (接口)、被代理的类以及InvocationHandler接口(一般持有被代理对象)例如(1)实现 InvocationHandler 接口(2)Proxy.newProxyInstance 但是JDK动态代理只能完成对接口的代理而不能完成对类的代理关键原因为Java只允许单继承。具体地代理对象proxySubject的类型为“com.sun.proxy.$Proxy0”这恰好印证了proxySubject对象是一个代理对象。除此之外我们还发现代理对象proxySubject所对应的类继承自java.lang.reflect.Proxy类这也正是JDK动态代理机制无法实现对class的动态代理的原因。15、迭代器模式迭代器模式是与集合共生共死。一般来说,我们实现一个容器,就需要同时提供这个容器的迭代器,使用迭代器的好处封装容器内部的实现细节,对于不同的集合,可以提供统一的遍历方式简化客户端的访问和获取容器内数据。 特别需要注意的是在迭代器模式中具体迭代器角色和具体容器角色是耦合在一起的 —— 遍历算法是与容器的内部细节紧密相关的。为了使客户程序从与具体迭代器角色耦合的困境中脱离出来避免具体迭代器角色的更换给客户程序带来的修改迭代器模式抽象了具体迭代器角色使得客户程序更具一般性和重用性这被称为多态迭代。 在 Java Collection FrameWork中提供的具体迭代器角色是定义在容器角色中的内部类这样便保护了容器的封装。但是同时容器也提供了遍历算法接口并且你可以扩展自己的迭代器。大家考虑一个问题为什么一定要去实现 Iterable 这个接口呢 为什么不直接实现 Iterator接口呢 看一下 JDK 中的集合类比如 List一族或者Set一族都是实现了 Iterable 接口但并不直接实现 Iterator 接口。仔细想一下这么做是有道理的因为 Iterator接口的核心方法 next() 或者 hasNext() 是依赖于迭代器的当前迭代位置的。若 Collection 直接实现 Iterator 接口势必导致集合对象中包含当前迭代位置的数据(指针)。当集合在不同方法间被传递时由于当前迭代位置不可预置那么 next() 方法的结果会变成不可预知。除非再为 Iterator接口 添加一个 reset() 方法用来重置当前迭代位置。但即使这样Collection 也只能同时存在一个当前迭代位置(不能同时多次迭代同一个序列必须要等到当前次迭代完成并reset后才能再一次从头迭代)。 而选择实现 Iterable 接口则不然每次调用都会返回一个从头开始计数的迭代器(Iterator)因此多个迭代器间是互不干扰的。16、适配器模式 适配器模式将一个类的接口转换成客户期望的另一个接口让原本不兼容的接口可以合作无间。也就是说适配器模式用于实现新、老接口之间的转换与适配其魅力在于不改变原有接口却还能使用新接口的功能。适配器模式主要包含以下四个角色,其内涵分别为(1)Target 客户所期待的接口(2)Adaptee Adapter 所包装的对象即被适配的类(适配者)(3)Adapter 一个用于包装不兼容接口的对象的包装类通过包装一个需要适配的对象把原接口转换成目标接口(4)Client客户端适配器模式的三个特点适配器对象实现原有接口适配器对象组合一个实现新接口的对象(这个对象也可以不实现一个接口只是一个单纯的对象)对适配器原有接口方法的调用被委托给新接口的实例的特定方法。1、模板方法模式 模板方法模式是一种基于继承的代码复用技术是一种类行为型模式其核心在于定义一个操作中算法的框架而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。18、策略模式 策略模式属于对象的行为模式其用意是针对一组算法将每一个算法封装到具有共同接口的独立的类中从而使得它们可以相互替换核心思想是面向接口编程。 策略模式的经典应用包括Spring的PlatfromTransactionManagerJDK 排序策略 (不同的Comparator)等其优点包括(1)算法可以自由切换避免使用多重条件判断(2)扩展性良好。 策略模式与模板方法的区别 对于策略模式而言一个“策略”是一个整体的(完整的)算法算法是可以被整体替换的而模板方法只能被替换其中的特定点算法流程是固定不可变的。在思想和意图上看模板方法更加强调①定义一条线(算法流程)线上的多个点是可以变化的(具体实现在子类中完成)线上的多个点一定是会被执行的并且一定是按照特定流程被执行的。②算法流程是唯一的入口,对于点的访问是受限的。19、Java 自动装箱、拆箱机制Java为每种基本数据类型都提供了对应的包装器类型。所谓自动装箱机制就是自动将基本数据类型转换为包装器类型而自动拆箱机制就是自动将包装器类型转换为基本数据类型。在JDK中装箱过程是通过调用包装器的valueOf方法实现的而拆箱过程是通过调用包装器的 xxxValue方法实现的(xxx代表对应的基本数据类型)。但是(1)Integer、Short、Byte、Character、Long 这几个类的valueOf方法的实现是类似的共享[-128,127](2)Double、Float的valueOf方法的实现是类似的无限不可列举不共享(3)Boolean的valueOf方法的实现不同于以上的整型和浮点型只有两个值有限可列举共享 什么时候装箱/拆箱 至于什么时候装箱什么时候拆箱主要取决于在当前场景下你需要的是引用类型还是原生类型。(例如使用equals方法时传进来原生类型的值)若需要的是原生类型但传进来的值是引用类型则自动拆箱(例如使用运算符进行运算时操作数是包装类型)。20、内部类 内部类指的是在一个类的内部所定义的类类名不需要和源文件名相同。在Java中内部类是一个编译时的概念一旦编译成功内部类和外部类就会成为两个完全不同的类共有四种类型(1)成员内部类成员内部类是外围类的一个成员是依附于外围类的所以只有先创建了外围类对象才能够创建内部类对象。也正是由于这个原因成员内部类也不能含有 static 的变量和方法(2)静态内部类静态内部类就是修饰为static的内部类该内部类对象不依赖于外部类对象就是说我们可以直接创建内部类对象但其只可以直接访问外部类的所有静态成员和静态方法(3)局部内部类局部内部类和成员内部类一样被编译只是它的作用域发生了改变它只能在该方法和属性中被使用出了该方法和属性就会失效(4)匿名内部类定义匿名内部类的前提是内部类必须要继承一个类或者实现接口格式为 new 父类或者接口(){定义子类的内容(如函数等)}。也就是说匿名内部类最终提供给我们的是一个匿名子类的对象。20.1内部类的作用(1)间接实现多重继承,例如(2)内部类还可以很好的实现隐藏(一般非内部类,是不允许有private与protected权限的),但内部类可以。 21、equals hashCode (1) 用于判断两个对象是否为同一个对象或者两基本类型的值是否相等(2)equals 用于判断两个对象内容是否相同(3)hashCode是一个对象的消息摘要函数一种压缩映射其一般与equals()方法同时重写若不重写hashCode方法默认使用Object类的hashCode方法该方法是一个本地方法由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数。21.1 equals与hashCode的区别(1)一般来讲equals 这个方法是给用户调用的而 hashcode 方法一般用户不会去调用(2)当一个对象类型作为集合对象的元素时那么这个对象应该拥有自己的equals()和hashCode()设计而且要遵守前面所说的几个原则。21.2 在HashMap中使用可变对象作为Key带来的问题HashMap用Key的哈希值来存储和查找键值对如果HashMap Key的哈希值在存储键值对后发生改变那么Map可能再也查找不到这个Entry了。也就是说在HashMap中可变对象作为Key会造成数据丢失。因此(1)在HashMap中尽量使用不可变对象作为Key比如使用String、Integer等不可变类型用作Key是非常明智的或者使用自己定义的不可变类。(2)如果可变对象在HashMap中被用作键那就要小心在改变对象状态的时候不要改变它的哈希值了例如可以只根据对象的标识属性生成HashCode。21.3 重新equals但不重写HashCode会出现的问题 在使用Set时若向其加入两个相同(equals返回为true)的对象由于hashCode函数没有进行重写那么这两个对象的hashCode值必然不同它们很有可能被分散到不同的桶中容易造成重复对象的存在。22、什么是不可变对象一个不可变对象应该满足以下几个条件(1)基本类型变量的值不可变(2)引用类型变量不能指向其他对象(3)引用类型所指向的对象的状态不可变(4)除了构造函数之外不应该有其它任何函数(至少是任何public函数)修改任何成员变量(5)任何使成员变量获得新值的函数都应该将新的值保存在新的对象中而保持原来的对象不被修改。23、Java的序列化/反序列化机制 使用Serializable序列化/反序列化。将实现了Serializable接口的对象转换成一个字节序列并能够在以后将这个字节序列完全恢复为原来的对象序列化可以弥补不同操作系统之间的差异。其中需要注意以下几点(1)需要序列化的对象必须实现Serializable接口(2)只有非静态字段和非transient字段进行序列化与字段的可见性无关(3)序列化/反序列化的实质上操纵的是一个对象图 此外Java中常用到的序列化方法还有 XML、JSON 等此不赘述。24、Path及ClassPath环境变量 (1)Path系统用来指定可执行文件的完整路径。当在CMD中执行命令时如果执行的可执行文件不在当前目录下那么系统就会依次搜索PATH中设置的路径。如果在PATH中设置了JDK的安装目录(如在PATH中添加如下的路径——D:ProgramFilesJavajdk1.8.0bin;D:ProgramFilesJavajdk1.8.0jrebin;)那么就可以在CMD中直接使用java、javac等命令而不必在CMD中切换到JDK的安装目录下运行该命令。(2)ClassPath是指定程序中所使用的类文件所在的位置。ClassPath环境变量中点(“.”)的含义是在当前路径下搜索Java类。如果编译器按照CLASSPATH指定的路径找不到所需要的类则会提示“*类找不到”这样的错误。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912605.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!