安全性:
端口号:
证书:
URL:
性能:
搜索引擎优化 (SEO) 优势:
用户信任:
MySQL 中的索引主要是通过数据结构来加速查询操作。最常用的数据结构是 B-Tree 和 B+Tree,尤其是 InnoDB 存储引擎中的 B+Tree。此外,有些 MySQL 存储引擎(例如 MEMORY)支持使用哈希索引。
以下是 MySQL 中常见的索引及其底层实现的简要描述:
B+Tree 索引:
哈希索引:
左连接(LEFT JOIN):
右连接(RIGHT JOIN):
总结:
JWT 的优点:
简洁和自包含:JWT 可以包含所有必要的信息,避免了每次都需要查询数据库来检索用户信息。
跨域认证:由于 JWT 是自包含的,它适合跨域认证场景,特别是在移动应用中。
无状态性:JWT 使得应用服务器可以完全无状态,从而简化了扩展应用服务器的复杂性。
性能:JWT 提供了一种避免每次请求都访问数据库的方法,从而提高性能。
适用于移动设备:由于其大小通常较小并且编码为字符串,JWT 非常适合 HTTP 头部传输,尤其在移动网络环境中。
安全:使用强加密算法(例如 RS256)可以验证 JWT 的发送者、接收者和内容的完整性。
JWT 的缺点:
大小:与简单的令牌或 cookie 相比,JWT 通常较大。当在 HTTP 头部中使用它时,这可能会增加所有请求的大小。
加密复杂性:虽然 JWT 可以加密数据,但实现和维护加密需要额外的复杂性。
无法从服务器端废除:由于 JWT 是无状态的,一旦颁发了一个 JWT,它会在其过期时间之前一直有效,除非客户端删除它。这意味着撤销或更改 JWT 的权限在其过期之前可能会更具挑战性。
存储安全问题:JWT 在客户端存储可能遭受跨站点脚本攻击 (XSS)。攻击者可能会尝试获取存储在客户端的 JWT。
过期策略:JWT 的有效性完全依赖于过期策略。如果你设置了一个很长的过期时间,攻击者可能有足够的时间利用一个窃取的令牌;如果设置得太短,用户体验可能会受到影响。
依赖于签名算法:JWT 的安全性完全依赖于其使用的签名算法。一些算法,如 "none" 或弱加密算法,可能被攻击。
轮询 (Round Robin):
权重 (Weighted Round Robin):
weight
参数可以指定后端服务器的权重。server backend1.example.com weight=3;
会使 backend1.example.com
接收到的请求是其他默认权重服务器的三倍。最少连接 (Least Connections):
IP 散列 (IP Hash):
通用散列 (Generic Hash):
使用第三方模块的策略:
sticky
模块可以使用户的请求在会话期间“粘滞”在同一个后端服务器。备份 (Backup) 服务器:
数据库事务是对数据库中数据进行管理的一个程序执行单元(可以理解为一组操作)。事务的主要目的是确保这组操作要么全部执行,要么全部不执行,从而保持数据库的完整性和一致性。简而言之,事务是一组原子性的 SQL 语句,或者说是一个原子操作序列
RESTful API:
gRPC:
原子性 (Atomicity):
一致性 (Consistency):
隔离性 (Isolation):
持久性 (Durability):
内存穿透:
缓存击穿:
缓存雪崩:
抽象类(Abstract Class)和接口(Interface)都是面向对象编程中用于实现抽象性和多态性的高级结构。尽管它们在某些方面有相似之处,但在设计和使用上存在几个关键的差异。以下是它们之间的主要区别:
基本定义:
继承和实现:
访问修饰符:
成员变量:
多继承:
添加新方法:
构造函数和静态块:
状态和行为:
当你在设计时决定使用抽象类还是接口时,考虑以下几点:
提高查询速度:索引允许数据库系统不必扫描整个表,可以直接定位到相关的数据行,大大减少查询时间。
加速表连接:对于多表查询(例如使用 JOIN 操作),索引可以极大地加速表间的连接操作。
确保数据的唯一性:通过为表中的某列或列组合创建唯一索引,可以确保每行数据在这些列上的值是唯一的。
提高数据排序和分组速度:索引可以加速 ORDER BY
和 GROUP BY
操作。
辅助数据库优化器:数据库优化器使用索引统计信息来选择最有效的查询执行计划。
使用 EXPLAIN:大多数关系数据库管理系统提供了 EXPLAIN
命令或相似的工具,允许你看到查询执行计划。这可以帮助你确定查询是否使用了索引。
避免使用非索引列进行计算:例如,WHERE year(birth_date) = 1990
这样的查询可能不会利用 birth_date
上的索引。
使用索引列的前缀:如果有一个多列的复合索引,那么查询条件应至少使用索引的第一列。
避免使用OR
:例如,WHERE col1 = value1 OR col2 = value2
。除非两个列都已经被索引,否则该查询可能不会使用索引。
确保数据类型匹配:确保查询中的数据类型与表中的数据类型(以及索引的数据类型)相匹配,以避免隐式数据类型转换,这可能会导致索引不被使用。
使用参数化查询:这不仅可以帮助避免 SQL 注入,还可以使数据库更容易地识别并重用执行计划。
定期维护和重新组织索引:随着时间的推移,索引可能会碎片化,导致其效率降低。定期优化或重建索引可以确保它们的效率。
避免使用 SELECT *
:尽量只查询你需要的列,这样可以更有效地使用覆盖索引。
避免使用 NOT、LIKE 以%开头的查询:这些查询往往无法有效地使用索引。
更新统计信息:数据库通常维护关于数据分布的统计信息,这有助于优化器选择最佳的执行计划。确保这些统计信息是最新的。
Synchronized:Java 中的关键字,它提供的锁是非公平的可重入锁。可以同步代码块或方法。
ReentrantLock:从 java.util.concurrent.locks 包中的一个类。它是一个互斥锁,并且是完全可重入的。ReentrantLock 允许选择公平性,也提供了更多的功能,如中断的锁获取操作、超时的锁获取等。
ReadWriteLock:它包含两个锁,一个是读锁,另一个是写锁。读锁可以由多个线程同时持有,写锁是互斥的。ReentrantReadWriteLock 是其常用实现。
使用 sort
和 uniq
命令是一个常见的方法。以下是如何删除文件中的重复行:
sort filename | uniq > newfile
其中 filename
是你要处理的文件名,newfile
是输出的文件名。这将会把 filename
中的行排序,并使用 uniq
命令删除连续的重复行。
(1)功能性测试:
正常流程:
a. 访问抖音应用,查看视频推荐页面是否正常加载。
b. 检查所有外部链接和资源(例如,视频、图片、脚本、CSS)是否都是https。
c. 在视频推荐中点击一段视频,确保视频正常播放。
d. 进行一些常规的操作,如点赞、评论和分享,确保这些功能在https下正常工作。
异常处理:
a. 当使用http URL尝试访问时,应自动重定向到https版本。
b. 使用过期或无效的SSL证书访问,应显示警告。
(2)安全性测试:
a. 验证所有数据传输是否加密。
b. 在浏览器中检查是否有任何http内容泄露到https页面。
c. 检查中间人攻击的可能性。
d. 使用安全扫描工具检查应用的安全性。
(3)性能测试:
a. 比较http和https下的页面加载时间。
b. 在多用户并发访问的情况下,检查服务器的响应时间。
c. 在不同的网络环境中(如WiFi, 4G, 3G)检查性能差异。
(4)兼容性测试:
a. 使用各种浏览器(如Chrome、Firefox、Safari、Edge等)访问,确保页面正常显示。
b. 在不同的设备上(如手机、平板、桌面)测试功能。
c. 在旧的浏览器版本上,检查是否提示用户升级或显示警告。
(5)持续集成/部署测试:
a. 确保在部署新代码时,所有资源仍然是https。
b. 在新代码部署后,自动执行上述所有测试用例。
(6)用户体验测试:
a. 与http版本相比,评估https版本的用户体验。
b. 从用户角度,提供有关https迁移的反馈。
(7)回滚测试:
a. 在遇到任何关键问题时,确保有回滚到http的策略。
b. 在必要时测试这一回滚策略。
a. 正常流程:
b. 异常情况:
c. 并发:
(1)功能性测试:
正常流程:
a. 在秒杀开始时,检查特定的秒杀商品是否显示为可用。
b. 成功选购秒杀商品并完成结账流程。
c. 一旦商品被秒杀完,检查是否显示“已售罄”或类似提示。
d. 确保购买的商品在用户的订单历史中正确显示。
异常处理:
a. 尝试在秒杀开始前和结束后购买商品,应得到一个提示或错误消息。
b. 当商品卖完但用户仍在购买流程中时,应当给予适当的提示。
c. 在结账过程中,尝试更改商品价格或数量,确保系统不允许这种行为。
(2)并发和性能测试:
a. 模拟高并发场景,例如使用多个用户同时尝试购买同一商品。
b. 检查系统在高流量下的响应时间。
c. 使用压力测试工具模拟大量用户在秒杀开始时同时访问网站。
d. 检查数据库和服务器资源使用情况,确保没有明显的瓶颈或资源耗尽。
(3)安全性和抗攻击测试:
a. 检查是否可以通过脚本或自动化工具进行购买。
b. 尝试使用SQL注入、XSS攻击或其他常见的Web攻击技巧。
c. 确保支付过程安全,数据传输加密。
(4)用户体验和界面测试:
a. 确保所有关于秒杀的信息、时间和提示都清晰可见。
b. 在不同的设备和浏览器上测试用户界面,确保兼容性。
c. 检查是否有明确的错误和成功消息供用户参考。
(5) 稳定性和恢复测试:
a. 模拟服务器或数据库故障,看看系统如何响应。
b. 在高压力情况下重启服务器,检查恢复时间。
(6)数据一致性测试:
a. 确保所有成功的购买都正确记录。
b. 检查商品库存和实际销售数量是否匹配。
(7)网络和基础设施测试:
a. 模拟网络延迟和中断,查看系统的反应。
b. 检查CDN和负载均衡器是否正确配置和工作。
a. 正常流程:
b. 异常情况:
a. 正常流程:
b. 异常情况:
a. 正常流程:
b. 输入验证:
c. 异常情况:
d. 安全性:
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
int temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (int i = 0; i < n; i++) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
DELETE t1 FROM mytable t1
JOIN mytable t2
ON t1.name = t2.name
WHERE t1.id > t2.id;
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode a = headA, b = headB;
while (a != b) {
a = (a != null) ? a.next : headB;
b = (b != null) ? b.next : headA;
}
return a;
}
public String longestPalindrome(String s) {
if (s == null || s.length() < 1) return "";
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
private int expandAroundCenter(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}