JS面试真题 part6

news2024/9/25 23:19:58

JS面试真题 part6

  • 26、如何判断一个元素是否在可视区域中
  • 27、什么是单点登录?如何实现
  • 28、 如何实现上拉加载,下拉刷新
  • 29、说说你对正则表达式的理解?应用场景?
  • 30、说说你对函数式编程的理解?优缺点

26、如何判断一个元素是否在可视区域中

自己回答:根据当前位置距离浏览器顶部的y轴距离x轴距离和浏览器显示屏的高度宽度进行对比
标准回答:
常用三种方式:

  1. offsetTop、scrollTop、可视区高度
  2. getBoundingClientRect
  3. Intersection Observer

1、offsetTop、scrollTop、可视区高度

主要关系:el.offsetTop - document.documentElement.scrollTop <= viewPortHeight
offsetTop:元素的上边框至包含元素的上内边框之间的像素距离
scrollTop:滚动条滚动距离

将元素的scrollTop和scrollLeft设置为0,可以重置元素的滚动位置

viewPortHeight:可视区高度、设备高度。

代码实现:

 function isInViewPortOfOne (el) {
 // viewPortHeight 
 const viewPortHeight = window.innerHeight || document.documentElement.c
lientHeight || document.body.clientHeight
 const offsetTop = el.offsetTop
 const scrollTop = document.documentElement.scrollTop
 const top = offsetTop - scrollTop
 return top <= viewPortHeight
}

2、getBoundingClientRect

返回值是一个DOMReact对象,拥有left,top,right,bottom,x,y,width和height属性

 const target = document.querySelector('.target');
const clientRect = target.getBoundingClientRect();
console.log(clientRect);
// {
// bottom: 556.21875,
// height: 393.59375,
// left: 333,
// right: 1017,
// top: 162.625,
// width: 684
// }

在这里插入图片描述
如果一个元素在视窗之内的话,那么它一定满足下面四个条件

  • top大于等于0
  • left大于等于0
  • bottom小于等于视窗高度
  • right小于等于视窗宽度

实现代码:

function isInViewPort(element) {
 const viewWidth = window.innerWidth || document.documentElement.clientWi
dth;
 const viewHeight = window.innerHeight || document.documentElement.client
Height;
 const {
 top,
 right,
 bottom,
 left,
 } = element.getBoundingClientRect();
 return (
 top >= 0 &&
 left >= 0 &&
 right <= viewWidth &&
 bottom <= viewHeight
 );
}

3、 Intersection Observer

Intersection Observer 重叠观察者,用于判断两个元素是否重叠,因为不用进行事件的监听,性能方面比 getBoundingClientRect会好很多

使用步骤主要分为两步:创建观察者和传入被观察者

创建观察者

 const options = {
 // 表示重叠面积占被观察者的比例,从0 - 1取值 
 // 1 表示完全被包含
 threshold: 1.0,
 root:document.querySelector('#scrollArea') // 必须是目标元素的父级元素
};
const callback = (entries, observer) => { ....}
const observer = new IntersectionObserver(callback, options);

通过new IntersectionObserver创建了观察者observer,传入的参数 callback在重叠比例超过threshold时会被执行

关于callback回调函数常用属性如下:

// callback
const callback = function(entries, observer) {
 entries.forEach(entry => {
 entry.time; // 触发的时间
 entry.rootBounds; // 根元素的位置矩形,这种情况下为视窗位置
 entry.boundingClientRect; // 被观察者的位置矩形
 entry.intersectionRect; // 重叠区域的位置矩形
 entry.intersectionRatio; // 重叠区域占被观察者面积的比例(被观察者不是矩形时也按矩形计算)
 entry.target; // 被观察者
 });
};

传入被观察者
通过 observer.observer(target) 这一行代码即可注册被观察者

const target = document.querySelector('.target');
observer.observe(target);

27、什么是单点登录?如何实现

标准回答:

什么是单点登录?

单点登录(Single Sign On),简称SSO,是目前比较流行的企业业务整合的解决方案之一

SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有互相信任的应用系统

SSO一般需要一个独立的认证中心(passport),子系统的登录均得通过passport,子系统本身将不参与登录操作

当一个系统成功登录以后,passport 将会颁发一个令牌给各个子系统,子系统可以拿着令牌获取各自的受保护资源,为了减少频繁认证,各个子系统在被 passport 授权以后,会建立一个局部会话,在一定时间内可以无需再次向 passport 发起认证。
在这里插入图片描述
上图有四个系统,当application1、application2、application3需要登录时,将跳到sso系统,sso系统完成登录。其他应用系统也就随之登录了。

如何实现

1、同域名下的单点登录:

cookiedomain属性设置为当前域的父域,并且父域的cookie会被子域所共享。path属性默认为web应用的上下文路径

利用 cookie 的这个特点,只需要将domain属性设置为当前域的父域,同时将cookie的path属性设置为根路径,将Session ID(或Token)保存到父域中。这样所有子域都可以访问这个cookie,不过这要求应用系统的域名建立在一个共同的主域下。

2、不同域名下的单点登录(一):

如果是不同域的情况下Cookie 是不共享的,这里我们可以部署一个认证中心,用于专门处理登录请求的独立的 Web 服务

用户统一在认证中心进行登录,登录成功后,认证中心记录用户的登录状态,并将token写入Cookie (注意这个 Cookie 是认证中心的,应用系统是访问不到的)

应用系统检查当前请求有没有Token,如果没有,说明用户在当前系统中尚未登录,那么就将页面跳转至认证中心

由于这个操作会将认证中心的Cookie 自动带过去,因此,认证中心能够根据:Cookie 知道用户是否已经登录过了

如果认证中心发现用户尚未登录,则返回登录页面,等待用户登录

如果发现用户已经登录过了,就不会让用户再次登录了,而是会跳转回目标URL,并在跳转前生成一个Token,拼接在目标 URL的后面,回传给目标应用系统

应用系统拿到 Token 之后,还需要向认证中心确认下Token的合法性,防止用户伪造。确认无误后,应用系统记录用户的登录状态,并将Token写入Cookie然后给本次访问放行。(注意这个Cookie 是当前应用系统的)

当用户再次访问当前应用系统时,就会自动带上这个Token,应用系统验证 Token 发现用户已登录,:于是就不会有认证中心什么事了

此种实现方式相对复杂,支持跨域,扩展性好,是单点登录的标准做法

3、不同域名下的单点登录(二):

可以选择将 Session ID(或 Token )保存到浏览器的 LocalStorage 中,让前端在每次向后端发送请求时,主动将 LocalStorage 的数据传递给服务端

这些都是由前端来控制的,后端需要做的仅仅是在用户登录成功后,将SessionID(或 Token)放在响应体中传递给前端

单点登录完全可以在前端实现。前端拿到SessionID(或 Token )后,除了将它写入自己的LocalStorage 中之外,还可以通过特殊手段将它写入多个其他域下的LocalStorage
关键代码如下:

//获取 token
var token = result.data.token;
// 动态创建一个不可见的iframe,在 iframe中加载一个跨域的 HTML
var iframe = document.createElement("iframe");
iframe.src = "http://app1.com/localstorage.html";
document.body.append(iframe);
// 使用postMessage()方法将token传递给iframe
setTimeout(function () {
 iframe.contentWindow.postMessage(token, "http://app1.com");
}, 4000);
setTimeout(function () {
 iframe.remove();
}, 6000);
//在这个iframe所加载的HTML中绑定一个事件监听器,当事件被触发时,把接收到的token数据写入localStorage
window.addEventListener('message', function (event) {
 localStorage.setItem('token', event.data)
}, false);

前端通过 iframe +postMessage()方式,将同一份 Token 写入到了多个域下的 Localstorage 中,前端每次在向后端发送请求之前,都会主动从 LocalStorage 中读取 Token 并在请求中携带,这样就实现了同一份 Token 被多个域所共享
此种实现方式完全由前端控制,几乎不需要后端参与,同样支持跨域

28、 如何实现上拉加载,下拉刷新

自己回答:一般存在于移动端,uniapp里有对应的api调用。原生的话,需要根据手指移动的距离和屏幕的高度进行对比,判断是向下滑还是向上拉

标准回答:
下拉刷新和上拉加载这两种交互方式通常出现在移动端中,本质上等同于pc网页中的分页,只是交互形式不同。
开源社区也有很多优秀的解决方案,如 iscrollbetter-scrollpulltorefresh.js

上拉加载实现原理:
在这里插入图片描述
上拉加载的本质是页面触底,或者快要触底的动作
首先了解几个属性

  • scrollTop:滚动视窗的高度距离window顶部的距离,它会随着往上滚动而不断增加,初始值是0,它是一个变化的值
  • clientHeight:它是一个定值,表示屏幕可视区域的高度
  • scrollHeight:页面不能滚动时也是存在的,此时scrollHeight等于clientHeight。scrollHeight表示body所有元素的总长度(包括body元素自身的padding)

综上得出触底公式:
scrollTop + clientHeight >= scrollHeight

简单实现

 let clientHeight = document.documentElement.clientHeight; //浏览器高度
let scrollHeight = document.body.scrollHeight;
let scrollTop = document.documentElement.scrollTop;
let distance = 50; // 距离视窗还有50的时候,开始触发
if ((scrollTop + clientHeight) >= (scrollHeight - distance)) {
 console.log("开始加载数据");
}

下拉刷新实现原理:

下拉刷新的本质是页面本身置于顶部时,用户下拉时需要触发的动作
关于下拉刷新的原生实现,主要分为三步:

  • 监听原生 touchstart 事件,记录其初始位置的值,e.touches[0].pageY;
  • 监听原生 touchmove 事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值;
  • 监听原生 touchend 事件,若此时元素滑动达到最大值,则触发 callback ,同时将 translateY 重设为0,元素回到初始位置。

代码实现,html结构

 <main>
 <p class="refreshText"></p >
 <ul id="refreshContainer">
 <li>111</li>
 <li>222</li>
 <li>333</li>
 <li>444</li>
 <li>555</li>
 ...
 </ul>
</main>

监听touchstart事件,记录初始的值

var _element = document.getElementById('refreshContainer'),
 _refreshText = document.querySelector('.refreshText'),
 _startPos = 0, // 初始的值
 _transitionHeight = 0; // 移动的距离
_element.addEventListener('touchstart', function(e) {
 _startPos = e.touches[0].pageY; // 记录初始位置
 _element.style.position = 'relative';
 _element.style.transition = 'transform 0s';
}, false);

监听touchmove事件,记录滑动差值

_element.addEventListener('touchmove', function(e) {
 // e.touches[0].pageY 当前位置
 _transitionHeight = e.touches[0].pageY - _startPos; // 记录差值
 if (_transitionHeight > 0 && _transitionHeight < 60) {
 _refreshText.innerText = '下拉刷新';
 _element.style.transform = 'translateY('+_transitionHeight+'px)';
 if (_transitionHeight > 55) {
 _refreshText.innerText = '释放更新';
 }
 } 
}, false);

最后,就是监听touchend离开的事件

_element.addEventListener('touchend', function(e) {
 _element.style.transition = 'transform 0.5s ease 1s';
 _element.style.transform = 'translateY(0px)';
 _refreshText.innerText = '更新中...';
 // todo...
}, false);

从上面可以看到,在下拉到松手的过程中,经历了三个阶段

  • 当前手势滑动位置与初始位置差值大于零时,提示正在进行下拉刷新操作
  • 下拉到一定值时,显示松手释放后的操作提示
  • 下拉到达设定最大值松手时,执行回调,提示正在进行更新操作

29、说说你对正则表达式的理解?应用场景?

自己回答:需要匹配某种对应的规则的时候.。应用场景:比如手机号码验证,中文名字验证等

标准回答:

正则表达式是一种用来匹配字符串的强有力的武器,它的设计思想是用一种描述性的语言定义一个规则,凡是符合规则的字符串,就认为它“匹配”,否则该字符串就是不合法的。
构建方法有两种
1、字面量创建,其由包含在斜杠之间的模式组成

const re = /\d+/g;

2、调用RegExp对象的构造函数

const re = new RegExp("\\d+","g");
const rul = "\\d+"
const re1 = new RegExp(rul,"g");

使用构造函数创建,第一个参数可以是一个变量,遇到特殊字符 \ 需要使用 \\ 进行转义

应用场景:

验证QQ合法性(5~15位、全是数字、不以0开头)

const reg = /^[1-9][0-9]{4,14}$/
const isvalid = patrn.exec(s)

校验用户账号合法性(只能输入5-20个以字母开头、可带数字、“_”、“.”的字符串)

var patrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;
const isvalid = patrn.exec(s)

将url参数解析为对象

30、说说你对函数式编程的理解?优缺点

自己回答:面向过程的编程,去对象化,更关注函数功能,使函数更简洁,不依赖对象。优点:功能集中化,缺点:失去对象的关联性
标准回答:

函数式编程是一种“编程范式"(programming paradigm),一种编写程序的方法论

主要的编程范式有三种:命令式编程声明式编程函数式编程

相比命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而非设计一个复杂的执行过程

举个例子,将数组每个元素进行平方操作,命令式编程与函数式编程如下

// 命令式编程
var array = [0, 1, 2, 3]
for(let i = 0; i < array.length; i++) {
 array[i] = Math.pow(array[i], 2)
}
// 函数式编程
[0, 1, 2, 3].map(num => Math.pow(num, 2))

简单来讲,就是要把过程逻辑写成函数,定义好输入参数,只关心它的输出结果
即是一种描述集合和集合之间的转换关系,输入通过函数都会返回有且只有一个输出值

在这里插入图片描述
可以看到,函数实际上是一个关系,或者说是一种映射,而这种映射关系是可以组合的,一旦我们知道一个函数的输出类型可以匹配另一个函数的输入,那他们就可以进行组合

了解几个相关概念

1、纯函数

函数式编程旨在尽可能的提高代码的无状态性和不变性。要做到这一点,就要学会使用无副作用的函数,也就是纯函数
纯函数是对给定的输入返回相同输出的函数,并且要求你所有的数据都是不可变的,即纯函数=无状态+数据不可变
在这里插入图片描述
举一个简单的例子

let double = value=>value*2;

特性:

  • 函数内部传入指定的值,就会返回确定唯一的值
  • 不会造成超出作用域的变化,例如修改全局变量或引用传递的参数

优势:

  • 使用纯函数,我们可以产生可测试的代码
  • 不依赖外部环境计算,不会产生副作用,提高函数的复用性
  • 可读性更强,函数不管是否是纯函数,都会有一个语义化的名称,更便于阅读
  • 可以组装成复杂任务的可能性。符合模块化概念及单一职责原则

2、高阶函数
在我们的编程世界中,我们需要处理的其实也只有“数据”和“关系”,而关系就是函数。
编程工作也就是在找一种映射关系,一旦关系找到了,问题就解决了。
在这里插入图片描述
在这里,就是高阶函数的作用,高级函数,就是以函数作为输入或输出的函数被称为高阶函数
通过高阶函数抽象过程,注重结果,如下面例子

 const forEach = function(arr,fn){
 for(let i=0;i<arr.length;i++){
 fn(arr[i]);
 }
}
let arr = [1,2,3];
forEach(arr,(item)=>{
 console.log(item);
})

上面通过高阶函数 forEach 来抽象循环如何做的逻辑,直接关注做了什么
高阶函数存在缓存的特性,主要是利用闭包作用

 const once = (fn)=>{
	 let done = false;
	 return function(){
		 if(!done){
			 fn.apply(this,fn);
		 }else{
			 console.log("该函数已经执行");
		 }
		 done = true;
	 }
 }

3、柯里化

柯里化是把一个多参数函数转化成一个嵌套的一元函数的过程

一个二元函数如下:

let fn = (x,y)=>x+y;

转化成柯里化函数如下:

const curry = function(fn){
	 return function(x){
		 return function(y){
			 return fn(x,y);
		 }
	 }
}
let myfn = curry(fn);
console.log( myfn(1)(2) );

上面的curry函数只能处理二元情况,下面来实现一个实现多参数的情况

// 多参数柯里化
const curry = function(fn){
	 return function curriedFn(...args){
		 if(args.length<fn.length){
			 return function(){
				 return curriedFn(...args.concat([...arguments]));
			 }
		 }
		 return fn(...args);
	 }
}
const fn = (x,y,z,a)=>x+y+z+a;
const myfn = curry(fn);
console.log(myfn(1)(2)(3)(1));

关于柯里化函数的意义如下:

  • 让纯函数更纯,每次接受一个参数,松散解耦
  • 惰性执行

4、组合与管道

组合函数,目的是将多个函数组合成一个函数
举个简单的例子:

 function afn(a){
    return a*2;
}
function bfn(b){
    return b*3;
}
const compose = (a,b)=>c=>a(b(c));
let myfn = compose(afn,bfn);
console.log( myfn(2));

compose 实现一个简单的功能:形成了一个新的函数,而这个函数就是一条从bfn->afn 的流水线

如何实现一个多函数组合:

const compose = (...fns)=>val=>fns.reverse().reduce((acc,fn)=>fn(acc),val);

compose从右边到左,而管道函数pipe从左到右执行

const pipe = (...fns)=>val=>fns.reduce((acc,fn)=>fn(acc),val);

组合函数与管道函数的意义在于:可以把很多小函数组合起来完成更复杂的逻辑

优缺点

优点:

  • 更好的管理状态:因为它的宗旨是无状态,或者说更少的状态,能最大化的减少这些未知、优化代码、减少出错情况
  • 更简单的复用:固定输入->固定输出,没有其他外部变量影响,并且无副作用。这样代码复用时,完全不需要考虑它的内部实现和外部影响
  • 更优雅的组合:往大的说,网页是各个组件组成的,往小的说,一个函数也可能是由多个小函数组成的。更强的复用性,带来更强大的组合性
  • 隐藏好处。减少代码量,提高维护性

缺点:

  • 性能:函数式编程相对于指令式编程,性能绝对是一个短板,因为它往往会对一个方法进行过度包装,从而产生上下文切换的性能开销
  • 资源占用:在JS中为了实现对象状态的不可变,往往会创建新的对象,因此,它对垃圾回收所产生的压力远远超过其他编程方式
  • 递归陷阱:在函数式编程中,为了实现迭代,通常会采用递归操作

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

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

相关文章

Vue74 路由的props配置

笔记 ​ 作用&#xff1a;让路由组件更方便的收到参数 {name:xiangqing,path:detail/:id,component:Detail,//第一种写法&#xff1a;props值为对象&#xff0c;该对象中所有的key-value的组合最终都会通过props传给Detail组件// props:{a:900}//第二种写法&#xff1a;props…

《动手学深度学习》笔记1.11——实战Kaggle比赛:预测房价+详细代码讲解

目录 0. 前言 原书正文 1. 下载和缓存数据集 1.1 download() 下载数据集 1.2 download_extract() 解压缩 2. Kaggle 简介 3. 访问和读取数据集 4. 数据预处理 5. 训练&#xff08;核心难点&#xff09; 5.1 get_net() 定义模型-线性回归 5.2 log_rmse() 对数均方根…

见合八方亮相重庆光纤传感大会(OFS China-2024)

2024年9月20日至22日&#xff0c;第十二届中国光纤传感大会&#xff08;OFS China-2024&#xff09;在重庆成功举办&#xff0c;该大会旨在展示光纤传感技术在多个领域的最新研究成果&#xff0c;推动该技术的产业化进程。 在本次大会上&#xff0c;天津见合八方光电科技有限公…

JDK1.8与JDK17相互切换

&#x1f4d6; 前言&#xff1a;在电脑已经安装jdk17后&#xff0c;发现有些项目不兼容&#xff0c;需要用到以前的jdk1.8&#xff0c;本文介绍简单切换的方法。 &#x1f50e; 甲骨文jdk1.8官网下载 下载完jdk1.8后&#xff0c;可以将其与jdk17放在同一目录层级下。 搜索栏直…

我眼中的Token2049 是一场加密大秀

今年Token2049&#xff0c;其实我也收到很多来自币圈朋友、项目方或交易所的邀请&#xff0c;都一一婉拒了。因为每年9月&#xff0c;都是我一年来最忙碌的日子。一方面进入金九银十的销售旺季&#xff0c;另外副业也需要谈一些团购业务。 我喜欢Web3&#xff0c;也曾是 #Bitg…

《操作系统 - 清华大学》1 -1:操作系统概述 —— 内容概述

文章目录 1. 内容摘要2. 实验内容 1. 内容摘要 在这里对学习内容做一个整体上的介绍&#xff0c;那在这里包括我们要学习的内容&#xff0c;实验的内容。操作系统课涉及到计算机系统当中的资源管理&#xff0c;所以我们围绕着操作系统的实现来介绍相关内容&#xff0c;那主要分…

Java之路--瓦解逻辑控制与方法使用已是瓮中捉鳖

嗨嗨大家&#xff01;今天我们来学习逻辑运算和方法的使用~ 目录 一 逻辑控制 1 分支结构 1.1 if语句 1.2 switch 语句 2 循环结构 2.1 while 循环 2.2 for 循环 2.3 do while 循环 2.4 break 2.5 continue 3. 输出输入 二、方法的使用 1 方法定义语法 2 实参和…

NCU-机器学习-作业3:RANK: 0.0代码(No)

想体验一把No.1的快乐吗&#xff1f;话不多说直接上代码。 代码&#xff1a; import osimport pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC import numpy as npdef get_dataset(path):dataset, labels [], []filenames os…

SDK使用指南

本文档主要讲解音视频终端 SDK 产品家族下各子产品的能力支持及购买方式&#xff0c;并提供了相关 Demo 和 SDK 集成资源&#xff0c;具体体验步骤如下&#xff1a; 步骤一&#xff1a;了解产品 1.1 音视频终端 SDK 产品家族介绍 音视频终端 SDK&#xff08;腾讯云视立方&…

python基础之绘图turtle与分词

python基础 1.学习目的2.实验2.1实验一2.2实验二 3.实验代码及结果 1.学习目的 python库很多&#xff0c;所以我们要在空闲之余学习我们没有遇到的库&#xff0c;就比如turtle和分词库 2.实验 2.1实验一 2.2实验二 3.实验代码及结果 # File: turtle库.py # Author: chen_so…

第L2周:机器学习|线性回归模型 LinearRegression:1. 简单线性回归模型

本文为&#x1f517;365天深度学习训练营 中的学习记录博客原作者&#xff1a;K同学啊 任务&#xff1a; ●1. 通过本文学习LinearRegression简单线形回归模型。 ●2. 模仿本文代码&#xff0c;通过鸢尾花花瓣长度预测花瓣宽度。 一、概念 什么是回归 回归的目的是为了预测&…

Vue3入门 - ElementPlus中左侧菜单和Tabs菜单组合联动效果

在Vue3中&#xff0c;ElementPlus是使用比较广泛的UI组件库&#xff0c;提供了丰富的界面元素支持项目开发需求。在后台管理系统中&#xff0c;左侧或顶部的菜单栏通常包含多个子菜单项&#xff0c;通过菜单的展开和收缩功能&#xff0c;用户可以方便地查看或隐藏不需要的菜单项…

Centos7.9安装.Net 8.0框架

1.背景 在Centos7.9编译运行Net8.0项目时&#xff0c;会用到.Net8.0框架。所以我实操了如何在Centos7.9去安装.Net8.0框架。本文记录了相关操作过程&#xff0c;是一个比较好的参考。 2.操作 2.1 安装框架 sudo rpm -Uvh https://packages.microsoft.com/config/centos/8/pa…

一文理解AXI4-lite与AXI4-stream协议

AXI4-lite与AXI4-stream协议 上篇博文《AMBA3.0 AXI总线入门》浅要介绍AXI4总线协议&#xff0c;AXI总线作为一种总线&#xff0c;可以挂载多个主设备&#xff08;master&#xff09;和从设备&#xff08;slave&#xff09;&#xff0c;AXI总线协议定义了主设备和从设备之间如何…

Docker本地部署Chatbot Ollama搭建AI聊天机器人并实现远程交互

文章目录 前言1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 前言 本文主要分享如何在群晖NAS本地部署并运行一个基于大语言模型Llama 2的个人本地聊天机器人并结合内网穿透工具…

Web安全-SQL注入之联合查询注入

声明 环境 墨者学院-SQL手工注入漏洞测试(MySQL数据库-字符型) 判断是否存在漏洞 http://124.70.64.48:42937/new_list.php?idtingjigonggao and 12-- and 11正常 http://124.70.64.48:42937/new_list.php?idtingjigonggao and 12-- and 12出错&#xff0c;存在字符型注入…

yolov8训练数据集——labelme的json文件转txt文件

yolov8的环境搭建&#xff0c;参考&#xff1a;Home - Ultralytics YOLO Docs 1.把标注好的json文件和jpg放同一个目录下。 2.运行转换脚本文件labelme2yolo.py文件&#xff1a; # -*- coding: utf-8 -*-import os import numpy as np import json from glob import glob im…

python学习笔记(3)——控制语句

控制语句 我们在前面学习的过程中&#xff0c;都是很短的示例代码&#xff0c;没有进行复杂的操作。现在&#xff0c;我们将开始学习流程控制语句。 前面学习的变量、数据类型&#xff08;整数、浮点数、布尔&#xff09;、序列&#xff08;字符串、列表、元组、字 典、集合&am…

GPS在Linux下的使用(war driving的前置学习)

1.ls /dev/tty* 列出所有与 tty 相关的设备文件。这些设备文件通常对应终端设备 ttyUSB0是GPS端口 2.cat /dev/ttyUSB0 用于读取并显示连接到 /dev/ttyUSB0 串口设备发送的原始数据 这种是GPS定位不全的&#xff0c;要拿到更开阔的地方 这种是GPS定位全的 因为会持续输出…

大模型神书《HuggingFace自然语言处理详解——基于BERT中文模型的任务实战》读完少走几年弯路!

这几年&#xff0c;自然语言处理&#xff08;NLP&#xff09;绝对是机器学习领域最火的方向。那么今天给大家带来一本 《HuggingFace自然语言处理详解——基于BERT中文模型的任务实战》 这本大模型书籍资料已经上传CSDN&#xff0c;朋友们如果需要可以微信扫描下方CSDN官方认证…