0%

MySQL范式与反模式

第一范式

每列都保持原子性。

举个例子,活动表(活动编码,活动名称,活动地址),假设这个场景中,活动地址可以细分为国家、省份、城市、市区、位置,那么就没有达到第一范式。

第二范式

非主属性不部分依赖于候选码。

举个例子,版本表(版本编码,版本名称,产品编码,产品名称),其中主键是(版本编码,产品编码),这个场景中,数据库设计并不符合第二范式,因为产品名称只依赖于产品编码。存在部分依赖。所以,为了使其满足第二范式,可以改造成两个表:版本表(版本编码,产品编码)和产品表(产品编码,产品名称)。

阅读全文 »

什么是Java虚拟机?

Java虚拟机是一个可以执行Java字节码(Java 源文件被编译成能被 Java 虚拟机执行的字节码文件( .class ))的虚拟机进程。

Java 被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java 虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。

但是,跨平台的是 Java 程序(包括字节码文件),,而不是 JVM。JVM 是用 C/C++ 开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本的 JVM 。

阅读全文 »

Java中用到的线程调度算法是什么

有两种调度模型:分时调度模型和抢占式调度模型。

  • 分时调度模型是指让所有的线程轮流获得 CPU 的使用权,并且平均分配每个线程占用的 CPU 的时间片这个也比较好理解。

  • Java 虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用 CPU ,如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用 CPU 。处于运行状态的线程会一直运行,直至它不得不放弃 CPU 。

阅读全文 »

Spring MVC 各组件以及功能

  • MultipartResolver:内容类型( Content-Type )为 multipart/* 的请求的解析器接口
  • LocaleResolver:本地化( 国际化 )解析器接口
  • ThemeResolver:主题解析器接口(例如,从请求头 User-Agent ,判断使用 PC 端,还是移动端的主题)
  • HandlerMapping:处理器匹配接口,根据请求( handler )获得其的处理器( handler )和拦截器们( HandlerInterceptor 数组 )
  • HandlerAdapter:处理器适配器接口
  • HandlerExceptionResolver:处理器异常解析器接口,将处理器( handler )执行时发生的异常,解析( 转换 )成对应的 ModelAndView 结果
  • RequestToViewNameTranslator:请求到视图名的转换器接口
  • ViewResolver:实体解析器接口,根据视图名和国际化,获得最终的视图 View 对象
  • FlashMapManager:FlashMap 管理器接口,负责重定向时,保存参数到临时存储中
阅读全文 »

如果你对 “如何充分利用你的24小时”感兴趣,我推荐你读《时间管理 如何充分利用你的24小时》漫画版。

以下是我个人从书中学到的以及一些自己的体会。

意识到自己的时间花费在什么地方

每天睡觉之前的时间,可以总结一下当天都做什么事情,分别花费了多少时间。画一个如下类似的表格:

时间段 内容 时间
02:30-12:00 睡觉 9.5小时
14:00-20:00 打王者荣耀 6小时
19:00-22:00 看电视剧 5小时
23:00-24:00 定外卖吃饭 3小时

这样可以清晰看到自己在某件事情上花费的时间,可以根据自己的情况在计划表中减少或者增加。

阅读全文 »

什么是面向对象?

面向过程是分析出实现需求所需要的步骤,通过函数一步一步实现这些步骤,然后依次调用。将实现步骤化

面向对象是把整个需求按照特点、功能划分,将这些存在共性的部分封装成对象。创建对象不是为了完成某一个步骤,而是描述某个事物在解决问题中的行文。将实现行为化

面向对象的特征

  • 封装:隐藏对象内部的特性和行为。
  • 继承:子类继承父类的特性和行为。
  • 多态:不同类的对象,对同一消息,做出不同响应。
  • 抽象:把一类事物共有的属性和行为提出来,形成一个模板。

重载和重写的区别

  • 重写 override
    • 方法名、参数、返回值相同
    • 方法被定义为final 不能被重写
    • 存在于父类和子类之间
  • 重载 overload
    • 参数类型、个数、顺序至少有一个不同
    • 不能重载只有返回值不同的方法名
    • 存在于父类和子类、同类中
阅读全文 »

贪心算法思想

贪心算法就是这样的算法,它在每一步都做出当时看起来最佳的选择。也就是说它总是做出局部最优的选择,寄希望这样的选择导致全局最优解。

贪心算法并不保证得到最优解,但很多问题确实可以求得最优解。

我们可以按如下步骤设计贪心算法:

  1. 将最优化问题转化为这样的形式:对其做出一次选择后,只剩下一个子问题需要求解。
  2. 证明做出贪心选择后,原问题总是存在最优解,即贪心选择总是安全的。
  3. 证明做出选择后,剩余的子问题满足性质:其最优解与贪心选择组合即可得到原问题的最优解,这样就得到了最优子结构。
阅读全文 »

动态规划算法思想

动态规划(dynamic programming)与分治方法相似,都是通过组合子问题的解来求解原问题(在这里,programming 指的是一种表格法)。分治法将问题划分为互不相交的子问题,再将他们的解组合起来,求出原问题的解。与之相反,动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子问题(子问题的求解释递归进行的,将其划分为更小的子子问题)。在这种情况下,分治法会做许多不必要的工作,它会反复求解那些公共子问题。而动态规划算法对每个子问题只求解一次,将其解保存在一个表格中,从而无需每次求解一个子问题时都重新计算,避免了这种不必要的计算工作。

适用场景

动态规划方法通常用来求解最优化问题。这类问题可以有很多可行解,每个解都有一个值,我们希望寻找具有最优值(最小值或最大值)的解。我们称这样的解为问题的一个最优解(an optimal solution),而不是最优解(the optimal solution),因为可能有多个解都达到最优值。

阅读全文 »