人工智能理论基础

目录 技术

机器学习、深度学习和深度神经网络三者之间存在着紧密的关系

一、机器学习
机器学习是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。它专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

  • 主要特点:
    • 依靠数据:通过大量的数据进行训练,从中发现规律和模式。
    • 算法多样:包括监督学习、无监督学习、半监督学习、强化学习等多种学习方式,每种方式下又有众多具体的算法,如决策树、支持向量机、K 近邻等。
  • 应用领域:广泛应用于图像识别、语音识别、自然语言处理、推荐系统等众多领域。

继续阅读 “人工智能理论基础”

基于Redis实现分布式锁

目录 技术
一个好的分布式锁需要能保证以下几个条件:
  • 互斥性(在任意时刻,只有一个客户端能持有锁)
  • 安全性(加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了)
  • 不会发生死锁(即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁)
  • 容错性(当部分节点宕机客户端仍然能获取锁或释放锁)

正确加锁姿势:
一些老的写法是通过setnx key value和expire配合实现,但是因为是分成两步所以不能保证原子性,所以一旦在setnx后redis宕机了,那expire就不能设置成功,导致死锁。
新写法redis支持set直接设置过期时间,这种方式可以保证原子性。set key value [EX seconds][PX milliseconds][NX|XX],并且满足分布式锁的四个条件。

正确解锁姿势:
先获取锁对应的value值,检查是否与requestId相等,如果相等则删除key(解锁)。redis支持通过eval命令执行Lua脚本,这样能保证原子性,在eval命令执行Lua代码的时候,Lua代码将被当成一个命令去执行,并且直到eval命令执行完成,Redis才会执行其他命令。

JDK动态代理和cglib的区别

目录 技术
分类:
  • 基于接口的动态代理
  • 基于子类的动态代理
cglib基于子类的动态代理:
  • 涉及的类:Enhancer
  • 提供者:第三方cglib库
-如何创建代理对象:
  • 使用Enhancer类中的create方法
-创建代理对象的要求:
  • 被代理类不能是最终类
-newProxyInstance方法的参数:在使用代理时需要转换成指定的对象
  • ClassLoader:类加载器,用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法
  • Callback:用于提供增强的代码,一般写的都是该接口的子接口实现类,MethodInterceptor

继续阅读 “JDK动态代理和cglib的区别”

J.U.C工具包之CyclicBarrier

目录 技术

什么是CyclicBarrier:

  • CyclicBarrier可以在构造时指定需要在屏障前执行await的个数,所有对await的调用都会等待,直到调用await的次数达到预定指,所有等待都会立即被唤醒。
  • 从使用场景上来说,CyclicBarrier是让多个线程互相等待某一事件的发生,然后同时被唤醒。而CountDownLatch是让某一线程等待多个线程的状态,然后该线程被唤醒。
  • 例子:
    继续阅读 “J.U.C工具包之CyclicBarrier”

    J.U.C工具包之CountDownLatch

    目录 技术

    什么是CountDownLatch:

  • countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
  • 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
  • 例子:
    继续阅读 “J.U.C工具包之CountDownLatch”

    你需要知道的那些文件描述符

    目录 技术

    什么是文件描述符:

    • 内核利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
    • 每一个进程在内核中,都对应有一个“打开文件”数组,存放指向文件对象的指针,而 fd 是这个数组的下标。
    • 我们对文件进行操作时,系统调用,将fd传入内核,内核通过fd找到文件,对文件进行操作。

    既然是数组下标,fd的类型为int, < 0 为非法值, >=0 为合法值。在linux中,一个进程默认可以打开的文件数为1024个,fd的范围为0~1023。可以通过设置,改变最大值。
    在linux中,值为0、1、2的fd,分别代表标准输入、标准输出、标准错误输出。因为 0 1 2已经被linux使用了,通常在程序中打开的fd,是从3开始的。但我们在判断一个fd是否合法时,依然要使用>=0的判断标准。
    fd的分配原则,是从小到大,找到第一个不用的进行分配。除了open之外, socket编程的socket()/accept()等函数,也会返回一个fd值。

    查看文件描述符:

  • Linux系统下,所有进程允许打开的最大fd数量。查询语句:
  • Linux系统下,所有进程已经打开的fd数量及允许的最大数量。查询语句:
  • 单个进程允许打开的最大fd数量.查询语句:
  • 单个进程已经打开的fd.查询语句:
  • 通过反射简化模型中多次get set方法

    目录 技术

    在某些场景里Javabean包含了大量的字段,很多程序员会通过一个一个set get来匹配,这种写法不但繁琐而且代码冗余不好看且维护起来很麻烦,我们可以通过反射来解决:

    之后如果DemoModel再扩展字段,不再需要额外地写set、get,只要满足set、get的命名规范约定,直接在paramList里面补充字段名字就可以,后续可扩展性好很多。

    根据前序、中序、后序遍历的结果还原二叉树

    目录 技术
    • 已知二叉树的前序遍历和中序遍历可以得到原二叉树

    • 同样已知二叉树的中序遍历和后序遍历可以得到原二叉树