5.22学习记录

这是一篇实习记录博客,包含公司项目学习和每日一题。项目学习涉及Java注解@inherited和@Documented,还介绍了缓存实现,利用AOP将注解作为切点,结果存入Redis。每日一题是找出数组中只出现一次的元素,给出两种思路,一是用set求和计算,二是设计状态转换电路。

实习记录

公司项目学习

###注解

@inherited

允许子类继承父类的注解

@Documented

注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中,是一个标记注解,没有成员。

缓存的实现

定义一个注解@screencache,利用aop,把screencache这个注解作为切点,采用环绕时加强。

  • 传入的参数为ProceedingJoinPoint类型的joinpoint,它是joinpoint的子类,Springaop是通过joinpoint来获取连接点数据的,使用环绕时则为proceedingjoinpoint,源码如下
public interface JoinPoint {  
    String toString();         //连接点所在位置的相关信息  
    String toShortString();     //连接点所在位置的简短相关信息  
    String toLongString();     //连接点所在位置的全部相关信息  
    Object getThis();         //返回AOP代理对象  
    Object getTarget();       //返回目标对象  
    Object[] getArgs();       //返回被通知方法参数列表  
    Signature getSignature();  //返回当前连接点签名  
    SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置  
    String getKind();        //连接点类型  
    StaticPart getStaticPart(); //返回连接点静态部分  
}  
复制代码
public interface ProceedingJoinPoint extends JoinPoint {
    void set$AroundClosure(AroundClosure var1);
    Object proceed() throws Throwable;
    Object proceed(Object[] var1) throws Throwable;
}
复制代码
  • 由上可知可以通过各种get方法获取参数
Strign className = joinPoint.getTarget().getClass();
String methodName = joinPoint.getSignature().getName();
复制代码

以 注解值+类名+方法名+区域代码拼接的string为key,joinpoint.proceed()执行后返回值作为value,存入redis中作为缓存。

每日一题

题目

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,3,2] 输出: 3

思路1

遍历数组,将数存储在set中,求和得到sum1。原数组求和得到sum2.(sum1*3-sum2)/2即为结果。

思路2

网上大佬曾经说,如果能设计一个状态转换电路,使得一个数出现3次时能自动抵消为0,最后剩下的就是只出现1次的数。

开始设计:一个二进制位只能表示0或者1。也就是天生可以记录一个数出现了一次还是两次。

x ^ 0 = x; x ^ x = 0; 要记录出现3次,需要两个二进制位。那么上面单独的x就不行了。我们需要两个变量,每个变量取一位:

ab ^ 00 = ab; ab ^ ab = 00; 这里,a、b都是32位的变量。我们使用a的第k位与b的第k位组合起来的两位二进制,表示当前位出现了几次。也就是,一个8位的二进制x就变成了16位来表示。

x = x[7] x[6] x[5] x[4] x[3] x[2] x[1] x[0]

x = (a[7]b[7]) (a[6]b[6]) ... (a[1]b[1]) (a[0]b[0])

于是,就有了这一幕....

它是一个逻辑电路,a、b变量中,相同位置上,分别取出一位,负责完成00->01->10->00,也就是开头的那句话,当数字出现3次时置零。

代码
int singleNumber(vector<int>& nums) {
    int a = 0, b = 0;
    for (auto x : nums) {
        b = (b ^ x) & ~a;
        a = (a ^ x) & ~b;
    }
    return b;
}
复制代码

转载于:https://juejin.im/post/5ce4b7f2f265da1bac3fec9b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值