学习笔记:代理设计模式,注解,前端JS代码示例,企业面试题,企业实际应用场景

28 阅读4分钟

代理设计模式

代码示例

  1. 接口定义

java

// 定义一个服务接口
public interface Service {
    void execute();
}
  1. 真实服务实现

java

// 真实服务类
public class RealService implements Service {
    @Override
    public void execute() {
        System.out.println("执行真实服务逻辑");
    }
}
  1. 静态代理

java

// 静态代理类
public class StaticProxy implements Service {
    private Service realService;

    public StaticProxy(Service realService) {
        this.realService = realService;
    }

    @Override
    public void execute() {
        System.out.println("代理预处理逻辑");
        realService.execute();
        System.out.println("代理后处理逻辑");
    }
}
  1. 动态代理(JDK 动态代理)

java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 动态代理处理器
public class DynamicProxyHandler implements InvocationHandler {
    private Object target;

    public DynamicProxyHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态代理预处理逻辑");
        Object result = method.invoke(target, args);
        System.out.println("动态代理后处理逻辑");
        return result;
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }
}
  1. 测试代码

java

public class ProxyPatternTest {
    public static void main(String[] args) {
        // 静态代理测试
        Service realService = new RealService();
        StaticProxy staticProxy = new StaticProxy(realService);
        staticProxy.execute();

        // 动态代理测试
        DynamicProxyHandler dynamicProxyHandler = new DynamicProxyHandler(realService);
        Service dynamicProxy = (Service) dynamicProxyHandler.getProxy();
        dynamicProxy.execute();
    }
}

企业面试题

  1. 静态代理和动态代理的区别是什么?

    • 静态代理:代理类在编译期就已经确定,手动编写代理类代码,代理类和目标类实现相同接口,代理类中包含目标类的实例。
    • 动态代理:代理类在运行期动态生成,通过反射机制实现。JDK 动态代理要求目标对象必须实现接口,CGLIB 动态代理可以代理没有实现接口的类,通过继承目标类生成代理类。
  2. 在什么情况下会选择使用代理设计模式?

    • 远程代理:隐藏一个对象存在于不同地址空间的事实,比如 RMI(Remote Method Invocation)。
    • 虚拟代理:当需要创建一个资源消耗较大的对象时,先创建一个消耗相对较小的代理对象,在真正需要时才创建真实对象,如加载大图片。
    • 保护代理:控制对一个对象的访问,根据不同的权限决定是否允许访问真实对象。

企业实际应用场景

  1. Spring AOP(面向切面编程) :基于动态代理实现,用于在不修改目标对象代码的情况下,为其添加横切关注点,如日志记录、事务管理、权限控制等。
  2. RPC(Remote Procedure Call)框架:如 Dubbo,使用代理模式隐藏远程调用的细节,让调用者感觉像是在调用本地方法。

注解

代码示例

  1. 自定义注解

java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String value() default "";
}
  1. 使用注解

java

public class AnnotationExample {
    @MyAnnotation("这是一个示例注解")
    public void annotatedMethod() {
        System.out.println("执行被注解的方法");
    }
}
  1. 解析注解

java

import java.lang.reflect.Method;

public class AnnotationParser {
    public static void main(String[] args) {
        AnnotationExample example = new AnnotationExample();
        Class clazz = example.getClass();
        try {
            Method method = clazz.getMethod("annotatedMethod");
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            if (annotation != null) {
                System.out.println("注解值: " + annotation.value());
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

企业面试题

  1. Java 注解的作用是什么?

    • 编译检查:如 @Override 注解,用于检查方法是否正确重写父类方法。
    • 代码配置:在 Spring 框架中,使用注解进行 Bean 的定义和依赖注入,如 @Component@Autowired 等。
    • 运行时处理:通过反射获取注解信息,实现特定的业务逻辑,如自定义权限控制注解。
  2. 元注解有哪些,它们的作用是什么?

    • @Retention:指定注解的保留策略,如 RetentionPolicy.RUNTIME(运行时保留)、RetentionPolicy.CLASS(编译时保留)、RetentionPolicy.SOURCE(源文件保留)。
    • @Target:指定注解可以应用的目标元素类型,如 ElementType.METHOD(方法)、ElementType.TYPE(类、接口等)。
    • @Documented:将注解包含在 Javadoc 中。
    • @Inherited:允许子类继承父类的注解。

企业实际应用场景

  1. Spring 框架:广泛使用注解进行配置和依赖注入,简化了 XML 配置的繁琐。
  2. JUnit 测试框架:使用注解如 @Test 标记测试方法,方便测试类的编写和执行。

前端 JS

代码示例

  1. 基本函数和变量

javascript

// 定义变量
let message = "Hello, World!";
// 定义函数
function greet() {
    console.log(message);
}
greet();
  1. DOM 操作

html





    
    JS DOM 示例



    <div id="myDiv">原始文本</div>
    修改文本
    
        function changeText() {
            let div = document.getElementById('myDiv');
            div.textContent = &#34;文本已修改&#34;;
        }
    



  1. 事件监听

html





    
    JS 事件监听示例



    点击我
    
        let button = document.getElementById('myButton');
        button.addEventListener('click', function () {
            alert('按钮被点击了');
        });
    



企业面试题

  1. JavaScript 中 letconst 和 var 的区别是什么?

    • var:函数作用域,存在变量提升,可重复声明。
    • let:块级作用域,不存在变量提升,不可重复声明。
    • const:块级作用域,不存在变量提升,不可重复声明,声明时必须初始化,且值不能重新赋值(对于对象和数组,可修改其内部属性和元素)。
  2. 什么是闭包,它有什么应用场景?

    • 闭包:函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包。
    • 应用场景:实现数据封装和私有化,如模块模式;用于回调函数,保持状态。

企业实际应用场景

  1. 网页交互:实现按钮点击、表单验证、页面动态更新等交互功能。
  2. 单页应用(SPA)开发:如 Vue.js、React.js 等框架,使用 JavaScript 构建复杂的前端应用,提供流畅的用户体验。