前端实现登录拼图验证

news2024/11/23 17:25:49

前言

不知各位朋友现在在 web 端进行登录的时候有没有注意一个变化,以前登录的时候是直接账号密码通过就可以直接登录,再后来图形验证码,数字结果运算验证,到现在的拼图验证。这一系列的转变都是为了防止机器操作,但对于我们来说,有亿点麻烦,但也没办法呀。

今天我们也一起实现一个拼图验证。

核心功能

  • 滑动解锁功能
  • 重置位置功能
  • 滑块进度条功能
  • 结果提示功能
  • 随机生成滑块位置

实现原理

这个的实现原理并不复杂,我们只需要一张背景图作为我们的拼接素材,再单独定义一个盒子并拖拽移动它到指定位置就可以完成拼图验证功能了

实现前端登录拼图验证

搭建框架

我们要实现这个功能,我们需要先搭建出来一个样式结构出来。

// css
:root {
	 --iWidth: 50px;
	 --iHeight: 50px;
}

.wrapper {
    width: 100%;
    width: 500px;
    margin: 0 auto;
}

.container {
    position: relative;
    width: 500px;
    height: 300px;
    box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.5);
    border-radius: 8px;
    background-image: url("./bg.webp");
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

// html
<div class="wrapper">
   <!-- 容器 -->
   <div class="container"></div>
</div>

我们根据刚才的样式结构搭建完成后,它就长下图这个样子
在这里插入图片描述

添加被校验区域及校验区域

我们需要添加一个被校验区域及校验区域,用来做我们的滑动校验
!!在滑动区域中使用 background-position 配合 background-size 根据校验区域的大小和位置切出滑动区域的图

// css
// 被校验区域样式
.container-move {
    position: absolute;
    width: var(--iWidth);
    height: var(--iHeight);
    top: 180px;
    left: 0;
    z-index: 3;
    background-size: 500px 300px;
    background-repeat: no-repeat;
    background-image: url("./img/bg.jpg");
    background-position: -180px -200px;
}
// 校验区域样式
.container-empty {
    position: absolute;
    width: var(--iWidth);
    height: var(--iHeight);
    top: 180px;
    left: 200px;
    background: #fff;
    z-index: 2;
    opacity: .6;
}
// html
<div class="wrapper">
    <!-- 容器 -->
    <div class="container">
    	<!-- 被校验区域 -->
        <div class="container-move"></div>
        <!-- 校验区域 -->
        <div class="container-empty"></div>
    </div>
</div>

效果图
在这里插入图片描述

添加滑块、滑块背景、拖动条、提示文字

拖动条来控制滑块移动的最大距离
滑块来控制被校验区域的移动距离
提示文字是提示用户这里可以操作解锁

拖动条内的滑块、滑块背景、提示文字都对拖动条进行绝对定位
主要是为了控制他们的层级,提示文字 < 滑块背景 < 滑块

我们添加滑块、滑块背景、拖动条、提示文字

// css
/* 拖动条样式 */
.slider-control {
    width: 500px;
    height: 50px;
    margin-top: 20px;
    border-radius: 4px;
    position: relative;
    overflow: hidden;
    background: #f2f2f2;
    box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
}

/* 滑块 */
.slider {
    width: var(--iWidth);
    height: var(--iHeight);
    position: absolute;
    left: 0;
    top: 0;
    background: skyblue;
    border-radius: 4px;
    text-align: center;
    line-height: var(--iHeight);
    transition: all;
    user-select: none;
    z-index: 3;
}

/* 滑块背景 */
.slider-shadow {
    position: absolute;
    left: 0;
    top: 0;
    width: 0;
    height: 50px;
    background: #fff;
    z-index: 2;
}

/* 提示文案 */
.slider-info {
    text-align: center;
    color: rgba(102, 102, 102, 1);
    margin: 0;
    line-height: 50px;
}
// html
<div class="wrapper">
    <!-- 控制容器 -->
    <div class="slider-control">
    	// 提示文字
        <p class="slider-info">按住左边按钮向右拖动完成上方图像验证</p>
         // 滑块
        <div class="slider">>></div>
        // 滑块背景
        <div class="slider-shadow"></div>
    </div>
</div>

效果图如下
在这里插入图片描述

添加交互

到这里拼图验证的样式结构已经完成了,接下来我们需要对相关的元素添加交互事件

让滑块可以在拖动条内随意拖拽

// 我太懒了,不想写那么一大堆,这里封装个用 class 来获取实例的函数
function getElement(elName) {
   return document.getElementsByClassName(elName)[0]
}

// 获取实例
let sliderBox = getElement('slider'); // 滑动的块
let sliderShadow = getElement('slider-shadow'); // 滑动背景

let container = getElement("container"); // 容器的实例
let sliderMove = getElement("container-move"); // 解锁的块

let containerWidth = container.clientWidth; // 获取容器的可视区宽度
let sliderMoveWidth = sliderMove.clientWidth; // 被校验区域的可视区宽度
        
let maxDistance = (containerWidth - sliderMoveWidth); // 根据容器和被校验区域的大小限制滑块移动最大的距离

/**
* 监听鼠标在sliderBox(滑动块)按下时 mousedowm, 并根据可视区左边的距离减去鼠标按下的距离, 获取到实际
* document的onmouseMove和mouseup事件,
* 获取鼠标滑动的位置
*/
sliderBox.onmousedown = function (moveStart) {
   // console.log("🚀 ~ file: index.html ~ line 94 ~ moveStart", moveStart)
   let left = moveStart.clientX - sliderBox.offsetLeft; // 获取按下时元素距离可视区左边的位置 - 鼠标按下时的位置, 获取到鼠标距离元素边缘的位置
   let lefta // 记录移动的距离
   // 鼠标按下持续移动中
   document.onmousemove = function (moveTo) {
       // 如果不减去 left 那么就会导致鼠标一直在移动元素的左边框上, 也就会出现元素不跟着鼠标走的问题, 有偏差
       lefta = moveTo.clientX - left; // 元素移动的距离
       // 限制元素的移动距离,不能小于0, 或者大于最大宽度 - 元素本身的距离, 否则就初始化位置
       if (lefta < 0) {
           lefta = 0;
       } else if (maxDistance < lefta) {
           lefta = maxDistance;
       }
       sliderBox.style.left = lefta + 'px';
       // 因为滑块加了圆角的功能,所以要在这里加4px,让滑块刚好压住滑块背景,不加的话,放大的时候会比较突兀
       sliderShadow.style.width = (lefta + 4) + 'px';
   }

   // 鼠标移动结束
   document.onmouseup = function (moveEnd) {
       // 解除document身上绑定的事件, 不让事件一直触发
       document.onmousemove = null;
       document.onmouseup = null;
       // 重置位置
       sliderBox.style.left = 0 + 'px'
       sliderShadow.style.width = 0 + 'px'
   }
}

通过我们上述代码实现的效果图,可以看到滑块可以在拖动条内随意拖动了,且滑块、滑块背景、文字的层级关系也处理好了
在这里插入图片描述

联动被校验区域

我们在上述内容中已经实现了滑块的自由拖拽,接下来就要联动被校验区域的滑动位置进行校验

// 获取实例以及定义常量
let faultSize = 10; // 滑动距离的容错处理, 滑动距离- 10, +10 都可解锁
// 事件处理
sliderBox.onmousedown = function (moveStart) {
    let left = moveStart.clientX - sliderBox.offsetLeft; // 获取按下时元素距离可视区左边的位置 - 鼠标按下时的位置, 获取到鼠标距离元素边缘的位置
    let lefta // 记录移动的距离
    // 鼠标按下持续移动中
    document.onmousemove = function (moveTo) {
        // 如果不减去 left 那么就会导致鼠标一直在移动元素的左边框上, 也就会出现元素不跟着鼠标走的问题, 有偏差
        lefta = moveTo.clientX - left; // 元素移动的距离
        sliderMove.style.left = lefta + 'px'
    }

    // 鼠标移动结束
    document.onmouseup = function (moveEnd) {
        // 判断滑动距离是否相同,这里的滑动距离允许10px的容错,所以在当被校验区域大于小于校验区域10px都可以校验通过
        if (lefta >= movePointer - faultSize && lefta <= movePointer + faultSize) {
            success(true)
        } else {
            success(false)
        }
        init()
        // 重置位置
        sliderBox.style.left = 0 + 'px'
        sliderMove.style.left = 0 + 'px'
        sliderShadow.style.width = 0 + 'px';
        infomation.innerText = ''
    }
}

function success(valid) {
    let text = valid ? '成功' : "失败"
    alert(`解锁${text}`)
}

在这里插入图片描述

通过我们的上述代码就已经实现了拼图验证的功能,我们有一个随机生成校验位置的功能没有实现,下面我们一起来实现一下吧

随机生成校验位置

在我们登录平台系统的时候,当我们的拼图没有移动到指定位置或移动错误的时候,都是需要重新生成校验位置的,所以拼图刷新功能还是很有必要的,下面我们就一起来实现一下吧。

// css
/* 重置 */
.container-reset {
   position: absolute;
   top: 0;
   right: 10px;
   cursor: pointer;
   user-select: none;
   z-index: 1;
   color:#fff;
}
// html
<div class="wrapper">
<!-- 解锁容器 -->
<div class="container">
   <div class="container-reset">刷新</div>
</div>
</div>
// js

// 获取实例
let containerReset = getElement('container-reset'); // 刷新按钮实例

// 初始化位置
init()
// 刷新拼图位置
containerReset.onclick = function () {
    init()
}
/**
 * 随机生成空白的位置, 并指定解锁块的高度
 *  */
function init() {
    const moveTop = Math.floor(Math.random() * 90); // 校验区域随机生成的 top 高度
    const moveLeft = Math.floor(Math.random() * (270 - 60) + 60); // 校验区域随机生成的 left 距离

    movePointer = moveLeft // 重置校验区域解锁的位置

    sliderMove.style.top = moveTop + 'px'; // 初始化被校验区域位置

    containerEmpty.style.top = moveTop + 'px'; // 初始化校验区域
    containerEmpty.style.left = moveLeft + 'px'; // 初始化校验区域

    sliderShadow.style.width = 0 + 'px'; // 重置拖拖动条阴影位置

    sliderMove.style.backgroundPosition = `-${moveLeft}px  -${moveTop}px`; // 裁剪被校验区域上的切图
}

在这里插入图片描述
到这里看一下我们都一起实现文章开头说的这些功能,是不是也没有想象中的那么难?

  • 滑动解锁功能
  • 重置位置功能
  • 滑块进度条功能
  • 结果提示功能
  • 随机生成滑块位置

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>滑动验证码</title>
    <style>
        :root {
            --iWidth: 50px;
            --iHeight: 50px;
        }

        .wrapper {
            width: 100%;
            width: 500px;
            margin: 0 auto;
        }

        /* 容器 */
        .container {
            position: relative;
            width: 500px;
            height: 300px;
            box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
            border-radius: 8px;
            background-image: url("./img/bg.jpg");
            background-size: 100% 100%;
            background-repeat: no-repeat;
        }

        /* 被校验区域 */
        .container-move {
            position: absolute;
            width: var(--iWidth);
            height: var(--iHeight);
            top: 180px;
            left: 0;
            z-index: 3;
            background-size: 500px 300px;
            background-repeat: no-repeat;
            background-image: url("./img/bg.jpg");
            background-position: -180px -200px;
        }

        /* 校验区域 */
        .container-empty {
            position: absolute;
            width: var(--iWidth);
            height: var(--iHeight);
            top: 180px;
            left: 200px;
            background: #fff;
            z-index: 2;
            opacity: .6;
        }

        /* 重置 */
        .container-reset {
            position: absolute;
            top: 0;
            right: 10px;
            cursor: pointer;
            user-select: none;
            z-index: 1;
            color:#fff;
        }

        /* 拖动条样式 */
        .slider-control {
            width: 500px;
            height: 50px;
            margin-top: 20px;
            border-radius: 4px;
            position: relative;
            overflow: hidden;
            background: #f2f2f2;
            box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
        }

        /* 滑块 */
        .slider {
            width: var(--iWidth);
            height: var(--iHeight);
            position: absolute;
            left: 0;
            top: 0;
            background: skyblue;
            border-radius: 4px;
            text-align: center;
            line-height: var(--iHeight);
            transition: all;
            user-select: none;
            z-index: 3;
        }

        /* 滑块背景 */
        .slider-shadow {
            position: absolute;
            left: 0;
            top: 0;
            width: 0;
            height: 50px;
            background: #fff;
            z-index: 2;
        }

        /* 提示文案 */
        .slider-info {
            text-align: center;
            color: rgba(102, 102, 102, 1);
            margin: 0;
            line-height: 50px;
            user-select: none;
        }
    </style>
</head>

<body>
    <div class="wrapper">
        <!-- 解锁容器 -->
        <div class="container">
            <div class="container-move"></div>
            <div class="container-empty"></div>
            <div class="container-reset">刷新</div>
        </div>
        <!-- 控制容器 -->
        <div class="slider-control">
            <p class="slider-info">按住左边按钮向右拖动完成上方图像验证</p>
            <div class="slider">>></div>
            <div class="slider-shadow"></div>
        </div>
        <p class="infomation"></p>
    </div>


    <script>
        let sliderBox = getElement('slider'); // 滑动的块

        let sliderShadow = getElement('slider-shadow'); // 滑动的阴影
        let container = getElement("container"); // 最外层的盒子
        let sliderMove = getElement("container-move"); // 解锁的块
        let containerEmpty = getElement("container-empty"); // 解锁的位置

        let infomation = getElement('infomation'); // 解锁提示
        let containerReset = getElement('container-reset'); // 重置功能

        let containerWidth = container.clientWidth; // 获取背景图的大小
        let sliderMoveWidth = sliderMove.clientWidth; // 解锁的块的大小

        let movePointer = containerEmpty.offsetLeft // 解锁的位置

        let maxDistance = (containerWidth - sliderMoveWidth); // 根据背景和解锁块的宽度限制滑块移动最大的距离

        let faultSize = 10; // 滑动距离的容错处理, 滑动距离- 10, +10 都可解锁

        init()

        containerReset.onclick = function () {
            init()
        }

        /**
         * 监听鼠标在sliderBox(滑动块)按下时 mousedowm, 并根据可视区左边的距离减去鼠标按下的距离, 获取到实际
         * document的onmouseMove和mouseup事件,
         * 获取鼠标滑动的位置
        */
        sliderBox.onmousedown = function (moveStart) {
            let left = moveStart.clientX - sliderBox.offsetLeft; // 获取按下时元素距离可视区左边的位置 - 鼠标按下时的位置, 获取到鼠标距离元素边缘的位置
            let lefta // 记录移动的距离
            // 鼠标按下持续移动中
            document.onmousemove = function (moveTo) {
                // 如果不减去 left 那么就会导致鼠标一直在移动元素的左边框上, 也就会出现元素不跟着鼠标走的问题, 有偏差
                lefta = moveTo.clientX - left; // 元素移动的距离
                // 限制元素的移动距离,不能小于0, 或者大于最大宽度 - 元素本身的距离, 否则就初始化位置
                if (lefta < 0) {
                    lefta = 0;
                } else if (maxDistance < lefta) {
                    lefta = maxDistance;
                }
                sliderBox.style.left = lefta + 'px'
                sliderMove.style.left = lefta + 'px'
                // 因为滑块加了圆角的功能,所以要在这里加4px,让滑块刚好压住滑块背景,不加的话,放大的时候会比较突兀
                sliderShadow.style.width = (lefta + 4) + 'px';
            }

            // 鼠标移动结束
            document.onmouseup = function (moveEnd) {
                // 解除document身上绑定的事件, 不让事件一直触发
                document.onmousemove = null;
                document.onmouseup = null;
                // 判断滑动距离是否相同,这里的滑动距离允许10px的容错,所以在当被校验区域大于小于校验区域10px都可以校验通过
                if (lefta >= movePointer - faultSize && lefta <= movePointer + faultSize) {
                    success(true)
                } else {
                    success(false)
                }
                init()
                // 重置位置
                sliderBox.style.left = 0 + 'px'
                sliderMove.style.left = 0 + 'px'
                sliderShadow.style.width = 0 + 'px';
                infomation.innerText = ''
            }
        }


        function success(valid) {
            let text = valid ? '成功' : "失败"
            infomation.innerText = `解锁${text}`
            alert(`解锁${text}`)
        }

        /**
         * 随机生成空白的位置, 并指定解锁块的高度
         *  */
        function init() {
            const moveTop = Math.floor(Math.random() * 90); // 滑块随机生成的高度
            const moveLeft = Math.floor(Math.random() * (270 - 60) + 60); // 滑块随机生成的left距离

            movePointer = moveLeft // 重置滑块解锁的位置

            sliderMove.style.top = moveTop + 'px'; // 初始化滑块位置

            containerEmpty.style.top = moveTop + 'px'; // 初始化解锁区域
            containerEmpty.style.left = moveLeft + 'px';

            sliderShadow.style.width = 0 + 'px';

            sliderMove.style.backgroundPosition = `-${moveLeft}px  -${moveTop}px`
        }

        function getElement(elName) {
            return document.getElementsByClassName(elName)[0]
        }
    </script>
</body>

</html>

本篇前端实现登录拼图验证就到此结束了,这个功能一般都是在登录的时候用的。文章中的案例可以正常使用哦 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/169877.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 第六章 函数

6.1函数的定义和调用6.1.1定义函数格式&#xff1a;def 函数名 ([参数列表]):["""文档字符串"""]函数体[return 语句]6.1.2函数调用格式&#xff1a;函数名([参数列表])python中函数可以嵌套定义例如&#xff1a;def add_modify(a,b):resultabpr…

Vue3响应式原理解析

前言 今年上半年开始&#xff0c;自己开始在新项目中使用 Vue3 进行开发&#xff0c;相比较于 Vue2 来说&#xff0c;最大的变化就是 composition Api 代替了之前的 options Api&#xff0c;更像是 React Hooks 函数式组件的编程方式。 Vue3相对于Vue2响应式原理也发生了变化…

vue日期组件el-date-picker中更改默认日期格式并且实时显示的方法

在项目中有一个需求是这样的,要求实时显示他的当前默认时间,并且不能修改 使用了默认:default-value"currentTime"属性之后,新增的时候会报错,前端与后端传递的数据不匹配 因为默认时间被new date() 解析之后返回的数据是默认时间形式的,格式不符 方法如下: 第一步&a…

Elasticsearch入门 - Mac上Elasticsearch和Kibana的安装运行与简单使用

文章目录一&#xff0c;Mac上Elasticsearch和Kibana的安装1.1 环境与下载1.2 安装与运行1.3 问题1.3.1 elasticsearch安装后其他机器不能访问1.3.2 kibana安装后其他机器不能访问二&#xff0c;Elasticsearch在Kibana的常见命令2.1 查看集群的健康状态2.2 索引2.2.1 查看所有索…

Scrum 敏捷开发

什么是敏捷开发 敏捷 开发是一个术语&#xff0c;用于描述迭代软件开发。 迭代软件开发通过在短增量完成工作&#xff08;通常称为 冲刺&#xff0c; Sprint&#xff09;来缩短 DevOps 生命周期。 冲刺通常长达一到四周。 敏捷开发通常与传统或瀑布式开发形成鲜明对比&#xff…

Vue基础9之脚手架的使用、ref属性、props配置项和mixin混入

Vue基础9使用Vue脚手架初始化脚手架说明具体步骤项目文件介绍将前面写好的单文件组件放入这里运行脚手架文件结构render的作用修改默认配置配置项ref属性props配置项简单的传值方法默认的字符串传值使用v-bind对数字类型进行传值限制数据类型接收数据时候只对数据类型进行限制接…

Java 搜索二维矩阵 II

搜索二维矩阵 II中等编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a;每行的元素从左到右升序排列。每列的元素从上到下升序排列。示例 1&#xff1a;输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22]…

v-model表单

1、v-model的基本使用 表单提交是开发中非常常见的功能&#xff0c;也是和用户交互的重要手段&#xff1a; 比如用户在登录、注册时需要提交账号密码&#xff1b;比如用户在检索、创建、更新信息时&#xff0c;需要提交一些数据&#xff1b; 这些都要求我们可以在代码逻辑中获…

【GD32F427开发板试用】+软件IIC(OLED显示)

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;四季的温度 gitee开源地址https://gitee.com/sijiwendu/gd32-f427-v/tree/master/module/oled 上一次完成DHT11开发文章https://aijishu.com/a…

什么是EDA?常见的EDA工具有哪些?

大家都知道&#xff0c;芯片设计难度非常大&#xff0c;要把上千亿颗晶体管集成在面积不到指甲盖大小的芯片上。其实能实现这样目标所以靠的是电子设计自动化&#xff08;Electronics Design Automation&#xff09;工具&#xff0c;也就是我们所称的EDA工具。 什么是EDA&…

从零搭建SpringCloud服务

一.微服务基础1.什么是SpringCloud&#xff1f;SpringCloud官网&#xff1a;https://spring.io/projects/spring-cloud&#xff08;个人建议是用谷歌浏览器访问官网打开中文翻译粗略把官网读一遍&#xff09;个人理解&#xff1a;以前的服务器就好像&#xff0c;一个会语数外全…

Elasticsearch:从实例中学习 nested 数据类型的 CRUD 及搜索

nested 数据类型是一个比较高级的话题。在本文中&#xff0c;将介绍 Elasticsearch 中针对嵌套对象的一些高级 CRUD 和搜索查询。 如果你想了解有关 Elasticsearch 基础知识的更多信息&#xff0c;可以查看这些文章以快速入门或复习&#xff1a; Elasticsearch&#xff1a;关于…

koa-router 正解

Koa-Router 之前分析过 Koa/ Koa-Bodyparser 的源码&#xff0c;今天让我们来分析下koa-router的源码&#xff0c;这个插件其实还是挺重要的。毕竟作为路由&#xff0c;我们还是要知道他的工作原理 这里会重申下 其实我是分析了 koa-router 主干流程。一些小众类的方法并没有看…

多步骤复杂 SQL 优化实例

问题先看数据&#xff1a;deliver 表是主表&#xff0c;一个客户会发生多次投递行为&#xff1a;deliverItem 表是从表&#xff0c;一个投递行为有多个投递项&#xff0c;delivered 是投递状态&#xff08;1 表示未完成&#xff0c;2 表示投递完成&#xff09;&#xff1a;需求…

如何了解一个软件的设计?

刚入职&#xff0c;接手新项目&#xff0c;面对一个全新项目&#xff0c;怎么快速研究它&#xff1f; 很多人直接看源码&#xff0c;一头扎入代码&#xff0c;很快就迷失其中&#xff0c;最初那股子探索精神&#xff0c;也会逐渐被迷茫所替。有多少次你满怀激情打开一个开源项…

极光推送REST API与Java后台对接

极光推送官网的web推送页面 因为是对接它的api&#xff0c;所以我参照这这个样式实现了一个&#xff0c;效果如下&#xff1a; 定时任务推送界面&#xff0c;可定制。实现了推送一次和每日定时推送&#xff0c;如果再扩展的话有每周、每月的功能&#xff0c;只是没有这个业务…

银行数字化转型导师坚鹏:银行数字化转型的五大痛点

首先从汇丰银行业绩持续下滑谈起&#xff0c;汇丰银行作为一家国际知名的全球性银行&#xff0c;最近10年左右的时间里&#xff0c;营业收入持续下降&#xff0c;已经从2008年的1400多亿美元到2021年的804.29亿美元; 净利润徘徊不前,2021年比2020年下降29.2%&#xff0c;仅为52…

kafka心得记录

1.为何引入kafka? 削峰填谷,主要还是为了应对上游瞬时大流量的冲击&#xff0c;避免出现流量毛刺现象&#xff0c;保护下游应用和数据库不被大流量打垮。 2.kafka备份机制&#xff0c;主从机制&#xff0c;Leader-Follower&#xff1a; Kafka 定义了两类副本&#xff1a;领导…

C语言文件操作函数详解——将你的代码永久化 ( •̀ ω •́ )✧

&#x1f384;博客主页&#xff1a;&#x1f390;大明超听话 &#x1f38b;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;关注✍评论 &#x1f38d;系列专栏&#xff1a;&#x1f391;从零开始C语言 &#x1f38a;从0开始数据结构与算法详解 &#x1f386;计算机考研——…

JavaScript中的原型链

本文作者为奇舞团前端开发工程师概述JavaScript 是 Web 的编程语言&#xff0c;简单易学&#xff0c;功能强大&#xff0c;但由于过于灵活设计理念&#xff0c;导致初学者经常一脸懵&#xff0c;本文要谈的是JavaScript中难点之一原型链。原型链的前世JavaScript的诞生要理解Ja…