当前位置: 首页 > news >正文

西双网站建设南海佛山网站建设

西双网站建设,南海佛山网站建设,wordpress教学主题,响应式网站如何设计上周投了一些简历#xff0c;约了8-9家面试#xff0c;其中完成了3家的第一轮面试#xff0c;由于面试的是Java 的实习生#xff0c;感觉问的题目都比较基础#xff0c;不过有些问题回答的不是很好#xff0c;在这里对回答的不太好的题目做一下总结和复盘。 目录 一、后…上周投了一些简历约了8-9家面试其中完成了3家的第一轮面试由于面试的是Java 的实习生感觉问的题目都比较基础不过有些问题回答的不是很好在这里对回答的不太好的题目做一下总结和复盘。 目录 一、后端开发Java面试复盘 1.1、23种设计模式 1.2、数据库(MySQL)的索引失效情况 1.3、线程池的使用 1.4、ConcurrentHashMap的使用及底层原理 1.5、Spring的传递依赖问题 1.6、MySQL事务的四种隔离级别 一、后端开发Java面试复盘 1.1、23种设计模式 设计模式就是代码设计经验的总结。使用设计模式可以提高代码的可靠性和可重用性。 设计模式共有23中整体分为3大类如下 创建型模式共五种工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式 结构型模式共七种适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式 行为型模式共十一种策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式 设计模型有6大原则具体如下 1开放封闭原则尽量通过扩展软件实体应对需求的改变而不是修改原有代码 2里氏代换原则使用的基类可以在任何地方使用继承的字类完美的替换基类 3依赖倒转原则即面向接口编程依赖抽象而不依赖具体 4接口隔离原则使用多个隔离的接口替代单个接口降低耦合 5迪米特法则一个类尽量减少对其他类的依赖 6单一职责一个方法尽量只负责一件事 单例模式分为饿汉模式和懒汉模式都是每个类中只创建一个实例并提供全局访问点来访问这个实例。饿汉模型是线程安全的懒汉模式线程不安全需要使用双重检测锁保证线程安全具体的Java代码实现如下 /*** 单例模式确保每个类只有一个实例并提供全局访问点来访问这个实例*/ //饿汉模式线程安全 class Singleton1 {private static Singleton1 instance new Singleton1() ;public Singleton1 getInstance(){return instance ;} }//懒汉模式线程不安全需要通过双重检查锁定机制控制 class Singleton2{private static Singleton2 instance2 null ;public Singleton2 getInstance2(){if(instance2 null){instance2 new Singleton2() ;}return instance2 ;} } //使用双重检查锁的方式保重线程安全 class Singleton3{//使用双重检查进行初始化的实例必须使volatile关键字修饰private volatile static Singleton3 instance3 null ;public Singleton3 getInstance3(){if(instance3 null){synchronized (Singleton3.class){if(instance3 null){instance3 new Singleton3();}}}return instance3 ;} } public class Main {public static void main(String[] args) {Singleton1 singleton1 new Singleton1() ;Singleton1 singleton2 new Singleton1() ;Singleton2 singleton21 new Singleton2() ;Singleton2 singleton22 new Singleton2() ;Singleton1 instance1 singleton1.getInstance();Singleton1 instance2 singleton2.getInstance();Singleton2 instance21 singleton21.getInstance2();Singleton2 instance22 singleton22.getInstance2();System.out.println(instance1 instance2);System.out.println(instance21 instance22);} }下面在了解一下工厂模式和代理模式。 工厂模式是一种创建对象的最佳方式在创建对象时不对客户端暴露创建逻辑通过使用一个共同的接口来指向新创建的对象实现创建者和调用者的分离工厂模式分为简单工厂工厂方法和抽象工厂。我们熟知的Spring的IOC容器使用工厂模式创建Bean只需要交给Bean进行管理即可这样我们在业务层调接口层的方法时候就不需要再new了可以直接注入。 1简单工厂模式也称为静态工厂方法可以根据参数的不同返回不同类的实例简单工厂模式专门定义一个类来负责创建其它类的实例被创建的实例通常都有共同的父类。 首先创建工厂 public interface Car {public void run() ; } 定义工厂中的两个产品 public class Car1 implements Car {Overridepublic void run() {System.out.println(我是小汽车);} }public class Bus implements Car {Overridepublic void run() {System.out.println(我是大卡车);} }创建核心工厂类决定调用工厂中的哪一种方法具体如下 /*** 创建工厂类在工厂类中决定调用哪一种产品*/ public class CarFactory {public static Car createCar(String name){if(小汽车.equals(name)){return new Car1() ;}if(大卡车.equals(name)){return new Bus() ;}return null ;}}演示创建共创对象并调用工厂中的产品具体如下 /*** 演示简单工厂*/ public class Factory1 {public static void main(String[] args) {//通过工厂类创建工厂对象Car car CarFactory.createCar(小汽车);Car car1 CarFactory.createCar(大卡车);//调用工厂方法car.run();car1.run();} }优点简单工厂模式能够根据外界给定的信息决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力有利于整个软件体系结构的优化。缺点很明显工厂类集中了所有实例的创建逻辑容易违反GRASPR的高内聚的责任分配原则。 2工厂方法模式也称多态性工厂模式核心的工厂类不在负责所有产品实例的创建而是将具体的创建交给具体的子类去做该核心类成为一个抽象工厂角色仅仅给出具体工厂字类必须实现的接口而不涉及具体哪一个产品被实例化。 首先是创建工厂和工厂的两个产品具体如下 public interface Car {public void run() ; }public class Car1 implements Car {Overridepublic void run() {System.out.println(我是小汽车);} }public class Bus implements Car {Overridepublic void run() {System.out.println(我是大卡车);} } 然后创建工厂方法调用接口并创建工厂实例。 /*** 创建创建工厂方法调用接口所有工厂产品需要实现该接口并重写接口方法*/ public interface Factorys {Car createFactory() ; }public class CarF implements Factorys {Overridepublic Car createFactory() {return new Car1() ;} }public class BusF implements Factorys {Overridepublic Car createFactory() {return new Bus() ;} }最后演示工厂方法的实现。 public class Factory2 {public static void main(String[] args) {Car car new CarF().createFactory();Car car1 new BusF().createFactory();car.run() ;car1.run() ;} }3抽象工厂模式即工厂的工厂 抽象工厂可以创建具体工厂由具体工厂来生产具体产品。 首先创建第一个子工厂及其实现类如下 /*** 创建第一个工厂接口及其实现类*/ public interface A {void run() ; } class CarA implements A{Overridepublic void run() {System.out.println(奔驰);} } class CarB implements A{Overridepublic void run() {System.out.println(宝马);} } 创建第2个子工厂及其实现类具体如下 public interface B {void run() ; } class Animal1 implements B{Overridepublic void run() {System.out.println(狗);} } class Animal implements B{Overridepublic void run() {System.out.println(猫);} } 创建一个总工厂及其实现类由总工厂的实现类决定调用哪个工厂的哪个实例。 /*** 总工厂包含创建工厂工厂的接口*/ public interface TotalFactory {A createA() ;B createB() ; }/*** 总工厂的实现类决定创建哪个工厂的哪个实例*/ class TotalFactoryImpl implements TotalFactory{Overridepublic A createA() {return new CarA() ;}Overridepublic B createB() {return new Animal1();} }最后演示抽象工厂模式如下 public class Test {public static void main(String[] args) {A a new TotalFactoryImpl().createA();B b new TotalFactoryImpl().createB();a.run();b.run() ;} }下面我们看一下代理模式我们正常在Spring会接触到代理模式。我们先了解一下什么是代理。 通过代理控制对象的访问可以在这个对象调用方法之前、调用方法之后去处理/添加新的功能。(也就是AOP的实现)代理在原有代码乃至原业务流程都不修改的情况下直接在业务流程中切入新代码增加新功能这也和Spring的面向切面编程很相似 我们常见的代理模式分为3种即静态代理JDK动态代理和CGLIB动态代理。 静态代理简单代理模式是动态代理的理论基础。常见使用在代理模式。 JDK 代理 : 基于接口的动态代理技术·利用拦截器必须实现invocationHandler加上反射机制生成一个代理接口的匿名类在调用具体方法前调用InvokeHandler来处理从而实现方法增强。 CGLIB代理基于父类的动态代理技术动态生成一个要代理的子类子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截技术拦截所有的父类方法的调用顺势织入横切逻辑对方法进行增强。 1静态代理 我们首先看如下一个接口类如何在不改变接口类的基础上在接口方法中开启和关闭事务我们可以使用静态代理的方式。 public interface UserDao {void save() ; }class UserDaoImpl implements UserDao{Overridepublic void save() {System.out.println(添加数据);} }public class Test2 {public static void main(String[] args) {UserDaoImpl userDao new UserDaoImpl();userDao.save();} }下面是静态代理实现的代码如下 public class UserDaoProxy extends UserDaoImpl {public UserDaoImpl userDao ;public UserDaoProxy(UserDaoImpl userDao){this.userDao userDao ;}Overridepublic void save() {System.out.println(开启事务);super.save();System.out.println(关闭事务);} }public class Test2 {public static void main(String[] args) {UserDaoImpl userDao new UserDaoImpl();UserDaoProxy userDaoProxy new UserDaoProxy(userDao);userDaoProxy.save();} } 2下面看一下JDK动态代理它是基于接口的动态代理技术用拦截器必须实现invocationHandler加上反射机制生成一个代理接口的匿名类在调用具体方法前调用InvokeHandler来处理从而实现方法增强。 首先编写可以重复使用的代理类如下可以重复使用不像静态代理那样每次都要重复编写带泪类具体如下 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;public class InvocationHandlerImpl implements InvocationHandler {//通过构造方法传入目标对象public Object target ;InvocationHandlerImpl(Object target){this.target target ;}/*** 动态代理实际运行的代理方法,以反射的方式创建对象* param proxy* param method* param args* return* throws Throwable*/Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(开始);Object invoke method.invoke(target, args);System.out.println(结束);return invoke ;} } public class Test2 {public static void main(String[] args) {//已构造方法的方式传入被代理的对象UserDaoImpl userDaoImpl new UserDaoImpl() ;InvocationHandlerImpl invocationHandler new InvocationHandlerImpl(userDaoImpl);//类加载器ClassLoader classLoader userDaoImpl.getClass().getClassLoader();Class?[] interfaces userDaoImpl.getClass().getInterfaces();UserDao proxyInstance (UserDao)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);proxyInstance.save();} }3最后我们看一下CGLIB动态代理基于父类的动态代理技术动态生成一个要代理的子类子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截技术拦截所有的父类方法的调用顺势织入横切逻辑对方法进行增强。 简单地说就是实现MethodInterceptor接口并重写intercept()方法实现动态代理。 1.2、数据库(MySQL)的索引失效情况 1查询条件有or关键字(必须所有查询条件都有索引) 2模糊查询like以%开头 3索引列上的条件where部分涉及计算或者函数 4复合索引缺少左列字段 5数据库认为全表扫描比索引更高效 1.3、线程池的使用 创建线程常见的几种方法包括继承Thread类并重写run()方法实现Runnable()接口或实现Collable等。一般来说我们使用传统的方法每次创建和销毁线程的开销都比较大故我们可以使用线程池的方式减小开销。 使用线程池主要有如下的优势 1提高效率创建好一定数量的线程放在池中等需要使用的时候就从池中拿一个这要比需要的时候创建一个线程对象要快的多。 2减少了创建和销毁线程的次数每个工作线程都可以被重复利用可执行多个任务。 3提升系统响应速度假如创建线程用的时间为T1执行任务用的时间为T2,销毁线程用的时间为T3那么使用线程池就免去了T1和T3的时间。   Executors类并发包提供了4种创建线程池方法这些方法最终都是通过配置ThreadPoolExecutor的不同参数来达到不同的线程管理效果。 推荐通过 new ThreadPoolExecutor() 的写法创建线程池这样写线程数量更灵活开发中多数用这个类创建线程。 该类包含如下核心参数核心线程数最大线程数闲置超时时间超时时间的单位线程池中的任务队列线程工厂拒绝策略。 最后一个参数为拒绝策略一半包含四种拒绝策略如下 1. AbortPolicy 当任务添加到线程池中被拒绝时直接丢弃任务并抛出RejectedExecutionException异常。 2. DiscardPolicy 当任务添加到线程池中被拒绝时丢弃被拒绝的任务不抛异常。 3. DiscardOldestPolicy 当任务添加到线程池中被拒绝时丢弃任务队列中最旧的未处理任务然后将被拒绝的任务添加到等待队列中。 4. CallerRunsPolicy 被拒绝任务的处理程序直接在execute方法的调用线程中运行被拒绝的任务。 总结就是被拒绝的任务直接在主线程中运行不再进入线程池。 下面看一个demo创建线程池并设置最大线程数目为2设置拒绝策略为CallerRunsPolicy。 import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) {// 创建单线程-线程池任务依次执行ThreadPoolExecutor threadPoolExecutor new ThreadPoolExecutor(2, 2,60, TimeUnit.SECONDS,new LinkedBlockingDeque(2),new ThreadPoolExecutor.CallerRunsPolicy());for (int i 0; i 10; i) {//创建任务Runnable runnable new Runnable() {Overridepublic void run() {try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName());}};// 将任务交给线程池管理threadPoolExecutor.execute(runnable);}} }1.4、ConcurrentHashMap的使用及底层原理 Map包括HashMap和HashTable。 HashMap性能高但不是线程安全 HashMap的性能比较高但是HashMap不是线程安全的在并发环境下可能会形成环状链表导致get操作时cpu空转所以在并发环境中使用HashMap是非常危险的。 HashTable是线程安全的但性能差 HashTable和HashMap的实现原理几乎一样差别HashTable不允许key和value为null。 HashTable是线程安全的但是HashTable线程安全的策略实现代价却比较大get/put所有相关操作都是synchronized的这相当于给整个哈希表加了一把大锁多线程访问时候只要有一个线程访问或操作该对象那其他线程只能阻塞这就导致性能比较低。 ConcurrentHashMap是线程安全的且性能高 JDK1.7版本 容器中有多把锁每一把锁锁一段数据这样在多线程访问时不同段的数据时就不会存在锁竞争了这样便可以有效地提高并发效率。 JDK1.8版本做了2点修改取消segments字段直接采用transient volatile HashEntryK,V[] table保存数据采用table数组元素作为锁从而实现了对每一行数据进行加锁并发控制使用Synchronized和CAS来操作将原先table数组单向链表的数据结构变更为table数组单向链表红黑树的结构。   1.5、Spring的传递依赖问题 maven环境存在的依赖冲突问题可以在pom文件中使用exlusions标签排除依赖主动断开依赖的资源被排除的资源无需指定版本。 在Spring中解决循环依赖问题可以使用三级缓存三级缓存如下 1.6、MySQL事务的四种隔离级别 MySQL支持四种事务隔离级别默认的事务隔离级别为repeatable readOracle数据库默认的隔离级别是read committed。 四种隔离级别分别为读未提交读已提交可重复读 序列化/串行化。其中读未提交是最低的隔离级别序列化隔离级别最高。 1.读未提交(read uncommitted)没有提交就读取到了。 2.读已提交(read committed)已经提交的才能读取。 3.可重复读(repeatable read)事务结束之前。永远读取不到真实数据提交了也读取不到读取的永远都是最初的数据即假象。 4.序列化(serializable)表示事务排队不能并发每次读取的都是最真实的数据。 同时运行多个事务当这些事务访问数据库中相同的数据时如果没有采取必要的隔离机制就会导致各种并发问题。 1-脏读对于两个事务T1和T2T1读取了已经被T2更新但还没有提交的字段之后若T2回滚则T1读取的数据就是临时且无效的。 2-不可重复读对于两个事务T1和T2T1读取了该字段但是T2更新了该字段T1再次读取这个字段值就不同了。 3-幻读对于两个事务T1和T2T1从表中读取了一些字段T2在表中插入了一些新的行T1再次读取该表发现多几行。 read uncommitted:可以出现脏读幻读不可重复读。 read committed:避免脏读出现幻读和不可重复读。 repeatable read:避免脏读和不可重复读出现幻读。 serializable避免脏读幻读不可重复读。
http://www.dnsts.com.cn/news/102764.html

相关文章:

  • h5开发和前端开发区别东莞seo网站推广
  • 中国商标网商标查询网巩义网站优化培训
  • 皮具网站建设策划书施工企业管理杂志官网
  • 烟台城乡建设局网站网站建设颜色注意事项
  • 网站样式下载百度排名 网站标题
  • 网站建设怎么选公司我做微信淘宝客网站有哪些
  • 广州建设工程造价管理站深圳工作服制作
  • 小企业网站建设哪些好办郑州哪个公司专业做网站
  • 建筑学网站推荐wordpress系统付费
  • 网站制作公司怎样帮客户做优化免费网站建设行情
  • 手机 网站 翻页 外部网站建设视频教程推荐
  • 广州 天河网站设计百度关键词seo公司
  • 江门网站制作套餐能搜任何网站的浏览器
  • 学院网站建设的目的网站互动设计方式
  • 昆明网站建设报价网站中验证码如何做的
  • 网站弹出广告代码企业网站建设介绍
  • 昆明网站建设锐网ui培训设计
  • 商贸公司寮步网站建设价钱第一模板ppt免费下载
  • 企业网站推广计划书手机关键词seo排名优化
  • 阿里云服务器如何配置多网站自己做网站的步骤
  • 班组建设管理网站中国外贸平台排名
  • 如何做自己的网站百度推广石狮服装城商家微网站建设
  • 电子商务网站建设与管理论文网站工程师招聘
  • 免费无限建站系统wordpress中医主题
  • dell网站的网站设计特色广告设计和平面设计有什么区别
  • 杭州建站程序网站建设标书样本
  • 龙岩网站设计 都找推商吧系统开发语言有哪些
  • 上饶做网站的公司济南房产信息网站官网查询
  • php wordpress单本小说网站源码+采集河北省建设集团有限公司网站首页
  • 如何自建一个便宜的网站龙岗网站建设公司官网