来源不详了
原文地址: Java 基础面试题-20211228
欢迎访问我的博客: http://blog.duhbb.com/
下面通过一张图来对比两者的区别:
区别 | 重定向 | 请求转发 |
---|---|---|
在哪里完成 | 客户端完成 (可以在不同的服务器下完成) | 服务器端完成 (必须是在同一台服务器下完成) |
浏览器发送请求的次数 | 2 次或者 2 次以上 | 1 次 |
地址栏 URL 是否发生改变 | 地址栏发生变化 | 地址栏的地址不变 |
是否共享 request | 不共享数据 (经过重定向后,request 内的对象将无法使用) | 共享数据 (以前的 request 中存放的变量不会失效, 就像把两个页面拼到了一起) |
第二次请求发起者 | 浏览器 | 服务器 |
第二次的请求路径方式 | 绝对路径 | 相对路径 |
速度 | 因为还要浏览器发送第二次请求, 重定向相对慢一点 | 快 |
语句 | response.sendRedirect("success.jsp"); | request.getRequestDispatcher("success.jsp").forward(request,response); |
原文链接:https://blog.csdn.net/Weixiaohuai/article/details/103991831
区别如下:
作者:hunter886 链接:https://www.jianshu.com/p/5c34133ed372
来源: 简书
著作权归作者所有. 商业转载请联系作者获得授权, 非商业转载请注明出处.
那为什么 HashTable 的 key 或者 value 不能为 null 呢?
以下回答摘自 stackoverflow: Hashtable 是较古老的类, 通常不鼓励使用它.
在之后的使用中, 设计人员发现开发中通常需要一个空键或者空值, 于是就在 HashMap 中增加了对 null 的支持.
HashMap 最为 HashTable 之后实现的类, 具有更高级的功能, 这基本上只是对 Hashtable 功能的改进.
创建 HashMap 时, 它专门设计为将空值作为键处理并将其作为特殊情况处理.
补充:JDK 源码中作者的注释:
To successfully store and retrieve objects from a Hashtable, the objects used as keys must implement the hashCode method and the equals method.
要从 Hashtable 成功存储和检索对象, 用作键的对象必须实现 hashCode 方法和 equals 方法.
由于 null 不是对象, 因此不能在其上调用 equals() 或 hashCode(), 因此 Hashtable 无法将其计算哈希值以用作键.
作者: 王李红
链接:https://www.zhihu.com/question/264749854/answer/773203452
来源: 知乎
著作权归作者所有. 商业转载请联系作者获得授权, 非商业转载请注明出处.
所谓死锁, 是指多个进程在运行过程中因争夺资源而造成的一种僵局, 当进程处于这种僵持状态时, 若无外力作用, 它们都将无法再向前推进. 因此我们举个例子来描述, 如果此时有一个线程 A, 按照先锁 a 再获得锁 b 的的顺序获得锁, 而在此同时又有另外一个线程 B, 按照先锁 b 再锁 a 的顺序获得锁.
可归结为如下两点:
系统中的资源可以分为两类:
产生死锁中的竞争资源之一指的是竞争不可剥夺资源 (例如: 系统中只有一台打印机, 可供进程 P1 使用, 假定 P1 已占用了打印机, 若 P2 继续要求打印机打印将阻塞)
产生死锁中的竞争资源另外一种资源指的是竞争临时资源 (临时资源包括硬件中断, 信号, 消息, 缓冲区内的消息等), 通常消息通信顺序进行不当, 则会产生死锁
若 P1 保持了资源 R1,P2 保持了资源 R2, 系统处于不安全状态, 因为这两个进程再向前推进, 便可能发生死锁.
例如, 当 P1 运行到 P1:Request(R2) 时, 将因 R2 已被 P2 占用而阻塞;当 P2 运行到 P2:Request(R1) 时, 也将因 R1 已被 P1 占用而阻塞, 于是发生进程死锁
产生死锁的必要条件:
1 以确定的顺序获得锁
如果必须获取多个锁, 那么在设计的时候需要充分考虑不同线程之前获得锁的顺序.
针对两个特定的锁, 开发者可以尝试按照锁对象的 hashCode 值大小的顺序, 分别获得两个锁, 这样锁总是会以特定的顺序获得锁, 那么死锁也不会发生. 问题变得更加复杂一些, 如果此时有多个线程, 都在竞争不同的锁, 简单按照锁对象的 hashCode 进行排序 (单纯按照 hashCode 顺序排序会出现"环路等待"), 可能就无法满足要求了, 这个时候开发者可以使用银行家算法, 所有的锁都按照特定的顺序获取, 同样可以防止死锁的发生, 该算法在这里就不再赘述了, 有兴趣的可以自行了解一下.
2 超时放弃
当使用 synchronized 关键词提供的内置锁时, 只要线程没有获得锁, 那么就会永远等待下去, 然而 Lock 接口提供了 boolean tryLock(long time, TimeUnit unit) throws InterruptedException 方法, 该方法可以按照固定时长等待锁, 因此线程可以在获取锁超时以后, 主动释放之前已经获得的所有的锁. 通过这种方式, 也可以很有效地避免死锁.
预防死锁的几种策略, 会严重地损害系统性能. 因此在避免死锁时, 要施加较弱的限制, 从而获得 较满意的系统性能. 由于在避免死锁的策略中, 允许进程动态地申请资源. 因而, 系统在进行资源分配之前预先计算资源分配的安全性. 若此次分配不会导致系统进入不安全的状态, 则将资源分配给进程;否则, 进程等待. 其中最具有代表性的避免死锁算法是银行家算法.
银行家算法: 首先需要定义状态和安全状态的概念. 系统的状态是当前给进程分配的资源情况. 因此, 状态包含两个向量 Resource(系统中每种资源的总量) 和 Available(未分配给进程的每种资源的总量) 及两个矩阵 Claim(表示进程对资源的需求) 和 Allocation(表示当前分配给进程的资源). 安全状态是指至少有一个资源分配序列不会导致死锁. 当进程请求一组资源时, 假设同意该请求, 从而改变了系统的状态, 然后确定其结果是否还处于安全状态. 如果是, 同意这个请求;如果不是, 阻塞该进程知道同意该请求后系统状态仍然是安全的.
死锁检测的工具
当发现有进程死锁后, 便应立即把它从死锁状态中解脱出来, 常采用的方法有:
原文链接: https://www.cnblogs.com/crazymakercircle/p/14323919.html
所谓深浅拷贝, 都是进行复制, 那么区别主要在于复制出来的新对象和原来的对象是否会互相影响, 改一个, 另一个也会变.
深浅拷贝的主要区别就是: 复制的是引用 (地址) 还是复制的是实例.
https://github.com/YvetteLau/Step-By-Step/issues/17#issuecomment-497601234
感觉这个问题有点弱智:
if (1 == 2) {
System.out.println("never get here!");
}
你说这个会执行吗?
原文地址: Java 基础面试题-20211228
欢迎访问我的博客: http://blog.duhbb.com/
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。