邢台做网站推广价格,西湖区住房和城乡建设局网站,做搬家广告哪家网站有优,博物馆网站制作JavaEE面试题整理 一、Java基础篇二、JVM篇三、Tomcat篇四、MyBatis篇五、Spring篇六、SpringMVC面试题整理七、Redis篇八、Mongodb篇九、MQ篇十、Shiro篇十一、搜索引擎篇十二、Nginx篇十三、SpringBoot篇十四、Dubbo篇
一、Java基础篇
1、JAVA中的几种基本数据类型是什么各自占用多少字节浮点类型float4字节、double8个字整数类型byte1字节、short2字节、int4字节、long8字节字符类型char2字节布尔类型boolean4字节2、String类能被继承吗为什么不可以因为String类有final修饰符而final修饰的类是不能被继承的实现细节不允许改变。3、 StringStringbufferStringBuilder的区别String不可变字符串StringBuffer可变字符串、效率低、线程安全StringBuilder可变字符序列、效率高、线程不安全String可以空赋值后者不行报错如果要操作少量的数据用 String多线程操作字符串缓冲区下操作大量数据 StringBuffer单线程操作字符串缓冲区下操作大量数据 StringBuilder推荐使用。4、java中和equals和hashCode的区别是运算符用于比较两个变量是否相等。一般用于基本类型的比较equals是Objec类的方法用于比较两个对象是否相等默认Object类的equals方法是比较两个对象的地址跟的结果一样。hashCode也是Object类的一个方法返回一个离散的int型整数。在集合类操作中使用为了提高查询速度。HashMapHashSet等5、int与integer的区别Integer是int的包装类int则是java的一种基本数据类型Integer变量必须实例化后才能使用而int变量不需要Integer实际是对象的引用当new一个Integer时实际上是生成一个指针指向此对象而int则是直接存储数据值Integer的默认值是nullint的默认值是06、什么是内部类内部类的作用含义可以将一个类的定义放在另一个类的定义的内部这就是内部类。内部类的作用内部类可以很好的实现隐藏内部类拥有外围类的所有元素的访问权限可以实现多重继承(不要误解这个是在一个外部类里面多个内部类继承不同基类达到一个外部类拥有多个基类的方法)可以避免接口中的方法和同一个类中的方法同名的问题7、抽象类和接口区别抽象类和接口都不能直接实例化如果要实例化抽象类变量必须指向实现所有抽象方法的子类对象接口变量必须指向实现所有接口方法的类对象。抽象类要被子类继承接口要被类实现。接口只能做方法申明抽象类中可以做方法申明也可以做方法实现接口里定义的变量只能是公共的静态的常量抽象类中的变量是普通变量。抽象类里的抽象方法必须全部被子类所实现如果子类不能全部实现父类抽象方法那么该子类只能是抽象类。同样一个实现接口的时候如不能全部实现接口方法那么该类也只能为抽象类。抽象方法只能申明不能实现接口是设计的结果 抽象类是重构的结果抽象类里可以没有抽象方法如果一个类里有抽象方法那么这个类只能是抽象类抽象方法要被实现所以不能是静态的也不能是私有的。接口可继承接口并可多继承接口但类只能单根继承。8、进程和线程的区别进程是资源的分配和调度的一个独立单元而线程是CPU调度的基本单元同一个进程中可以包括多个线程并且线程共享整个进程的资源寄存器、堆栈、上下文一个进行至少包括一个线程。进程的创建调用fork或者vfork而线程的创建调用pthread_create进程结束后它拥有的所有线程都将销毁而线程的结束不会影响同个进程中的其他线程的结束线程是轻两级的进程它的创建和销毁所需要的时间比进程小很多所有操作系统中的执行功能都是创建线程去完成的线程中执行时一般都要进行同步和互斥因为他们共享同一进程的所有资源线程有自己的私有属性TCB线程id寄存器、硬件上下文而进程也有自己的私有属性进程控制块PCB这些私有属性是不被共享的用来标示一个进程或一个线程的标志9、泛型通配符extends与super的区别? extends T 只能用于方法返回告诉编译器此返参的类型的最小继承边界为TT和T的父类都能接收但是入参类型无法确定只能接受null的传入? super T只能用于限定方法入参告诉编译器入参只能是T或其子类型而返参只能用Object类接收? 既不能用于入参也不能用于返参10、error和exception有什么区别error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况 exception 表示一种设计或实现问题。也就是说它表示如果程序运行正常从不会发生的情况。11、GC是什么? 为什么要有GCGC是垃圾收集的意思Gabage Collection,内存处理是编程人员容易出现问题的地方忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的Java语言没有提供释放已分配内存的显示操作方法。12、运行时异常与一般异常有何异同异常表示程序运行过程中可能出现的非正常状态运行时异常表示虚拟机的通常操作中可能遇到的异常是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常但是并不要求必须声明抛出未被捕获的运行时异常。13、描述一下JVM加载class文件的原理机制?JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。14、和的区别是位运算符表示按位与运算是逻辑运算符表示逻辑与and15.什么是值传递和引用传递对象被值传递意味着传递了对象的一个副本。因此就算是改变了对象副本也不会影响源对象的值。对象被引用传递意味着传递的并不是实际的对象而是对象的引用。因此外部对引用对象所做的改变会反映到所有的对象上。二、JVM篇1、JVM内存模型都有哪些程序计数器java虚拟机栈本地方法栈java堆方法区运行时常量池直接内存2、讲讲什么情况下会出现内存溢出内存泄漏内存泄漏memory leak :是指程序在申请内存后无法释放已申请的内存空间一次内存泄漏似乎不会有大的影响但内存泄漏堆积后的后果就是内存溢出。内存溢出 out of memory :指程序申请内存时没有足够的内存供申请者使用或者说给了你一块存储int类型数据的存储空间但是你却存储long类型的数据那么结果就是内存不够用此时就会报错OOM,即所谓的内存溢出。Java内存泄漏的根本原因是什么呢长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏尽管短生命周期对象已经不再需要但是因为长生命周期持有它的引用而导致不能被回收这就是Java中内存泄漏的发生场景。3、说说Java线程栈Java线程栈从线程创建时存在并且是私有的。线程栈用户存储栈帧栈帧用于存储局部变量、中间运算结果。所以局部是不存在并发的问题因为每个栈是私有的。虚拟机只会对Java栈进行二种操作以栈帧为单位的压栈和出栈。对于执行引擎来说在活动线程中只有位于栈顶的栈帧才是有效的称为当前栈帧Current Stack Frame与这个栈帧相关联的方法称为当前方法Current Method。执行引擎运行的所有字节码指令都只针对当前栈帧进行操作。4、类的实例化顺序首先是父类的静态变量和静态代码块看两者的书写顺序第二执行子类的静态变量和静态代码块看两者的书写顺序第三执行父类的成员变量赋值第四执行父类类的构造代码块第五执行父类的构造方法执行子类的构造代码块第七执行子类的构造方法总结也就是说虽然客户端代码是new 的构造方法但是构造方法确实是在整个实例创建中的最后一个调用。切记切记先是父类再是子类先是类静态变量和静态代码块再是对象的成员变量和构造代码块–》构造方法。记住构造方法最后调用成员变量优先构造代码块优先构造方法5、java类加载机制加载通过类的全限定名获取类的二进制字节流将字节流代表的静态存储结构转化为方法区的运行时数据结构。在内存生成这个类的class对象连接包括三步验证准备解析验证保证class文件的字节流中包含的信息符合当前虚拟机的要求且不危害虚拟机自身安全准备正式为类变量分配内存并设置类变量初始值解析将常量池的符号引用替换为直接引用初始化根据程序员的意愿初始化类变量6、一个对象的内存划分是怎样的可分为3块区域对象头实例数据对齐填充对象头由Mark world和类型指针组成mark World包括hash码GC分代年龄锁状态标志等。类型指针来确定这个对象是哪个类的实例实例数据是对象存储的真正的有效信息hostspot虚拟机要求对象的大小必须是8字节的整数倍7、内存泄漏和内存溢出的区别内存泄漏分配出去的内存无法回收可达却无用的对象无法被gc回收内存溢出程序要求的内存超出了系统能分配的范围如栈满进栈栈空出栈8.垃圾收集算法有哪些标记-清除算法首先标记出所有的对象标记完成后统一回收1效率问题标记和清除两个过程效率都不高2空间问题产生碎片复制算法将内存划分为一块较大的Eden空间80%和两块较小的Survivor空间10%每次使用Eden和其中的一块Survivor当回收时将两者中存活的对象一次性复制到另一块Survivor并清空刚才用到的空间如果这块Survivor不够则启用分配担保机制将多处的对象存储再老年代标记-整理算法首先标记出所有的对象回收时让存活的对象都向一端移动直接清理端边界外的内存分代收集算法将java堆分为新生代和老年代垃圾回收时新生代每次都有大量对象死去所以采用复制算法老年代存活的对象较多使用标记-清除或标记-整理9、常见的垃圾收集器Serial收集器单线程收集器ParNew收集器新生代收集器Serial收集器的多线程版本Parallel Scavenge收集器新生代收集器使用复制算法。是用来实现最大吞吐量代码运行时间/代码运行时间垃圾收集的时间Serial Old收集器Serial收集器的老年代版本Parallel Old收集器ParNew收集器的老年代版本(一般使用Parallel Scavenge Parallel Old)CMS收集器是一种以获取最短停顿时间为目标的收集器。分为4个步骤初始标记并发标记重新标记并发清除采用 标记-清除算法1初始标记标记GC Root能直接关联到的对象 stop the world2并发标记进行Gc Root Tracing的过程3重新标记修正并发标记期间用户线程序继续工作而导致的标记的变动stop the world4并发清除清除未被标记的对象G1收集器可以独立的管理整个gc堆。步骤初始标记并发标记最终标记筛选回收首先对各个Region价值排序从整体上看是标记-整理算法 从局部上看两个region采用复制算法10、什么情况下对象进入老年代大对象直接进入老年代需要大量连续空间的对象。常见的大对象就是很长的字符串和数组长期存活的对象进入老年代。每个对象有一个年龄计数器。每熬过一次moinor gc年龄就增加一岁。当年龄增加到一定程度默认为15就会晋升到老年代通过MaxTenuringThreshold设置。动态年龄判断如果survivor空间某个年龄对象的大小大于survivor空间的一半年龄大于或等于的直接进入老年代空间分配担保复制算法中survivor中无法容纳的对象将通过分配担保机制直接进入老年代11、什么时候进行GC程序员不能控制具体的时间Eden区满了会触发minor GC老年代满或调用system.gc执行Full GC三、Tomcat篇1、Tomcat 有哪几种Connector 运行模式(优化)bio传统的Java I/O操作同步且阻塞IO。nioJDK1.4开始支持同步阻塞或同步非阻塞IO。aio(nio.2)JDK7开始支持异步非阻塞IO。aprTomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作从而大大地 提高Tomcat对静态文件的处理性能。2、Tomcat容器是如何创建servlet类实例用到了什么原理当容器启动时会读取在webapps目录下所有的web应用中的web.xml文件然后对xml文件进行解析并读取servlet注册信息。然后将每个应用中注册的servlet类都进行加载并通过反射的方式实例化。有时候也是在第一次请求时实例化在servlet注册时加上如果为正数则在一开始就实例化如果不写或为负数则第一次请求实例化。3、Tomcat内存调优内存方式的设置是在catalina.sh中调整一下JAVA_OPTS变量即可因为后面的启动参数会把JAVA_OPTS作为JVM的启动参数来处理。具体设置如下JAVA_OPTS$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio4 -XX:SurvivorRatio4其各项参数如下-Xmx3550m设置JVM最大可用内存为3550M。 -Xms3550m设置JVM促使内存为3550m。此值可以设置与-Xmx相同以避免每次垃圾回收完成后JVM重新分配内存。 -Xmn2g设置年轻代大小为2G。整个堆大小年轻代大小 年老代大小 持久代大小。持久代一般固定大小为64m所以增大年轻代后将会减小年老代大小。此值对系统性能影响较大Sun官方推荐配置为整个堆的3/8。 -Xss128k设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的不能无限生成经验值在3000~5000左右。 -XX:NewRatio4:设置年轻代包括Eden和两个Survivor区与年老代的比值除去持久代。设置为4则年轻代与年老代所占比值为14年轻代占整个堆栈的1/5 -XX:SurvivorRatio4设置年轻代中Eden区与Survivor区的大小比值。设置为4则两个Survivor区与一个Eden区的比值为2:4一个Survivor区占整个年轻代的1/6 -XX:MaxPermSize16m:设置持久代大小为16m。 -XX:MaxTenuringThreshold0设置垃圾最大年龄。如果设置为0的话则年轻代对象不经过Survivor区直接进入年老代。对于年老代比4、垃圾回收策略调优垃圾回收的设置也是在catalina.sh中调整JAVA_OPTS变量。具体设置如下JAVA_OPTS$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k -XX:UseParallelGC -XX:MaxGCPauseMillis100具体的垃圾回收策略及相应策略的各项参数如下串行收集器JDK1.5以前主要的回收方式-XX:UseSerialGC:设置串行收集器并行收集器吞吐量优先示例java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:UseParallelGC -XX:MaxGCPauseMillis100 -XX:UseParallelGC选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下年轻代使用并发收集而年老代仍旧使用串行收集。 -XX:ParallelGCThreads20配置并行收集器的线程数即同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。 -XX:UseParallelOldGC配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集 -XX:MaxGCPauseMillis100:设置每次年轻代垃圾回收的最长时间如果无法满足此时间JVM会自动调整年轻代大小以满足此值。 -XX:UseAdaptiveSizePolicy设置此选项后并行收集器会自动选择年轻代区大小和相应的Survivor区比例以达到目标系统规定的最低相应时间或者收集频率等此值建议使用并行收集器时一直打开。 并发收集器响应时间优先 示例java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:UseConcMarkSweepGC -XX:UseConcMarkSweepGC设置年老代为并发收集。测试中配置这个以后-XX:NewRatio4的配置失效了原因不明。所以此时年轻代大小最好用-Xmn设置。 -XX:UseParNewGC: 设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上JVM会根据系统配置自行设置所以无需再设置此值。 -XX:CMSFullGCsBeforeCompaction由于并发收集器不对内存空间进行压缩、整理所以运行一段时间以后会产生“碎片”使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。 -XX:UseCMSCompactAtFullCollection打开对年老代的压缩。可能会影响性能但是可以消除碎片5、添加JMS远程监控对于部署在局域网内其它机器上的Tomcat可以打开JMX监控端口局域网其它机器就可以通过这个端口查看一些常用的参数但一些比较复杂的功能不支持同样是在JVM启动参数中配置即可配置如下-Dcom.sun.management.jmxremote.sslfalse -Dcom.sun.management.jmxremote.authenticatefalse -Djava.rmi.server.hostname192.168.71.38 设置JVM的JMS监控监听的IP地址主要是为了防止错误的监听成127.0.0.1这个内网地址 -Dcom.sun.management.jmxremote.port1090 设置JVM的JMS监控的端口 -Dcom.sun.management.jmxremote.sslfalse 设置JVM的JMS监控不实用SSL -Dcom.sun.management.jmxremote.authenticatefalse 设置JVM的JMS监控不需要认证6、请解释Tomcat中使用的连接器是什么?在Tomcat中使用了两种类型的连接器HTTP连接器:它有许多可以更改的属性以确定它的工作方式和访问功能如重定向和代理转发AJP连接器:它以与HTTP连接器相同的方式工作但是他们使用的是HTTP的AJP协议。AJP连接器通常通过插件技术mod_jk在Tomcat中实现7、解释什么是Tomcat Valve?Tomcat Valve——Tomcat 4引入的新技术它允许您将Java类的实例链接到一个特定的Catalina容器。8、说明Tomcat配置了多少个Valve?Tomcat配置了四种类型的Valve访问日志远程地址过滤远程主机过滤器客户请求记录器9、请说明NAT协议的目的是什么?NAT协议的目的是将私有IP地址从公共IP地址隐藏起来并给组织提供一定的安全性。四、MyBatis篇1、Mybaits的优点基于SQL语句编程相当灵活不会对应用程序或者数据库的现有设计造成任何影响SQL写在XML里解除sql与程序代码的耦合便于统一管理提供XML标签支持编写动态SQL语句并可重用。与JDBC相比减少了50%以上的代码量消除了JDBC大量冗余的代码不需要手动开关连接很好的与各种数据库兼容因为MyBatis使用JDBC来连接数据库所以只要JDBC支持的数据库MyBatis都支持。能够与Spring很好的集成提供映射标签支持对象与数据库的ORM字段关系映射提供对象关系映射标签支持对象关系组件维护。2、MyBatis框架的缺点SQL语句的编写工作量较大尤其当字段多、关联表多时对开发人员编写SQL语句的功底有一定要求。SQL语句依赖于数据库导致数据库移植性差不能随意更换数据库。3、MyBatis与Hibernate有哪些不同Mybatis和hibernate不同它不完全是一个ORM框架因为MyBatis需要程序员自己编写Sql语句。Mybatis直接编写原生态sql可以严格控制sql执行性能灵活度高非常适合对关系数据模型要求不高的软件开发因为这类软件需求变化频繁一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件工作量大。Hibernate对象/关系映射能力强数据库无关性好对于关系模型要求高的软件如果用hibernate开发可以节省很多代码提高效率。4、#{}和${}的区别是什么#{}是预编译处理KaTeX parse error: Expected EOF, got # at position 23: …换。 Mybatis在处理#̲{}时会将sql中的#{}替…{}时就是把${}替换成变量的值。使用#{}可以有效的防止SQL注入提高系统安全性。5、Mybatis是如何进行分页的分页插件的原理是什么Mybatis使用RowBounds对象进行分页它是针对ResultSet结果集执行的内存分页而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能也可以使用分页插件来完成物理分页。分页插件的基本原理是使用Mybatis提供的插件接口实现自定义插件在插件的拦截方法内拦截待执行的sql然后重写sql根据dialect方言添加对应的物理分页语句和物理分页参数。6、Xml映射文件中除了常见的select|insert|updae|delete标签之外还有哪些标签、、、、加上动态sql的9个标签其中为sql片段标签通过标签引入sql片段为不支持自增的主键生成策略标签。7、最佳实践中通常一个Xml映射文件都会写一个Dao接口与之对应请问这个Dao接口的工作原理是什么Dao接口里的方法参数不同时方法能重载吗Dao接口就是人们常说的Mapper接口接口的全限名就是映射文件中的namespace的值接口的方法名就是映射文件中MappedStatement的id值接口方法内的参数就是传递给sql的参数。Mapper接口是没有实现类的当调用接口方法时接口全限名方法名拼接字符串作为key值可唯一定位一个MappedStatement举例com.mybatis3.mappers.StudentDao.findStudentById可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id findStudentById的MappedStatement。在Mybatis中每一个、、、标签都会被解析为一个MappedStatement对象。Dao接口里的方法是不能重载的因为是全限名方法名的保存和寻找策略。Dao接口的工作原理是JDK动态代理Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象代理对象proxy会拦截接口方法转而执行MappedStatement所代表的sql然后将sql执行结果返回。8、Mybatis动态sql是做什么的都有哪些动态sql能简述一下动态sql的执行原理不Mybatis动态sql可以让我们在Xml映射文件内以标签的形式编写动态sql完成逻辑判断和动态拼接sql的功能Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。其执行原理为使用OGNL从sql参数对象中计算表达式的值根据表达式的值动态拼接sql以此来完成动态sql的功能。9、Mybatis是如何将sql执行结果封装为目标对象并返回的都有哪些映射形式第一种是使用标签逐一定义列名和对象属性名之间的映射关系。第二种是使用sql列的别名功能将列别名书写为对象属性名比如T_NAME AS NAME对象属性名一般是name小写但是列名不区分大小写Mybatis会忽略列名大小写智能找到与之对应对象属性名你甚至可以写成T_NAME AS NaMeMybatis一样可以正常工作。有了列名与属性名的映射关系后Mybatis通过反射创建对象同时使用反射给对象的属性逐一赋值并返回那些找不到映射关系的属性是无法完成赋值的。10、Mybatis是否支持延迟加载如果支持它的实现原理是什么Mybatis仅支持association关联对象和collection关联集合对象的延迟加载association指的就是一对一collection指的就是一对多查询。在Mybatis配置文件中可以配置是否启用延迟加载lazyLoadingEnabledtrue|false。它的原理是使用CGLIB创建目标对象的代理对象当调用目标方法时进入拦截器方法比如调用a.getB().getName()拦截器invoke()方法发现a.getB()是null值那么就会单独发送事先保存好的查询关联B对象的sql把B查询上来然后调用a.setB(b)于是a的对象b属性就有值了接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。当然了不光是Mybatis几乎所有的包括Hibernate支持延迟加载的原理都是一样的。11、Mybatis的Xml映射文件中不同的Xml映射文件id是否可以重复不同的Xml映射文件如果配置了namespace那么id可以重复如果没有配置namespace那么id不能重复毕竟namespace不是必须的只是最佳实践而已。原因就是namespaceid是作为MapString, MappedStatement的key使用的如果没有namespace就剩下id那么id重复会导致数据互相覆盖。有了namespace自然id就可以重复namespace不同namespaceid自然也就不同。12、Mybatis中如何执行批处理使用BatchExecutor完成批处理。13、Mybatis都有哪些Executor执行器它们之间的区别是什么Mybatis有三种基本的Executor执行器SimpleExecutor、ReuseExecutor、BatchExecutor。SimpleExecutor每执行一次update或select就开启一个Statement对象用完立刻关闭Statement对象。ReuseExecutor执行update或select以sql作为key查找Statement对象存在就使用不存在就创建用完后不关闭Statement对象而是放置于MapString, Statement内供下一次使用。简言之就是重复使用Statement对象。BatchExecutor执行update没有selectJDBC批处理不支持select将所有sql都添加到批处理中addBatch()等待统一执行executeBatch()它缓存了多个Statement对象每个Statement对象都是addBatch()完毕后等待逐一执行executeBatch()批处理。与JDBC批处理相同。作用范围Executor的这些特点都严格限制在SqlSession生命周期范围内。14、Mybatis中如何指定使用哪一种Executor执行器在Mybatis配置文件中可以指定默认的ExecutorType执行器类型也可以手动给DefaultSqlSessionFactory的创建SqlSession的方法传递ExecutorType类型参数。15、Mybatis是否可以映射Enum枚举类Mybatis可以映射枚举类不单可以映射枚举类Mybatis可以映射任何对象到表的一列上。映射方式为自定义一个TypeHandler实现TypeHandler的setParameter()和getResult()接口方法。TypeHandler有两个作用一是完成从javaType至jdbcType的转换二是完成jdbcType至javaType的转换体现为setParameter()和getResult()两个方法分别代表设置sql问号占位符参数和获取列查询结果。16、Mybatis映射文件中如果A标签通过include引用了B标签的内容请问B标签能否定义在A标签的后面还是说必须定义在A标签的前面虽然Mybatis解析Xml映射文件是按照顺序解析的但是被引用的B标签依然可以定义在任何地方Mybatis都可以正确识别。原理是Mybatis解析A标签发现A标签引用了B标签但是B标签尚未解析到尚不存在此时Mybatis会将A标签标记为未解析状态然后继续解析余下的标签包含B标签待所有标签解析完毕Mybatis会重新解析那些被标记为未解析的标签此时再解析A标签时B标签已经存在A标签也就可以正常解析完成了。17、简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系Mybatis将所有Xml配置信息都封装到All-In-One重量级对象Configuration内部。在Xml映射文件中标签会被解析为ParameterMap对象其每个子元素会被解析为ParameterMapping对象。标签会被解析为ResultMap对象其每个子元素会被解析为ResultMapping对象。每一个、、、标签均会被解析为MappedStatement对象标签内的sql会被解析为BoundSql对象。18、为什么说Mybatis是半自动ORM映射工具它与全自动的区别在哪里Hibernate属于全自动ORM映射工具使用Hibernate查询关联对象或者关联集合对象时可以根据对象关系模型直接获取所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时需要手动编写sql来完成所以称之为半自动ORM映射工具。五、Spring篇1. 使用Spring框架的好处是什么轻量Spring 是轻量的基本的版本大约2MB。控制反转Spring通过控制反转实现了松散耦合对象们给出它们的依赖而不是创建或查找依赖的对象们。面向切面的编程(AOP)Spring支持面向切面的编程并且把应用业务逻辑和系统服务分开。容器Spring 包含并管理应用中对象的生命周期和配置。MVC框架Spring的WEB框架是个精心设计的框架是Web框架的一个很好的替代品。事务管理Spring 提供一个持续的事务管理接口可以扩展到上至本地事务下至全局事务JTA。异常处理Spring 提供方便的API把具体技术相关的异常比如由JDBCHibernate or JDO抛出的转化为一致的unchecked 异常。2. Spring由哪些模块组成以下是Spring 框架的基本模块Core moduleBean moduleContext moduleExpression Language moduleJDBC moduleORM moduleOXM moduleJava Messaging Service(JMS) moduleTransaction moduleWeb moduleWeb-Servlet moduleWeb-Struts moduleWeb-Portlet module3、BeanFactory和ApplicationContext有什么区别BeanFactory和ApplicationContext是Spring的两大核心接口都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。1BeanFactory是Spring里面最底层的接口包含了各种Bean的定义读取bean配置文档管理bean的加载、实例化控制bean的生命周期维护bean之间的依赖关系。ApplicationContext接口作为BeanFactory的派生除了提供BeanFactory所具有的功能外还提供了更完整的框架功能继承MessageSource因此支持国际化。统一的资源文件访问方式。提供在监听器中注册bean的事件。同时加载多个配置文件。载入多个有继承关系上下文 使得每一个上下文都专注于一个特定的层次比如应用的web层。2BeanFactroy采用的是延迟加载形式来注入Bean的即只有在使用到某个Bean时(调用getBean())才对该Bean进行加载实例化。这样我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入BeanFacotry加载后直至第一次使用调用getBean方法才会抛出异常。ApplicationContext它是在容器启动时一次性创建了所有的Bean。这样在容器启动时我们就可以发现Spring中存在的配置错误这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean通过预载入单实例bean ,确保当你需要的时候你就不用等待因为它们已经创建好了。相对于基本的BeanFactoryApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时程序启动较慢。3BeanFactory通常以编程的方式被创建ApplicationContext还能以声明的方式创建如使用ContextLoader。4BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用但两者之间的区别是BeanFactory需要手动注册而ApplicationContext则是自动注册。4、 解释Spring支持的几种bean的作用域。Spring容器中的bean可以分为5个范围singleton默认每个容器中只有一个bean的实例单例的模式由BeanFactory自身来维护。prototype为每一个bean请求提供一个实例。request为每一个网络请求创建一个实例在请求完成以后bean会失效并被垃圾回收器回收。session与request范围类似确保每个session中有一个bean的实例在session过期后bean会随之失效。global-session全局作用域global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。5、Spring框架中的单例Beans是线程安全的么Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上大部分的Spring bean并没有可变的状态(比如Serview类和DAO类)所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话比如 View Model 对象就需要自行保证线程安全。最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。6、Spring 框架中都用到了哪些设计模式1工厂模式BeanFactory就是简单工厂模式的体现用来创建对象的实例2单例模式Bean默认为单例模式。3代理模式Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术4模板模式用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。5观察者模式定义对象键一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都会得到通知被制动更新如Spring中listener的实现–ApplicationListener。7、解释一下Spring AOP里面的几个名词1切面Aspect被抽取的公共模块可能会横切多个对象。 在Spring AOP中切面可以使用通用类基于模式的风格 或者在普通类中以 AspectJ 注解来实现。2连接点Join point指方法在Spring AOP中一个连接点 总是 代表一个方法的执行。3通知Advice在切面的某个特定的连接点Join point上执行的动作。通知有各种类型其中包括“around”、“before”和“after”等通知。许多AOP框架包括Spring都是以拦截器做通知模型 并维护一个以连接点为中心的拦截器链。4切入点Pointcut切入点是指 我们要对哪些Join point进行拦截的定义。通过切入点表达式指定拦截的方法比如指定拦截add*、search*。5引入Introduction也被称为内部类型声明inter-type declaration。声明额外的方法或者某个类型的字段。Spring允许引入新的接口以及一个对应的实现到任何被代理的对象。例如你可以使用一个引入来使bean实现 IsModified 接口以便简化缓存机制。6目标对象Target Object 被一个或者多个切面aspect所通知advise的对象。也有人把它叫做 被通知adviced 对象。 既然Spring AOP是通过运行时代理实现的这个对象永远是一个 被代理proxied 对象。7织入Weaving指把增强应用到目标对象来创建新的代理对象的过程。Spring是在运行时完成织入。切入点pointcut和连接点join point匹配的概念是AOP的关键这使得AOP不同于其它仅仅提供拦截功能的旧技术。 切入点使得定位通知advice可独立于OO层次。 例如一个提供声明式事务管理的around通知可以被应用到一组横跨多个对象中的方法上例如服务层的所有业务操作。8、Spring中有哪些不同的通知类型通知(advice)是你在你的程序中想要应用在其他模块中的横切关注点的实现。Advice主要有以下5种类型前置通知(Before Advice): 在连接点之前执行的Advice不过除非它抛出异常否则没有能力中断执行流。使用Before注解使用这个Advice。返回之后通知(After Retuning Advice): 在连接点正常结束之后执行的Advice。例如如果一个方法没有抛出异常正常返回。通过AfterReturning关注使用它。抛出异常后执行通知(After Throwing Advice): 如果一个方法通过抛出异常来退出的话这个Advice就会被执行。通用AfterThrowing注解来使用。后置通知(After Advice): 无论连接点是通过什么方式退出的(正常返回或者抛出异常)都会执行在结束后执行这些Advice。通过After注解使用。围绕通知(Around Advice): 围绕连接点执行的Advice就你一个方法调用。这是最强大的Advice。通过Around注解使用。9、 什么是Spring的依赖注入依赖注入是IOC的一个方面是个通常的概念它有多种解释。这概念是说你不用创建对象而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务但是要在配置文件里描述哪些组件需要哪些服务之后一个容器IOC容器负责把他们组装起来。10、有哪些不同类型的IOC依赖注入方式构造器依赖注入构造器依赖注入通过容器触发一个类的构造器来实现的该类有一系列参数每个参数代表一个对其他类的依赖。Setter方法注入Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后调用该bean的setter方法即实现了基于setter的依赖注入。11、哪种依赖注入方式你建议使用构造器注入还是 Setter方法注入两种依赖方式都可以使用构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖setter方法实现可选依赖。12、 如何给Spring 容器提供配置元数据?这里有三种重要的方法给Spring 容器提供配置元数据。XML配置文件。基于注解的配置。基于java的配置。六、SpringMVC面试题整理SpringMVC相关https://blog.csdn.net/a745233700/article/details/80963758七、Redis篇1、什么是Redis简述它的优缺点Redis本质上是一个Key-Value类型的内存数据库很像memcached整个数据库统统加载在内存当中进行操作定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作Redis的性能非常出色每秒可以处理超过 10万次读写操作是已知性能最快的Key-Value DB。Redis的出色之处不仅仅是性能Redis最大的魅力是支持保存多种数据结构此外单个value的最大限制是1GB不像 memcached只能保存1MB的数据因此Redis可以用来实现很多有用的功能。比方说用他的List来做FIFO双向链表实现一个轻量级的高性 能消息队列服务用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间因此也可以被当作一 个功能加强版的memcached来用。 Redis的主要缺点是数据库容量受到物理内存的限制不能用作海量数据的高性能读写因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。2、Redis支持哪几种数据类型String、List、Set、Sorted Set、hashes3、Redis有哪几种数据淘汰策略noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令大部分的写入指令但DEL和几个例外allkeys-lru: 尝试回收最少使用的键LRU使得新添加的数据有空间存放。volatile-lru: 尝试回收最少使用的键LRU但仅限于在过期集合的键,使得新添加的数据有空间存放。allkeys-random: 回收随机的键使得新添加的数据有空间存放。vlatile-random: 回收随机的键使得新添加的数据有空间存放但仅限于在过期集合的键。volatile-ttl: 回收在过期集合的键并且优先回收存活时间TTL较短的键,使得新添加的数据有空间存放。4、一个字符串类型的值能存储最大容量是多少512M5、为什么Redis需要把所有数据放到内存中Redis为了达到最快的读写速度将数据都读到内存中并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天redis将会越来越受欢迎。 如果设置了最大使用的内存则数据已有记录数达到内存限值后不能继续插入新值。6、Redis集群最大节点个数是多少16384个。7、Redis有哪些适合的场景会话缓存Session Cache最常用的一种使用Redis的情景是会话缓存session cache。用Redis缓存会话比其他存储如Memcached的优势在于Redis提供持久化。当维护一个不是严格要求一致性的缓存时如果用户的购物车信息全部丢失大部分人都会不高兴的现在他们还会这样吗幸运的是随着 Redis 这些年的改进很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。全页缓存FPC除基本的会话token之外Redis还提供很简便的FPC平台。回到一致性问题即使重启了Redis实例因为有磁盘的持久化用户也不会看到页面加载速度的下降这是一个极大改进类似PHP本地FPC。再次以Magento为例Magento提供一个插件来使用Redis作为全页缓存后端。此外对WordPress的用户来说Pantheon有一个非常好的插件 wp-redis这个插件能帮助你以最快速度加载你曾浏览过的页面。队列Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作就类似于本地程序语言如Python对 list 的 push/pop 操作。如果你快速的在Google中搜索“Redis queues”你马上就能找到大量的开源项目这些项目的目的就是利用Redis创建非常好的后端工具以满足各种队列需求。例如Celery有一个后台就是使用Redis作为broker你可以从这里去查看。排行榜/计数器Redis在内存中对数字进行递增或递减的操作实现的非常好。集合Set和有序集合Sorted Set也使得我们在执行这些操作的时候变的非常简单Redis只是正好提供了这两种数据结构。所以我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”我们只需要像下面一样执行即可当然这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数你需要这样执行ZRANGE user_scores 0 10 WITHSCORESAgora Games就是一个很好的例子用Ruby实现的它的排行榜就是使用Redis来存储数据的你可以在这里看到。发布/订阅最后但肯定不是最不重要的是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用还可作为基于发布/订阅的脚本触发器甚至用Redis的发布/订阅功能来建立聊天系统10、Redis集群方案应该怎么做都有哪些方案twemproxy大概概念是它类似于一个代理方式使用方法和普通redis无任何区别设置好它下属的多个redis实例后使用时在本需要连接redis的地方改为连接twemproxy它会以一个代理的身份接收请求并使用一致性hash算法将请求转接到具体redis将结果再返回twemproxy。使用方式简便(相对redis只需修改连接端口)对旧项目扩展的首选。 问题twemproxy自身单端口实例的压力使用一致性hash后对redis节点数量改变时候的计算值的改变数据无法自动移动到新的节点。codis目前用的最多的集群方案基本和twemproxy一致的效果但它支持在 节点数量改变情况下旧节点数据可恢复到新hash节点。redis cluster3.0自带的集群特点在于他的分布式算法不是一致性hash而是hash槽的概念以及自身支持节点设置从节点。具体看官方文档介绍。在业务代码层实现起几个毫无关联的redis实例在代码层对key 进行hash计算然后去对应的redis实例操作数据。 这种方式对hash层代码要求比较高考虑部分包括节点失效后的替代算法方案数据震荡后的自动脚本恢复实例的监控等等。11、Redis支持的Java客户端都有哪些官方推荐用哪个Redisson、Jedis、lettuce等等官方推荐使用Redisson。12、Jedis与Redisson对比有什么优缺点Jedis是Redis的Java实现的客户端其API提供了比较全面的Redis命令的支持Redisson实现了分布式和可扩展的Java数据结构和Jedis相比功能较为简单不支持字符串操作不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离从而让使用者能够将精力更集中地放在处理业务逻辑上。13、说说Redis哈希槽的概念Redis集群没有使用一致性hash,而是引入了哈希槽的概念Redis集群有16384个哈希槽每个key通过CRC16校验后对16384取模来决定放置哪个槽集群的每个节点负责一部分hash槽。14、Redis集群的主从复制模型是怎样的为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用所以集群使用了主从复制模型,每个节点都会有N-1个复制品.15、Redis集群会有写操作丢失吗为什么Redis并不能保证数据的强一致性这意味这在实际中集群在特定的条件下可能会丢失写操作。16、Redis中的管道有什么用一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发送到服务器而不用等待回复最后在一个步骤中读取该答复。这就是管道pipelining是一种几十年来广泛使用的技术。例如许多POP3协议已经实现支持这个功能大大加快了从服务器下载新邮件的过程。17、怎么理解Redis事务事务是一个单独的隔离操作事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中不会被其他客户端发送来的命令请求所打断。事务是一个原子操作事务中的命令要么全部被执行要么全部都不执行。18、Redis事务相关的命令有哪几个MULTI、EXEC、DISCARD、WATCH19、Redis如何做内存优化尽可能使用散列表hashes散列表是说散列表里面存储的数少使用的内存非常小所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的web系统中有一个用户对象不要为这个用户的名称姓氏邮箱密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面.详细请看https://blog.csdn.net/u010682330/article/details/81043419八、Mongodb篇1、使用mongodb的优点面向文件高性能高可用易扩展可分片对数据存储友好2、MongoDB支持存储过程吗如果支持的话怎么用MongoDB支持存储过程它是javascript写的保存在db.system.js表中。3、MySQL和MongoDB之间最基本的区别是什么关系型数据库与非关系型数据库的区别即数据存储结构的不同。4、如何理解MongoDB中的GridFS机制MongoDB为何使用GridFS来存储文件GridFS是一种将大型文件存储在MongoDB中的文件规范。使用GridFS可以将大文件分隔成多个小文档存放这样我们能够有效的保存大文档而且解决了BSON对象有限制的问题。5、如果一个分片Shard停止或很慢的时候发起一个查询会怎样如果一个分片停止了除非查询设置了“Partial”选项否则查询会返回一个错误。如果一个分片响应很慢MongoDB会等待它的响应。6、 Mongodb 的索引注意事项索引很有用,但是它也是有成本的——它占内存,让写入变慢mongoDB通常在一次查询里使用一个索引,所以多个字段的查询或者排序需要复合索引才能更加高效复合索引的顺序非常重要在生成环境构建索引往往开销很大,时间也不可以接受,在数据量庞大之前尽量进行查询优化和构建索引避免昂贵的查询,使用查询分析器记录那些开销很大的查询便于问题排查通过减少扫描文档数量来优化查询,使用explai对开销大的查询进行分析并优化索引是用来查询小范围数据的不适合使用索引的情况 每次查询都需要返回大部分数据的文档避免使用索引 写比读多7、分析器在MongoDB中的作用是什么?MongoDB中包括了一个可以显示数据库中每个操作性能特点的数据库分析器。通过这个分析器你可以找到比预期慢的查询(或写操作);利用这一信息比如可以确定是否需要添加索引。8、 Mongodb允许空值null吗?对于对象成员而言是的。然而用户不能够添加空值(null)到数据库丛集(collection)因为空值不是对象。然而用户能够添加空对象{}。9、 如何执行事务/加锁?MongoDB没有使用传统的锁或者复杂的带回滚的事务因为它设计的宗旨是轻量快速以及可预计的高性能。可以把它类比成MySQL MylSAM的自动提交模式。通过精简对事务的支持性能得到了提升特别是在一个可能会穿过多个服务器的系统里。10、分片(sharding)和复制(replication)是怎样工作的?每一个分片(shard)是一个分区数据的逻辑集合。分片可能由单一服务器或者集群组成我们推荐为每一个分片(shard)使用集群。11、 我怎么查看 Mongo 正在使用的链接?db._adminCommand(“connPoolStats”);12、什么是master或primary?它是当前备份集群(replica set)中负责处理所有写入操作的主要节点/成员。在一个备份集群中当失效备援(failover)事件发生时一个另外的成员会变成primary。13、什么是secondary或slave?Seconday从当前的primary上复制相应的操作。它是通过跟踪复制oplog(local.oplog.rs)做到的。九、MQ篇1、Activemq的作用以及原理Activemq 的作用就是系统之间进行通信。 当然可以使用其他方式进行系统间通信 如果使用 Activemq 的话可以对系统之间的调用进行解耦 实现系统间的异步通信。 原理就是生产者生产消息 把消息发送给activemq。 Activemq 接收到消息 然后查看有多少个消费者 然后把消息转发给消费者 此过程中生产者无需参与。 消费者接收到消息后做相应的处理和生产者没有任何关系2、消息重复消费问题可能原因发送时消息重复、投递时消息重复消费者的接口要实现等幂性方法一全局唯一ID根据业务的操作和内容生成一个全局ID在执行操作前先根据这个全局唯一ID是否存在来判断这个操作是否已经执行。方法二去重表建立一个去重表去重表中设置唯一索引如果去重表插入成功则执行方式三多版本控制3、activemq消息丢失如何处理情况一发送到broker时消息丢失解决先持久到数据库发送成功后删除或者标记删除。定时任务处理情况二broker崩溃解决消息持久化情况三broker到消费端出问题解决逻辑整理使其可以重新发送如发送时持久化消息并置状态为已发送消费成功则置为已消费当然消费要实现等幂性情况一发送到broker时消息丢失解决先持久到数据库发送成功后删除或者标记删除。定时任务处理情况二broker崩溃解决消息持久化情况三broker到消费端出问题解决逻辑整理使其可以重新发送如发送时持久化消息并置状态为已发送消费成功则置为已消费当然消费要实现等幂性4、消费顺序性如何保证方案一保证需要排序的消息按照先后顺序发送到同一个消费队列中并且这个队列只有一个相应的消费者方案二通过业务限制保证前消息被消费完才可以发送后消息十、Shiro篇1、Shiro 的优点简单的身份认证, 支持多种数据源对角色的简单的授权, 支持细粒度的授权(方法级)支持一级缓存以提升应用程序的性能内置的基于 POJO 企业会话管理, 适用于 Web 以及非 Web 的环境非常简单的加密 API不跟任何的框架或者容器捆绑, 可以独立运行2、比较 SpringSecurity 和 Shiro相比 Spring Security, Shiro 在保持强大功能的同时, 使用简单性和灵活性 SpringSecurity: 即使是一个一个简单的请求最少得经过它的 8 个FilterSpringSecurity 必须在 Spring 的环境下使用初学Spring Security, 曲线还是较大, 需要深入学习其源码和框架, 配置起来也较费力.3、简述 Shiro 的核心组件Shiro 架构 3 个核心组件:Subject: 正与系统进行交互的人, 或某一个第三方服务. 所有 Subject 实例都被绑定到且这是必须的一个SecurityManager 上。SecurityManager: Shiro 架构的心脏, 用来协调内部各安全组件, 管理内部组件实例, 并通过它来提供安全管理的各种服务当 Shiro 与一个 Subject 进行交互时, 实质上是幕后的 SecurityManager 处理所有繁重的 Subject 安全操作。Realms: 本质上是一个特定安全的 DAO. 当配置 Shiro 时, 必须指定至少一个 Realm 用来进行身份验证和/或授权Shiro 提供了多种可用的Realms 来获取安全相关的数据. 如关系数据库(JDBC), INI 及属性文件等也可以定义自己 Realm 实现来代表自定义的数据源。4、Shiro认证过程①. 应用程序代码调用 Subject.login 方法传递创建好的包含终端用户的 Principals(身份)和 Credentials(凭证)的 AuthenticationToken 实例②. Subject 实例: 通常为 DelegatingSubject(或子类)委托应用程序的 SecurityManager 通过调用securityManager.login(token) 开始真正的验证。③. SubjectManager 接收 token调用内部的 Authenticator 实例调用 authenticator.authenticate(token).Authenticator 通常是一个 ModularRealmAuthenticator 实例, 支持在身份验证中协调一个或多个Realm 实例④. 如果应用程序中配置了一个以上的 Realm, ModularRealmAuthenticator 实例将利用配置好的AuthenticationStrategy 来启动 Multi-Realm 认证尝试. 在Realms 被身份验证调用之前, 期间和以后,AuthenticationStrategy 被调用使其能够对每个Realm 的结果作出反应.⑤. 每个配置的 Realm 用来帮助看它是否支持提交的 AuthenticationToken. 如果支持, 那么支持 Realm 的 getAuthenticationInfo 方法将会伴随着提交的 token 被调用. getAuthenticationInfo 方法有效地代表一个特定 Realm 的单一的身份验证尝试。5、Shiro授权过程①. 应用程序或框架代码调用任何 Subject 的hasRole, checkRole, isPermitted,或者checkPermission方法的变体, 传递任何所需的权限②. Subject 的实例—通常是 DelegatingSubject(或子类), 调用securityManager 的对应的方法.③. SecurityManager 调用 org.apache.shiro.authz.Authorizer 接口的对应方法.默认情况下authorizer 实例是一个 ModularRealmAuthorizer 实例, 它支持协调任何授权操作过程中的一个或多个Realm 实例④. 每个配置好的 Realm 被检查是否实现了相同的 Authorizer 接口. 如果是, Realm 各自的 hasRole, checkRole,isPermitted或 checkPermission 方法将被调用。6、Shiro 如何自实现认证Shiro 的认证过程由 Realm 执行, SecurityManager 会调用 org.apache.shiro.realm.Realm 的 getAuthenticationInfo(AuthenticationToken token) 方法. 实际开发中, 通常提供 org.apache.shiro.realm.AuthenticatingRealm 的实现类, 并在该实现类中提供 doGetAuthenticationInfo(AuthenticationToken token)方法的具体实现7、如何实现自实现授权实际开发中, 通常提供 org.apache.shiro.realm.AuthorizingRealm 的实现类, 并提供 doGetAuthorizationInfo(PrincipalCollection principals) 方法的具体实现8、如何配置在 Spring 中配置使用 Shiro①. 在 web.xml 中配置 Shiro 的 Filter②. 在 Spring 的配置文件中配置 Shiro:配置自定义 Realm实现自定义认证和授权配置 Shiro 实体类使用的缓存策略配置 SecurityManager配置保证 Shiro 内部 Bean 声明周期都得到执行的 Lifecycle Bean 后置处理器配置AOP 式方法级权限检查配置 Shiro Filter十一、搜索引擎篇1、Solr原理Solr是基于Lucene开发的全文检索服务器而Lucene就是一套实现了全文检索的api其本质就是一个全文检索的过程。全文检索就是把原始文档根据一定的规则拆分成若干个关键词然后根据关键词创建索引当查询时先查询索引找到对应的关键词并根据关键词找到对应的文档也就是查询结果最终把查询结果展示给用户的过程2、Solr基于什么基于lucene搜索库的一个搜索引擎框架lucene是一个开放源码的全文检索引擎工具包3、Solr怎么设置搜索结果排名靠前设置文档中域的boost值值越高相关性越高排名就靠前4、Solr的索引查询为什么比数据库要快Solr使用的是Lucene API实现的全文检索。全文检索本质上是查询的索引。而数据库中并不是所有的字段都建立的索引更何况如果使用like查询时很大的可能是不使用索引所以使用solr查询时要比查数据库快5、Solr如何分词新增词和禁用词如何解决schema.xml文件中配置一个IK分词器然后域指定分词器为IK新增词添加到词典配置文件中ext.dic禁用词添加到禁用词典配置文件中stopword.dic然后在schema.xml文件中配置禁用词典6、IK分词器原理本质上是词典分词在内存中初始化一个词典然后在分词过程中逐个读取字符和字典中的字符相匹配把文档中的所有词语拆分出来的过程7、Lucence 内部结构是什么索引(Index)在Lucene中一个索引是放在一个文件夹中的。 如上图同一文件夹中的所有的文件构成一个Lucene索引。段(Segment)一个索引可以包含多个段段与段之间是独立的添加新文档可以生成新的段不同的段可以合并。segments.gen和segments_X是段的元数据文件也即它们保存了段的属性信息。文档(Document)文档是我们建索引的基本单位不同的文档是保存在不同的段中的一个段可以包含多篇文档。新添加的文档是单独保存在一个新生成的段中随着段的合并不同的文档合并到同一个段中。域(Field)一篇文档包含不同类型的信息可以分开索引比如标题时间正文作者等都可以保存在不同的域里。 不同域的索引方式可以不同在真正解析域的存储的时候我们会详细解读。词(Term)词是索引的最小单位是经过词法分析和语言处理后的字符串。8、Elasticsearch 了解多少说说你们公司 es 的集群架构索引数据大小分片有多少以及一些调优手段。elasticsearch 的倒排索引是什么。ElasticSearch简称ES是一个分布式、Restful的搜索及分析服务器设计用于分布式计算能够达到实时搜索稳定可靠快速。和Apache Solr一样它也是基于Lucence的索引服务器而ElasticSearch对比Solr的优点在于轻量级安装启动方便下载文件之后一条命令就可以启动。Schema free可以向服务器提交任意结构的JSON对象Solr中使用schema.xml指定了索引结构。多索引文件支持使用不同的index参数就能创建另一个索引文件Solr中需要另行配置。分布式Solr Cloud的配置比较复杂。9、Elasticsearch 与 Solr 的比较二者安装都很简单Solr 利用 Zookeeper 进行分布式管理而 Elasticsearch 自身带有分布式协调管理功能;Solr 支持更多格式的数据而 Elasticsearch 仅支持json文件格式Solr 官方提供的功能更多而 Elasticsearch 本身更注重于核心功能高级功能多有第三方插件提供Solr 在传统的搜索应用中表现好于 Elasticsearch但在处理实时搜索应用时效率明显低于 Elasticsearch。Solr 是传统搜索应用的有力解决方案但 Elasticsearch 更适用于新兴的实时搜索应用。10、Elasticsearch 索引数据多了怎么办如何调优部署。使用bulk API初次索引的时候把 replica 设置为 0增大 threadpool.index.queue_size增大 indices.memory.index_buffer_size增大 index.translog.flush_threshold_ops增大 index.translog.sync_interval增大 index.engine.robin.refresh_interval详细http://www.jianshu.com/p/5eeeeb4375d411、Elasticsearch是如何实现Master选举的Elasticsearch的选主是ZenDiscovery模块负责的主要包含Ping节点之间通过这个RPC来发现彼此和Unicast单播模块包含一个主机列表以控制哪些节点需要ping通这两部分对所有可以成为master的节点node.master: true根据nodeId字典排序每次选举每个节点都把自己所知道节点排一次序然后选出第一个第0位节点暂且认为它是master节点。如果对某个节点的投票数达到一定的值可以成为master节点数n/21并且该节点自己也选举自己那这个节点就是master。否则重新选举一直到满足上述条件。12、Elasticsearch是如何避免脑裂现象的当集群中master候选的个数不小于3个node.master:true。可以通过discovery.zen.minimum_master_nodes这个参数的设置来避免脑裂设置为(N/2)1。假如集群master候选节点为2的时候这种情况是不合理的最好把另外一个node.master改成false。如果我们不改节点设置还是套上面的(N/2)1公式此时discovery.zen.minimum_master_nodes应该设置为2。这就出现一个问题两个master备选节点只要有一个挂就选不出master了。13、客户端在和集群连接时如何选择特定的节点执行请求的TransportClient利用transport模块远程连接一个elasticsearch集群。它并不加入到集群中只是简单的获得一个或者多个初始化的transport地址并以 轮询 的方式与这些地址进行通信。14、在并发情况下Elasticsearch如果保证读写一致可以通过版本号使用乐观并发控制以确保新版本不会被旧版本覆盖由应用层来处理具体的冲突另外对于写操作一致性级别支持quorum/one/all默认为quorum即只有当大多数分片可用时才允许写操作。但即使大多数可用也可能存在因为网络等原因导致写入副本失败这样该副本被认为故障分片将会在一个不同的节点上重建。对于读操作可以设置replication为sync(默认)这使得操作在主分片和副本分片都完成后才会返回如果设置replication为async时也可以通过设置搜索请求参数_preference为primary来查询主分片确保文档是最新版本。15、Elasticsearch在部署时对Linux的设置有哪些优化方法64 GB 内存的机器是非常理想的 但是32 GB 和16 GB 机器也是很常见的。少于8 GB 会适得其反。如果你要在更快的 CPUs 和更多的核心之间选择选择更多的核心更好。多个内核提供的额外并发远胜过稍微快一点点的时钟频率。如果你负担得起 SSD它将远远超出任何旋转介质。 基于 SSD 的节点查询和索引性能都有提升。如果你负担得起SSD 是一个好的选择。即使数据中心们近在咫尺也要避免集群跨越多个数据中心。绝对要避免集群跨越大的地理距离。请确保运行你应用程序的 JVM 和服务器的 JVM 是完全一样的。 在 Elasticsearch 的几个地方使用 Java 的本地序列化。通过设置gateway.recover_after_nodes、gateway.expected_nodes、gateway.recover_after_time可以在集群重启的时候避免过多的分片交换这可能会让数据恢复从数个小时缩短为几秒钟。Elasticsearch 默认被配置为使用单播发现以防止节点无意中加入集群。只有在同一台机器上运行的节点才会自动组成集群。最好使用单播代替组播。不要随意修改垃圾回收器CMS和各个线程池的大小。把你的内存的少于一半给 Lucene但不要超过 32 GB通过ES_HEAP_SIZE 环境变量设置。内存交换到磁盘对服务器性能来说是致命的。如果内存交换到磁盘上一个 100 微秒的操作可能变成 10 毫秒。 再想想那么多 10 微秒的操作时延累加起来。 不难看出 swapping 对于性能是多么可怕。Lucene 使用了大量的文件。同时Elasticsearch 在节点和 HTTP 客户端之间进行通信也使用了大量的套接字。 所有这一切都需要足够的文件描述符。你应该增加你的文件描述符设置一个很大的值如 64,000。补充索引阶段性能提升方法使用批量请求并调整其大小每次批量数据 5–15 MB 大是个不错的起始点。段和段合并Elasticsearch 默认值是 20 MB/s对机械磁盘应该是个不错的设置。如果你用的是 SSD可以考虑提高到 100–200 MB/s。如果你在做批量导入完全不在意搜索你可以彻底关掉合并限流。另外还可以增加 index.translog.flush_threshold_size 设置从默认的 512 MB 到更大一些的值比如 1 GB这可以在一次清空触发的时候在事务日志里积累出更大的段。如果你的搜索结果不需要近实时的准确度考虑把每个索引的index.refresh_interval 改到30s。如果你在做大批量导入考虑通过设置index.number_of_replicas: 0 关闭副本。16、对于GC方面在使用Elasticsearch时要注意什么SEEhttps://elasticsearch.cn/article/32倒排词典的索引需要常驻内存无法GC需要监控data node上segment memory增长趋势。各类缓存field cache, filter cache, indexing cache, bulk queue等等要设置合理的大小并且要应该根据最坏的情况来看heap是否够用也就是各类缓存全部占满的时候还有heap空间可以分配给其他任务吗避免采用clear cache等“自欺欺人”的方式来释放内存。避免返回大量结果集的搜索与聚合。确实需要大量拉取数据的场景可以采用scan scroll api来实现。cluster stats驻留内存并无法水平扩展超大规模集群可以考虑分拆成多个集群通过tribe node连接。想知道heap够不够必须结合实际应用场景并对集群的heap使用情况做持续的监控。十二、Nginx篇1、请解释一下什么是Nginx?Nginx是一个web服务器和方向代理服务器用于HTTP、HTTPS、SMTP、POP3和IMAP协议。2、Nginx和apache的区别轻量级同样起web 服务比apache 占用更少的内存及资源抗并发nginx 处理请求是异步非阻塞的而apache 则是阻塞型的在高并发下nginx 能保持低资源低消耗高性能高度模块化的设计编写模块相对简单最核心的区别在于apache是同步多进程模型一个连接对应一个进程nginx是异步的多个连接万级别可以对应一个进程3、Nginx是如何实现高并发的答一个主进程多个工作进程每个工作进程可以处理多个请求每进来一个request会有一个worker进程去处理。但不是全程的处理处理到可能发生阻塞的地方比如向上游后端服务器转发request并等待请求返回。那么这个处理的worker继续处理其他请求而一旦上游服务器返回了就会触发这个事件worker才会来接手这个request才会接着往下走。由于web server的工作性质决定了每个request的大部份生命都是在网络传输中实际上花费在server机器上的时间片不多。这是几个进程就解决高并发的秘密所在。即skoo所说的webserver刚好属于网络io密集型应用不算是计算密集型。4、请解释Nginx如何处理HTTP请求Nginx使用反应器模式。主事件循环等待操作系统发出准备事件的信号这样数据就可以从套接字读取在该实例中读取到缓冲区并进行处理。单个线程可以提供数万个并发连接。5、使用“反向代理服务器”的优点是什么?反向代理服务器可以隐藏源服务器的存在和特征。它充当互联网云和web服务器之间的中间层。这对于安全方面来说是很好的特别是当您使用web托管服务时。6、请列举Nginx服务器的最佳用途。Nginx服务器的最佳用法是在网络上部署动态HTTP内容使用SCGI、WSGI应用程序服务器、用于脚本的FastCGI处理程序。它还可以作为负载均衡器。7、请解释Nginx服务器上的Master和Worker进程分别是什么?Master进程读取及评估配置和维持Worker进程处理请求8、在Nginx中解释如何在URL中保留双斜线?要在URL中保留双斜线就必须使用merge_slashes_off;语法:merge_slashes [on/off]默认值: merge_slashes on环境: httpserver9、请解释ngx_http_upstream_module的作用是什么?ngx_http_upstream_module用于定义可通过fastcgi传递、proxy传递、uwsgi传递、memcached传递和scgi传递指令来引用的服务器组。10、请解释什么是C10K问题?C10K问题是指无法同时处理大量客户端(10,000)的网络套接字。11、请陈述stub_status和sub_filter指令的作用是什么?Stub_status指令该指令用于了解Nginx当前状态的当前状态如当前的活动连接接受和处理当前读/写/等待连接的总数Sub_filter指令它用于搜索和替换响应中的内容并快速修复陈旧的数据12、解释Nginx是否支持将请求压缩到上游?您可以使用Nginx模块gunzip将请求压缩到上游。gunzip模块是一个过滤器它可以对不支持“gzip”编码方法的客户机或服务器使用“内容编码:gzip”来解压缩响应。13、解释如何在Nginx中获得当前的时间?要获得Nginx的当前时间必须使用SSI模块、 d a t e g m t 和 date_gmt和 dategmt和date_local的变量。Proxy_set_header THE-TIME $date_gmt;18、用Nginx服务器解释-s的目的是什么?用于运行Nginx -s参数的可执行文件。19、解释如何在Nginx服务器上添加模块?在编译过程中必须选择Nginx模块因为Nginx不支持模块的运行时间选择。十三、SpringBoot篇1、Spring Boot 的核心配置文件有哪几个它们的区别是什么Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。application 配置文件这个容易理解主要用于 Spring Boot 项目的自动化配置。bootstrap 配置文件有以下几个应用场景。使用 Spring Cloud Config 配置中心时这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息一些固定的不能被覆盖的属性一些加密/解密的场景2、Spring Boot 的核心注解是哪个它主要由哪几个注解组成的启动类上面的注解是SpringBootApplication它也是 Spring Boot 的核心注解主要组合包含了以下 3 个注解SpringBootConfiguration组合了 Configuration 注解实现配置文件的功能。EnableAutoConfiguration打开自动配置的功能也可以关闭某个自动配置的选项如关闭数据源自动配置功能SpringBootApplication(exclude { DataSourceAutoConfiguration.class })。ComponentScanSpring组件扫描。3、开启 Spring Boot 特性有哪几种方式继承spring-boot-starter-parent项目导入spring-boot-dependencies项目依赖4、Spring Boot 需要独立的容器运行吗可以不需要内置了 Tomcat/ Jetty 等容器。5、SpringBoot 实现热部署有哪几种方式主要有两种方式Spring LoadedSpring-boot-devtools6、Spring Boot 2.X 有什么新特性与 1.X 有什么区别配置变更JDK 版本升级第三方类库升级响应式 Spring 编程支持HTTP/2 支持配置属性绑定更多改进与加强7、springboot项目需要兼容老项目spring框架,该如何实现.集成老项目spring框架的容器配置文件即可:spring-boot一般提倡零配置.但是如果需要配置,也可增加:ImportResource({“classpath:spring1.xml” , “classpath:spring2.xml”})注意:resources/spring1.xml位置.8、springboot支持的默认日志框架是什么spring-boot: 默认采用Logback作为日志框架.9、什么是JavaConfigSpring JavaConfig是Spring社区的产品它提供了配置Spring IoC容器的纯Java方法。因此它有助于避免使用XML配置。使用JavaConfig的优点在于面向对象的配置。由于配置被定义为JavaConfig中的类因此用户可以充分利用Java中的面向对象功能。一个配置类可以继承另一个重写它的Bean方法等。减少或消除XML配置。基于依赖注入原则的外化配置的好处已被证明。但是许多开发人员不希望在XML和Java之间来回切换。JavaConfig为开发人员提供了一种纯Java方法来配置与XML配置概念相似的Spring容器。从技术角度来讲只使用JavaConfig配置类来配置容器是可行的但实际上很多人认为将JavaConfig与XML混合匹配是理想的。类型安全和重构友好。JavaConfig提供了一种类型安全的方法来配置Spring容器。由于Java 5.0对泛型的支持现在可以按类型而不是按名称检索bean不需要任何强制转换或基于字符串的查找。10、Spring Boot中的监视器是什么Spring boot actuator是spring启动框架中的重要功能之一。Spring boot监视器可帮助您访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为HTTP URL访问的REST端点来检查状态。11、如何实现Spring Boot应用程序的安全性为了实现Spring Boot的安全性我们使用 spring-boot-starter-security依赖项并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter并覆盖其方法。12、如何实现Spring Boot应用程序的安全性为了实现Spring Boot的安全性我们使用 spring-boot-starter-security依赖项并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter并覆盖其方法。十四、Dubbo篇1、dubbo都支持什么协议推荐用哪种dubbo://推荐rmi://hessian://http://webservice://thrift://memcached://redis://rest://2、Dubbo需要 Web 容器吗不需要如果硬要用 Web 容器只会增加复杂性也浪费资源。3、Dubbo内置了哪几种服务容器Spring ContainerJetty ContainerLog4j Container4、Dubbo里面有哪几种节点角色节点角色说明Provider暴露服务的服务提供方Consumer调用远程服务的服务消费方Registry服务注册于发现的注册中心Monitor统计服务的调用次数和调用时间的监控中间Container服务运行容器5、Dubbo默认使用什么注册中心还有别的选择吗推荐使用 Zookeeper 作为注册中心还有 Redis、Multicast、Simple 注册中心但不推荐。6、Dubbo推荐使用什么序列化框架你知道的还有哪些推荐使用Hessian序列化还有Duddo、FastJson、Java自带序列化。7、Dubbo默认使用的是什么通信框架还有别的选择吗Dubbo 默认使用 Netty 框架也是推荐的选择另外内容还集成有Mina、Grizzly。8、服务上线怎么兼容旧版本可以用版本号version过渡多个不同版本的服务注册到注册中心版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。9、在 Provider 上可以配置的 Consumer 端的属性有哪些timeout方法调用超时retries失败重试次数默认重试 2 次loadbalance负载均衡算法默认随机actives 消费者端最大并发调用限制10、Dubbo有哪几种集群容错方案默认是哪种集群容错方案说明Failover Cluster失败自动切换自动重试其他服务器默认Failfast Cluster快速失败立即报错只发起一次调用Failsafe Cluster失败安全出现异常时直接忽略Failback Cluster失败自动恢复记录失败请求定时重发Forking Cluster并行调用多个服务器只是一个成功即返回Broadcast Cluster广播逐个调用所有提供者任意一个报错则报错11、Dubbo有哪几种负载均衡策略默认是哪种负载均衡策略说明Random LoadBalance随机按权重设置随机概率默认RoundRobin LoadBalance轮询按公约后的权重设置轮询比率LeastActive LoadBalance最少活跃调用数相同活跃的随机ConsistentHash LoadBalance一致性Hash相同参数的请求总是发到同一提供者12、Dubbo可以对结果进行缓存吗可以Dubbo 提供了声明式缓存用于加速热门数据的访问速度以减少用户加缓存的工作量。13、当一个服务接口有多种实现时怎么做当一个接口有多种实现时可以用 group 属性来分组服务提供方和消费方都指定同一个 group 即可。14、Dubbo服务之间的调用是阻塞的吗默认是同步等待结果阻塞的支持异步调用。Dubbo 是基于 NIO 的非阻塞实现并行调用客户端不需要启动多线程即可完成并行调用多个远程服务相对多线程开销较小异步调用会返回一个 Future 对象。15、Dubbo在安全机制方面是如何解决的Dubbo通过Token令牌防止用户绕过注册中心直连然后在注册中心上管理授权。Dubbo还提供服务黑白名单来控制服务所允许的调用方。16、dubbo连接注册中心和直连的区别在开发及测试环境下经常需要绕过注册中心只测试指定服务提供者这时候可能需要点对点直连点对点直联方式将以服务接口为单位忽略注册中心的提供者列表服务注册中心动态的注册和发现服务使服务的位置透明并通过在消费方获取服务提供方地址列表实现软负载均衡和Failover 注册中心返回服务提供者地址列表给消费者如果有变更注册中心将基于长连接推送变更数据给消费者。服务消费者从提供者地址列表中基于软负载均衡算法选一台提供者进行调用如果调用失败再选另一台调用。注册中心负责服务地址的注册与查找相当于目录服务服务提供者和消费者只在启动时与注册中心交互注册中心不转发请求服务消费者向注册中心获取服务提供者地址列表并根据负载算法直接调用提供者注册中心服务提供者服务消费者三者之间均为长连接监控中心除外注册中心通过长连接感知服务提供者的存在服务提供者宕机注册中心将立即推送事件通知消费者注册中心和监控中心全部宕机不影响已运行的提供者和消费者消费者在本地缓存了提供者列表注册中心和监控中心都是可选的服务消费者可以直连服务提供者。17、dubbo通信协议dubbo协议为什么不能传大包因dubbo协议采用单一长连接如果每次请求的数据包大小为500KByte假设网络为千兆网卡(1024Mbit128MByte)每条连接最大7MByte(不同的环境可能不一样供参考)单个服务提供者的TPS(每秒处理事务数)最大为128MByte / 500KByte 262。单个消费者调用单个服务提供者的TPS(每秒处理事务数)最大为7MByte / 500KByte 14。如果能接受可以考虑使用否则网络将成为瓶颈。说真的这两年看着身边一个个搞Java、C、前端、数据、架构的开始卷大模型挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis稳稳当当过日子。结果GPT、DeepSeek火了之后整条线上的人都开始有点慌了大家都在想“我是不是要学大模型不然这饭碗还能保多久”先给出最直接的答案一定要把现有的技术和大模型结合起来而不是抛弃你们现有技术掌握AI能力的Java工程师比纯Java岗要吃香的多。即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇Java与大模型结合的技术优势推理环节的核心地位大模型训练依赖Python生态的高性能计算资源而Java在推理阶段模型部署、性能优化、系统集成具有独特优势。其“编写一次处处运行”的特性使其能无缝集成到微服务、分布式系统等企业级架构中高效处理高并发请求。例如某电商平台通过Java构建的大模型API网关支撑每日千万级请求的稳定运行响应时间缩短50%。生态成熟与性能稳定Java拥有Spring Boot、Spring Cloud等成熟框架可快速实现服务注册、负载均衡、熔断降级等生产级能力。JVM的垃圾回收机制和即时编译技术使其在长连接、高并发场景下表现优于脚本语言。例如某金融系统采用Java实现大模型推理服务系统可用率长期保持99.99%以上。兼容性与工程化能力Java与现有业务系统的兼容性极强可降低大模型落地的集成成本。例如某制造企业通过Java将大模型与ERP系统对接实现生产流程的智能优化故障率降低30%。同时Java在代码规范、测试流程、版本管理等方面的积累能大幅降低大模型项目的研发成本和维护难度。因此捕获AI掌握技术是关键让AI成为我们最便利的工具.一定要把现有的技术和大模型结合起来而不是抛弃你们现有技术掌握AI能力的Java工程师比纯Java岗要吃香的多。即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇如何学习AGI大模型作为一名热心肠的互联网老兵我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。因篇幅有限仅展示部分资料需要点击下方链接即可前往获取2025最新版CSDN大礼包《AGI大模型学习资源包》免费分享**一、2025最新大模型学习路线一个明确的学习路线可以帮助新人了解从哪里开始按照什么顺序学习以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛没有明确的学习路线可能会导致新人感到迷茫不知道应该专注于哪些内容。我们把学习路线分成L1到L4四个阶段一步步带你从入门到进阶从理论到实战。L1级别:AI大模型时代的华丽登场L1阶段我们会去了解大模型的基础知识以及大模型在各个行业的应用和分析学习理解大模型的核心原理关键技术以及大模型应用场景通过理论原理结合多个项目实战从提示工程基础到提示工程进阶掌握Prompt提示工程。L2级别AI大模型RAG应用开发工程L2阶段是我们的AI大模型RAG应用开发工程我们会去学习RAG检索增强生成包括Naive RAG、Advanced-RAG以及RAG性能评估还有GraphRAG在内的多个RAG热门项目的分析。L3级别大模型Agent应用架构进阶实践L3阶段大模型Agent应用架构进阶实现我们会去学习LangChain、 LIamaIndex框架也会学习到AutoGPT、 MetaGPT等多Agent系统打造我们自己的Agent智能体同时还可以学习到包括Coze、Dify在内的可视化工具的使用。L4级别大模型微调与私有化部署L4阶段大模型的微调和私有化部署我们会更加深入的探讨Transformer架构学习大模型的微调技术利用DeepSpeed、Lamam Factory等工具快速进行模型微调并通过Ollama、vLLM等推理部署框架实现模型的快速部署。整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握而L3 L4更多的是通过项目实战来掌握大模型的应用开发针对以上大模型的学习路线我们也整理了对应的学习视频教程和配套的学习资料。二、大模型经典PDF书籍书籍和学习文档资料是学习大模型过程中必不可少的我们精选了一系列深入探讨大模型技术的书籍和学习文档它们由领域内的顶尖专家撰写内容全面、深入、详尽为你学习大模型提供坚实的理论基础。书籍含电子版PDF三、大模型视频教程对于很多自学或者没有基础的同学来说书籍这些纯文字类的学习教材会觉得比较晦涩难以理解因此我们提供了丰富的大模型视频教程以动态、形象的方式展示技术概念帮助你更快、更轻松地掌握核心知识。四、大模型项目实战学以致用当你的理论知识积累到一定程度就需要通过项目实战在实际操作中检验和巩固你所学到的知识同时为你找工作和职业发展打下坚实的基础。五、大模型面试题面试不仅是技术的较量更需要充分的准备。在你已经掌握了大模型技术之后就需要开始准备面试我们将提供精心整理的大模型面试题库涵盖当前面试中可能遇到的各种技术问题让你在面试中游刃有余。因篇幅有限仅展示部分资料需要点击下方链接即可前往获取2025最新版CSDN大礼包《AGI大模型学习资源包》免费分享