面试题 - 使用线程交替打印奇数偶数

这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书

  • 分析题目。需要使用两个线程交替打印奇偶数。
    • 使用同步锁解决这个问题
    • 使用信号量来实现交替打印
  • 定义两个信号量,一个奇数信号量,一个偶数信号量,都初始化为1
  • 先用掉偶数的信号量,因为要让奇数先启动,等奇数打印完再释放

信号量实现

  • 具体实现思路:
    • 定义两个信号量,一个奇数信号量,一个偶数信号量,都初始化为1
    • 先用掉偶数的信号量,因为要让奇数先启动,等奇数打印完再释放
    • 具体流程就是 第一次的时候先减掉偶数的信号量 奇数线程打印完成以后用掉奇数的信号量。然后释放偶数的信号量如此循环
阅读更多

拦截器和过滤器的区别

1.过滤器:依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等

2.拦截器:依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理3.过滤器和拦截器的区别:

  • ①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  • ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  • ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  • ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  • ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  • ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。过滤器
阅读更多

Java 设计模式

设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结

  • 设计模式分为 23 种经典的模式,根据用途我们又可以分为三大类。分别是创建型模式、结构型模式和行为型模式
  • 列举几种设计原则,这几种设计原则将贯通全文:
    • 面向接口编程,而不是面向实现。这个尤为重要,也是优雅的、可扩展的代码的第一步,这就不需要多说了吧
    • 职责单一原则。每个类都应该只有一个单一的功能,并且该功能应该由这个类完全封装起来
    • 对修改关闭,对扩展开放。对修改关闭是说,我们辛辛苦苦加班写出来的代码,该实现的功能和该修复的 bug 都完成了,别人可不能说改就改;对扩展开放就比较好理解了,也就是说在我们写好的代码基础上,很容易实现扩展。
阅读更多

Java集合框架

前言

  Java集合框架 (Java Collections Framework, JCF) 也称容器,这里可以类比 C++ 中的 STL,在市面上似乎还没能找到一本详细介绍的书籍。在这里主要对如下部分进行源码分析,及在面试中常见的问题。

  例如,在阿里面试常问到的 HashMap 和 ConcurrentHashMap 原理等等。深入源码分析是面试中必备的技能,通过本文的阅读会对集合框架有更深一步的了解。

阅读更多

Spring Bean 生命周期

Spring Bean 生命周期

前言

Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。

首先看下生命周期图:

阅读更多

java防止接口被篡改--接口签名(简单版本)续

一、前言

  • 此次来说一下另一种简单粗暴的签名方案。相对于之前的签名方案,对body、paramenter、path variable的获取都做了简化的处理。也就是说这种方式针所有数据进行了签名,并不能指定某些数据进行签名。

二、签名规则

  • 1、线下分配appidappsecret,针对不同的调用方分配不同的appidappsecret

  • 2、加入timestamp(时间戳),10分钟内数据有效

  • 3、加入流水号nonce(防止重复提交),至少为10位。针对查询接口,流水号只用于日志落地,便于后期日志核查。 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。

  • 4、加入signature,所有数据的签名信息。

  • 以上红色字段放在请求头中。

阅读更多

java防止接口被篡改--接口签名(Signature)

前言

  •  在为第三方系统提供接口的时候,肯定要考虑接口数据的安全问题,比如数据是否被篡改,数据是否已经过时,数据是否可以重复提交等问题。其中我认为最终要的还是数据是否被篡改。在此分享一下我的关于接口签名的实践方案。

签名规则

  • 1、线下分配appidappsecret,针对不同的调用方分配不同的appidappsecret
  • 2、加入timestamp(时间戳),10分钟内数据有效
  • 3、加入流水号nonce(防止重复提交),至少为10位。针对查询接口,流水号只用于日志落地,便于后期日志核查。 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。
  • 4、加入signature,所有数据的签名信息。以上红色字段放在请求头中。
阅读更多

网站防止恶意登陆或防盗链的使用

  • 使用场景:明明引用了一个正确的图片地址,但显示出来的却是一个红叉或写有“此图片仅限于网站用户交流沟通使用”之类的“假图片”。用嗅探软件找到了多媒体资源的真实地址用下载软件仍然不能下载。下载一些资源时总是出错,如果确认地址没错的话,大多数情况都是遇上防盗链系统了。常见的防盗链系统,一般使用在图片、音视频、软件等相关的资源上。

  • 实现原理:把当前请求的主机与服务器的主机进行比对,如果不一样则就是恶意链接,反之则是正常链接。

  • 不说了,直接上代码:

阅读更多

Mybatis Plus的分页插件的小问题

一、前言

在spring Boot环境下快速应用Mybatis plus,篇幅中我们使用了BaseMapper,从而可以直接使用selectPage这样的分页,但如果你够细心的话,返回的数据确实是分页后的数据,但在控制台打印的SQL语句其实并没有真正的物理分页,而是通过缓存来获得全部数据中再进行的分页,这样对于大数据量操作时是不可取的,那么接下来就叙述一下,真正实现物理分页的方法。

二、分页配置

官方在分页插件上如是描述:自定义查询语句分页(自己写sql/mapper),也就是针对自己在Mapper中写的方法,但经过测试,如果不配置分页插件,其默认采用的分页为RowBounds的分页即逻辑分页,也就是先把数据记录全部查询出来,然在再根据offset和limit截断记录返回(数据量大的时候会造成内存溢出),故而不可取,而通过分页插件的配置即可达到物理分页效果。

阅读更多

记一次事务的坑 Transaction rolled back because it has been marked as rollback-only

最近在项目中发现了一则报错:“org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only”。根据报错信息来看是spring框架中的事务管理报错:事务回滚了,因为它被标记为回滚状态。

报错原因

多层嵌套事务中,如果使用了默认的事务传播方式,当内层事务抛出异常,外层事务捕捉并正常执行完毕时,就会报出rollback-only异常。

阅读更多