当前位置: 首页 > news >正文

flask入门-4.项目实战

4. 项目实战1

1. 问答平台项目结构搭建

项目结构

在这里插入图片描述

config.py

hostname = "127.0.0.1"
port = 3306
username = "root"
password = "root"database = "flask_qa"# 在 app.config 中设置连接数据库的信息
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{username}:{password}@{hostname}:{port}/{database}?charset=utf8mb4"

exts.py

扩展文件,先预定义db

from flask_sqlalchemy import SQLAlchemy
# 扩展文件,先预定义db
# 避免出现循环引用, 比如将db=db = SQLAlchemy(app)放入app.py中, modules 实体类中需要引用 db, 而app.py中需要导入实体类, 出现了循环引用
# 如果在此处定义 db=db = SQLAlchemy(app) , 则会引用 app.py文件, 而 modules 实体类中需要引用 db, 也相当于引用了 app.py , app.py中需要导入实体类, 又会出现循环引用
# 因此此处预定义, 从而 实体类中引用该文件, app.py 中引用实体类 , 并在app.py中初始化db的配置
db = SQLAlchemy()

实体类定义(modules包下:):

User.py

from exts import db
from datetime import datetimeclass UserModel(db.Model):__tablename__ = 'user'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(100), nullable=False)password = db.Column(db.String(100), nullable=False)email = db.Column(db.String(100), nullable=False, unique=True)join_time = db.Column(db.DateTime, default=datetime.now)

视图定义(blueprints包下):

autho.py

from flask import Blueprint# 初始化, 定义该视图名称和访问前缀
bp = Blueprint('auth', __name__, url_prefix='/auth')# 相当于访问 /auth/login
@bp.route('/login')
def login():pass

qa.py

from flask import Blueprint# 初始化, 定义该视图名称和访问前缀
bp = Blueprint('qa', __name__, url_prefix='/qa')

最后在app.py中进行整合:

from flask import Flask
import config
from exts import db# 导入自定义的视图
from buleprints.autho import bp as auth_bp
from buleprints.qa import bp as qa_bp# 导入定义的实体类
from modules.User import UserModel
from flask_migrate import Migrateapp = Flask(__name__)# 绑定数据库的配置文件,自动读取配置信息
app.config.from_object(config)
# 初始化db的配置
db.init_app(app)# 绑定自定义的视图
app.register_blueprint(auth_bp)
app.register_blueprint(qa_bp)# 将定义的实体类模型映射到数据库中
migrate = Migrate(app, db)
# 然后在控制台 flask db init, flask db migrate, flask db upgrade@app.route('/')
def hello_world():  # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run()

2. 模板渲染

注册登录页面模板渲染

3. flask 发送邮箱验证码

3.1 邮箱设置

qq邮箱:

设置->账户->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务

开启 POP3/SMTP服务

3.2 项目文件配置-发送验证码到邮箱

第一步,下载 flask_mail

pip install flask-mail

config.py

# 发送邮件的相关配置
MAIL_SERVER = "smtp.qq.com"
MAIL_USE_SSL = True
MAIL_PORT = 465
MAIL_USERNAME = "3148524372@qq.com"
MAIL_PASSWORD = "vbjpvdzrzzlhdfca"
MAIL_DEFAULT_SENDER = "3148524372@qq.com"

exts.py 中 预定义(作用和db的预定义一样)

from flask_sqlalchemy import SQLAlchemy
# 扩展文件,先预定义db
# 避免出现循环引用, 比如将db=db = SQLAlchemy(app)放入app.py中, modules 实体类中需要引用 db, 而app.py中需要导入实体类, 出现了循环引用
# 如果在此处定义 db=db = SQLAlchemy(app) , 则会引用 app.py文件, 而 modules 实体类中需要引用 db, 也相当于引用了 app.py , app.py中需要导入实体类, 又会出现循环引用
# 因此此处预定义, 从而 实体类中引用该文件, app.py 中引用实体类 , 并在app.py中初始化db的配置
db = SQLAlchemy()from flask_mail import Mailmail = Mail()

app.py 中 初始化

# 绑定数据库的配置文件,自动读取配置信息
app.config.from_object(config)
# 初始化db的配置
db.init_app(app)
# 初始化邮箱相关配置
mail.init_app(app)

autho.py 中测试

from flask import Blueprint
from flask_mail import Message
from exts import mail# 初始化, 定义该视图名称和访问前缀
bp = Blueprint('auth', __name__, url_prefix='/auth')# 相当于访问 /auth/login
@bp.route('/login')
def login():pass@bp.route('/mail/test')
def mail_test():message = Message(subject='发送邮件测试', recipients=["yangzhaohui4132@163.com"], body="测试邮件")mail.send(message)return "success"

3.3 验证码的生成与存储

因为需要将验证码存储到数据库中,因此需要先创建实体类 EmailCaptch.py

from exts import dbclass EmailCaptchaModel(db.Model):__tablename__ = 'email_captcha'id = db.Column(db.Integer, primary_key=True, autoincrement=True)email = db.Column(db.String(100), nullable=False)captcha = db.Column(db.String(100), nullable=False)

autho.py 中 请求 /autho/captch/email 会执行下面的方法,生成验证码并发送到对应的邮件中,并将生成的验证码存储到数据库中

# 获取验证码
@bp.route('/captch/email')
def get_email_captch():# 请求方式 captch/email/<email># captch/email?email=xx@qq.com# 通过request获取请求的参数email = request.args.get('email')# 生成验证码# 验证码为4个随机数字的组合source = string.digits*4captch = random.sample(source, 4)   # 此时captch为列表captch = "".join(captch)# 发送验证码message = Message(subject='发送邮件测试', recipients=[email], body=f"验证码是:{captch}")mail.send(message)# 将验证码存储到数据库中email_captch = EmailCaptchaModel(email=email, captcha=captch)db.session.add(email_captch)db.session.commit()# 统一对前端请求的返回信息,采用 RESTFUL 的形式# {"code":200, "message":"", "data":None}return jsonify({"code":200, "message": "", "data":None})

进行测试:访问 127.0.0.1:5000/auth/captch/email?email=yangzhaohui4132@163.com

image-20230227162252971

3.4 前端请求验证码

register.html页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="{{ url_for('static', filename='js/jquery-3.6.3.js') }}"></script><script src="{{ url_for('static', filename='js/register.js') }}"></script>
</head>
<body>
<form><div><input type="text" name="email"></div><button name="captcha-btn" id="captcha-btn">获取验证码</button>
</form></body>
</html>

register.js 页面

// 定义绑定 发送验证码按钮 的函数
function bindEmailCaptchaClick(){$("#captcha-btn").click(function (event) {//    $this, 代表的是当前按钮的 jquery 对象var $this = $(this)//    阻止默认事件event.preventDefault()console.log("1111")//    获取输入的邮箱let email = $("input[name='email']").val()//    点击发送验证码按钮后,发送ajax请求$.ajax({// 根目录 : http:127.0.0.1:5000// 请求路径为 : /auth/captcha/email?email=XX@qq.comurl: "/auth/captch/email?email="+email,method: "GET",// 如果请求成功, 服务器会返回结果success: function(result){var code = result['code']if (code == 200){// 说明请求成功// 开始倒计时// 进行倒计时之前, 需要先取消按钮的点击事件$this.off("click")var countdown = 60 // 倒计时60s// 使用 setInterval 定义计时器var timer = setInterval(function () {$this.text(countdown)countdown -= 1// 倒计时结束if (countdown <= 0){// 清除计时器clearInterval(timer)// 修改按钮的文字$this.text("获取验证码")// 重新绑定点击事件bindEmailCaptchaClick()}}, 1000)alert("验证码发送成功")}else {// 未能成功发送成功alert(result["message"])}},fail: function(error){console.log(error)}})})
}//先加载完整个页面文档后, 再加载js函数
$(function () {bindEmailCaptchaClick()
})

3.5 前端提交数据验证和保存

首先下载 flask-wtf 包, 该包包含对表单 form 的相关处理

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple flask-wtf

其次在配置文件中配置 密钥

config.py

# flask_wtf 进行对前端传递到服务器的数据验证
# 需要在配置文件中设定 关键字
SECRET_KEY = "qwoehavnOEJVIN "

然后定义对应的表单验证类

注册表单对应 RegisterForm

form.py 中

import wtforms
from wtforms.validators import Email, Length, EqualTo
from modules.User import UserModel
from modules.EmailCaptch import EmailCaptchaModel
# 用来验证前端提交的表单数据是否符合要求
class RegisterForm(wtforms.Form):email = wtforms.StringField(validators=[Email(message="邮箱格式错误")])captcha = wtforms.StringField(Length(min=4, max=4, message="验证码格式错误"))username = wtforms.StringField(Length(min=3, max=20, message="用户名格式错误"))password = wtforms.StringField(Length(min=3, max=20, message="密码格式错误"))password_confirm = wtforms.StringField(validators=[EqualTo("password")])# 自定义验证# 判断邮箱是否被注册def validate_email(self, field):email = field.datauser = UserModel.query.filter_by(email=email).first()if user:raise wtforms.ValidationError(message="该邮箱已被注册")# 验证验证码是否正确def validate_captcha(self, field):captcha = field.dataemail = self.email.datacaptcha_model = EmailCaptchaModel.query.filter_by(email=email, captcha=captcha).first()if not captcha_model:raise wtforms.ValidationError(message="邮箱或验证码错误")

最后服务器对前端提交的数据进行处理, 并保存到数据库中

autho.py

@bp.route('/register', methods=['GET', 'POST'])
def register():# 默认是get请求if request.method == 'GET':return render_template('register.html')else:# 验证用户提交的邮箱和验证码是否正确# 使用flask-wtf: wtforms 进行表单验证form = RegisterForm(request.form)if form.validate():# 验证成功, 将提交的数据存储到数据库中email = form.email.datausername = form.username.datapassword = form.password.datauser = UserModel(email=email, username=username, password=generate_password_hash(password))db.session.add(user)db.session.commit()return redirect('/auth/login')else:# 验证失败print(form.errors)return "fail"

4. 登录

首先定义一个和登录表单对应的验证类 loginForm

form.py 中

class loginForm(wtforms.Form):email = wtforms.StringField(validators=[Email(message="邮箱格式错误")])password = wtforms.StringField(Length(min=3, max=20, message="密码格式错误"))

在 autho.py 中对登录请求进行处理

# 相当于访问 /auth/login
@bp.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'GET':return render_template("login.html")else:form = LoginForm(request.form)if form.validate():# 验证成功, 将提交的数据存储到数据库中email = form.email.datapassword = form.password.data# 数据库查找user = UserModel.query.filter_by(email=email).first()if not user:print("该用户不存在")return redirect(url_for('auth.login'))# 如果用户存在, 判断密码是否正确# check_password_hash(arg1, arg2) 第一个参数是加密后的密码, 第二个参数是用户通过前端传递过来的密码if check_password_hash(user.password, password):# 如果密码正确, 通过cookie存储用户的id, 下一次用户访问服务器时会顺带着携带cookie, 从而可以通过cookie识别用户的身份# flask 中的session, 是经过加密后存储在cookie中的session['user_id'] = user.idreturn redirect("/")    # 跳转到首页else:print("密码错误")return redirect(url_for("auth.login"))else:# 验证失败print(form.errors)return redirect(url_for("auth.login"))

5. 钩子函数

app.py

# 钩子函数
# before_request/before_first_request/after_request# 在调用视图函数处理请求前先执行该方法
# 在视图函数之前,将一些后面需要用到的数据先处理好,方便视图函数使用
@app.before_request
def my_before_request():user_id = session.get("user_id")if user_id: # 判断是否授权user = UserModel.query.filter_by(user_id)# 保存到全局变量中setattr(g, "user", user)else:setattr(g, "user", None)# 上下文处理器
# 使用这个钩子函数,必须返回一个字典。
# 这个字典中的值在所有模版中都可以使用。
# 如果一些在很多模版中都要用到的变量,那么就可以使用这个钩子函数来返回,而不用在每个视图函数中的render_template中去写,从而让代码更加简洁和好维护。
@app.context_processor
def my_context_processor():return {"user", g.user}

钩子函数可以用来在执行视图函数之前, 判断用户是否授权

6. 切换登录状态

首先钩子函数判断用户是否授权, 并且在上下文处理器中返回了用户信息

然后在 base.html 中

<ul class="navbar-nav">{% if user %}<li class="nav-item"><a class="nav-link" href="#">{{user.username}}</a></li><li class="nav-item"><a class="nav-link" href="{{ url_for('auth.logout') }}">退出登录</a></li>{% else %}<li class="nav-item"><a class="nav-link" href="{{url_for('auth.login')}}">登录</a></li><li class="nav-item"><a class="nav-link" href="{{url_for('auth.register')}}">注册</a></li>{% endif %}</ul>

在 autho.py 中,定义退出登录的视图函数

@bp.route('logout')
def logout():# 清楚cookiesession.clear()return redirect("/")

7. 实现发布问题功能

7.1 创建问题的实体类

QuestionModel.py

from exts import db
from datetime import datetime
from User import UserModelclass QuestionModel(db.Model):__tablename__ = 'question'id = db.Column(db.Integer, primary_key=True, autoincrement=True)title = db.Column(db.String(100), nullable=False)content = db.Column(db.Text, nullable=False)create_time = db.Column(db.DateTime, default=datetime.now)# 每一个问题都对应一个用户, 一个用户可以发布多个问题, 因此需要外键author_id = db.Column(db.Integer, db.ForeignKey("user.id"))# 关联 question 和 user 表, 从而可以通过 QuestionModel 的对象 questionModel的 questionModel.author的形式访问该问题属于的用户author = db.relationship(UserModel, backref="questions")

7.2 对前端提交的问题表单进行验证

对应的表单验证类 QuestionForm

form.py

class QuestionForm(wtforms.Form):title = wtforms.StringField(validators=[Length(min=3, max=20, message="标题格式错误")])content = wtforms.StringField(validators=[Length(min=3,  message="内容格式错误")])

7.3 后端对应的视图函数对请求进行处理

qa.py

@bp.route('/qa/publish_question', methods=['GET', 'POST'])
def publish_question():if request.method == 'GET':return render_template("publish_question.html")else:form = QuestionForm(request.form)# 进行表单验证if form.validate():title = form.title.datacontent = form.content.data# 保存到数据库中question = QuestionModel(title=title, content=content, author = g.user)db.session.add(question)db.session.commit()# 应该跳转到详情页面return redirect("/")else:print(form.errors)return redirect(url_for("qa.publish_question"))

8. 实现登录装饰器

登录装饰器的作用:

  • 没有登录的用户无法通过像 http://127.0.0.1:5000/qa/publish_question 这样链接 直接发布问题, 而是会重定向到登录页面;
  • 将装饰器写在哪个视图函数上, 那么该视图函数处理对应的请求前, 都会在装饰器中进行验证, 验证通过后对请求进行正常处理; 验证不通过, 会在装饰器中直接定向到对应页面

创建一个装饰器类 decorators.py

登录装饰器函数如下:

# 需要进行登录验证的装饰器函数
def login_require(func):# 保存func信息@wraps(func)# 内函数的参数是函数 func的参数def inner(*args, **kwargs):if g.user:return func(*args, **kwargs)else:return redirect(url_for("auth.login"))return inner

/qa/publish_question 请求中应用登录装饰器函数

@bp.route('/qa/publish_question', methods=['GET', 'POST'])
@login_require
def publish_question():if request.method == 'GET':return render_template("publish_question.html")else:form = QuestionForm(request.form)# 进行表单验证if form.validate():title = form.title.datacontent = form.content.data# 保存到数据库中question = QuestionModel(title=title, content=content, author = g.user)db.session.add(question)db.session.commit()# 应该跳转到详情页面return redirect("/")else:print(form.errors)return redirect(url_for("qa.publish_question"))

9. 实现首页展示所有问题

在 qa.py 对首页请求返回 定向到首页的同时携带所有问题

@bp.route('/')
def index():questions = QuestionModel.query.order_by(QuestionModel.create_time.desc()).all()return render_template("index.html", questions=questions)

前端页面 index.html

 <ul class="question-ul">{% for question in questions %}<li><div class="side-question"><img class="side-question-avatar" src="{{url_for('static', filename='/images/11.jpg')}}" alt=""></div><div class="question-main"><div class="question-title"><a href="#">{{ question.title }}</a></div><div class="question-content">{{question.content}}</div><div class="question-detail"><span class="question-author">{{question.author.username}}</span><span class="question-time">{{ question.create_time}}</span></div></div></li>{% endfor %}</ul>

10. 实现问题详情页面

首先定义一个视图函数处理访问 问题详情页的请求

qa.py中

@bp.route('/qa/question_detail/<question_id>')
@login_require
def question_detail(question_id):question = QuestionModel.query.get(question_id)return render_template("detail.html", question = question)

index.html 中, 点击问题标题进入详情页

 <div class="question-title"><a href="{{url_for('qa.question_detail', question_id = question.id)}}">{{ question.title }}</a></div>

detail.html 中

<h3 class="page-title">{{question.title}}</h3><p class="question-info"><span>{{ question.author.username }}</span><span>{{question.create_time}}</span></p><hr><p class="question-content">{{ question.content }}</p>

11. 实现评论功能

11.1 创建评论实体类

Comment.py

class CommentModel(db.Model):__tablename__ = 'comment'id = db.Column(db.Integer, primary_key=True, autoincrement=True)content = db.Column(db.Text, nullable=False)create_time = db.Column(db.DateTime, default=datetime.now)# 一个评论对应一个用户, 一个用户可以有多个评论author_id = db.Column(db.Integer, db.ForeignKey("user.id"))author = db.relationship(UserModel, backref="comments")# 一个评论对应一个问题, 一个问题可以有多个评论question_id = db.Column(db.Integer, db.ForeignKey("question.id"))question = db.relationship(QuestionModel, backref=db.backref("comments", order_by=create_time.desc()))

11.2 评论表单验证

form.py 中

class CommentForm(wtforms.Form):content = wtforms.StringField(validators=[Length(min=3, message="内容格式错误")])# 验证前端传递的评论是否带有该评论属于的问题idquestion_id = wtforms.IntegerField(validators=[InputRequired(message="必须传入对应问题")])

11.3 添加评论请求的视图函数

qa.py 中

# 添加评论请求
# @bp.route('/qa/add_comment', methods=["POST"])
@bp.post('/qa/add_comment')
@login_require
def add_comment():form = CommentForm(request.form)if form.validate():# 验证成功content = form.content.dataquestion_id = form.question_id.data# 保存到数据库中comment = CommentModel(content=content, question_id=question_id, author_id=g.user.id)db.session.add(comment)db.session.commit()return redirect(url_for("qa.question_detail", question_id=question_id))else:# 未验证成功print(form.errors)# 通过 request 获取 question_idreturn redirect(url_for("qa.question_detail", question_id=request.form.get("question_id")))

11.4 前端页面

detail.html

<form action="{{url_for("qa.add_comment")}}" method="post"><div class="form-group"><input type="text" placeholder="请填写评论" name="content" class="form-control"></div><input type="hidden" name="question_id" value="{{ question.id }}"><div class="form-group" style="text-align: right;"><button class="btn btn-primary">评论</button></div></form><ul class="comment-group">{% for comment in question.comments %}<li><div class="user-info"><img class="side-question-avatar" src="{{url_for('static', filename='images/11.jpg')}}" alt=""><span class="username">{{comment.author.username}}</span><span class="create-time">{{ comment.create_time}}</span></div><p class="comment-content">{{comment.content}}</p></li>{% endfor %}</ul>

12. 实现搜索问题功能

处理搜索请求的视图函数:

qa.py

@bp.route("/search")
def search_qa():# search?q=XXXq = request.args.get("q")questions = QuestionModel.query.filter(QuestionModel.title.contains(q)).all()return render_template("index.html", questions=questions)

前端页面

base.html

<li class="nav-item ml-2"><form class="form-inline my-2 my-lg-0" method="GET" action="{{url_for("qa.search_qa")}}"><input class="form-control mr-sm-2" type="search" placeholder="关键字" aria-label="Search" name="q"><button class="btn btn-outline-success my-2 my-sm-0" type="submit">搜索</button></form></li>

相关文章:

flask入门-4.项目实战

4. 项目实战1 1. 问答平台项目结构搭建 项目结构 config.py hostname "127.0.0.1" port 3306 username "root" password "root"database "flask_qa"# 在 app.config 中设置连接数据库的信息 SQLALCHEMY_DATABASE_URI f"…...

java 1(概要、变量与运算符)

java ——概要、变量与运算符 ✍作者&#xff1a;电子科大不知名程序员 &#x1f332;专栏&#xff1a;java学习指导 各位读者如果觉得博主写的不错&#xff0c;请诸位多多支持&#xff1b;如果有错误的地方&#xff0c;欢迎在评论区指出 目录java ——概要、变量与运算符命令行…...

​力扣解法汇总2363. 合并相似的物品

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣 描述&#xff1a; 给你两个二维整数数组 items1 和 items2 &#xff0c;表示两个物品集合。每个数…...

2022年终总结-找回初心

和“那个夏天”群聊的几位死党聊完天后&#xff0c;发现自己已经忘了初心2年有余了&#xff0c;也是这次聊天让我重新燃起了要继续努力奋斗的想法。那就说一说2022年我过得如何吧。2022年过完春节刚来公司的几天就传来了一个好消息&#xff0c;我涨薪了。在没有涨薪之前私下有时…...

Allegro如何打开或者关闭DFA规则设置操作指导

Allegro如何打开或者关闭DFA规则设置操作指导 在用Allegro做PCB布局的时候,器件与器件之间的DFA规则可以避免器件出现装配问题。如下图 当DFA规则设置好之后,如何打开或者关闭规则,具体操作如下 点击Setup点击Constraints...

kind kubernetes 集群内如何通过 helm 部署定制化 Prometheus-Operator?

文章目录1. Prometheus 简介2. Prometheus 优势3. Prometheus 架构图4. Prometheus-Operator 简介5. Prometheus-Operator 架构图6. 环境准备7. Kind 部署 Kubernetes7.1 安装 Ingress-nginx 组件7.2 安装 Metric Server 组件8. helm 快速安装 Prometheus-Operator9. 定制 Prom…...

流媒体付服务器 ZLMediaKit 学习记录

1.官方github&#xff1a;ZLMediaKit 依赖于 media-server 库 #国内用户推荐从同步镜像网站gitee下载 git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit #千万不要忘记执行这句命令 git submodule update --init 之后 cd ZLMediaKit mkdir build…...

2023年了还不会写软件测试简历吗,那就来看这里吧,怎么样才能更容易让HR看到你的简历

作为软件测试的从业者&#xff0c;面试或者被面试都是常有的事。 可是不管怎样&#xff0c;和简历有着理不清的关系&#xff0c;面试官要通过简历了解面试者的基本信息、过往经历等。 面试者希望通过简历把自己最好的一面体现给面试官&#xff0c;所以在这场博弈中&#xff0…...

第四阶段08-基于element-ui的vue2.0脚手架(续)

42. VUE脚手架项目嵌套路由 在配置路由&#xff08;配置/src/router/index.js&#xff09;时&#xff0c;如果配置的路由对象是routes常量的直接数组元素&#xff0c;则此路由配置的视图会显示在App.vue的<router-view/>中。 在设计视图时&#xff0c;可能会出现<ro…...

数据库设计规范

三范式首先&#xff0c;设计数据库&#xff0c;要尽可能的满足三范式&#xff0c;遵循三范式开发会减少数据冗余、提升系统可扩展性和查询性能。第一范式的目标是确保每列的原子性如果每列都是不可再分的最小数据单元&#xff08;也称为最小的原子单元&#xff09;&#xff0c;…...

深入浅出PaddlePaddle函数——paddle.Tensor

分类目录&#xff1a;《深入浅出PaddlePaddle函数》总目录 Tensor是Paddle中最为基础的数据结构&#xff0c;有几种创建Tensor的不同方式&#xff1a; 用预先存在的数据创建1个Tensor&#xff0c;请参考paddle.to_tensor创建一个指定shape的Tensor&#xff0c;请参考paddle.on…...

docker删除已停止的容器

一、docker删除已停止的容器 1、根据容器的状态&#xff0c;删除Exited状态的容器 先停止容器、再删除镜像中的容器、最后删除none的镜像。执行命令如下&#xff1a; docker stop $(docker ps -a | grep "Exited" | awk {print $1 }) #停止容器 docker rm $(docke…...

JS#1 引入方式和基础语法

JavaScript(JS)是一门跨平台, 面向对象的脚本语言, 来控制网页行为的, 它能够是网页可交互一. 引入方式内部脚本与外部脚本内部脚本: 将JS代码定义在HTML页面中外部脚本: 将JS代码定义在外部JS文件中, 然后引入到HTML页面中注意: 在HTML中,JS代码必须位于<script></sc…...

面了一个测试工程师,明显感觉他背了很多面试题...

最近有朋友去字节面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…...

C#生成缩略图

using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;using System.Drawing.Imaging;using System.Text;namespace learun.util{public enum ThumbnailMode{/// <summary>/// 指定宽度&#xff0c;高度按照比例缩放/// …...

算法 # SimHash 算法:文本相似度、文本去重、海量文本快速查询

SimHash SimHash 是 Google 发明的海量网页去重的高效算法,将原始的文本映射为 64 位的二进制串,然后通过比较二进制的差异进而表示原始文本内容的差异。 传统的 Hash 算法只负责将原始内容尽量均匀随机地映射为一个 hash 值,原理上相当于伪随机数产生算法。SimHash 本身属…...

Java程序设计-JSP程序设计-SSM校园二手交易系统

摘 要 网络的广泛应用给生活带来了十分的便利。所以把二手物品交易管理与现在网络相结合&#xff0c;利用java技术建设二手物品交易系统&#xff0c;实现二手物品交易的信息化。则对于进一步提高二手物品交易管理发展&#xff0c;丰富二手物品交易管理经验能起到不少的促进作用…...

springBoot 消息转换器和自定义消息转换器

public interface HttpMessageConverter<T> {/*** 能否以指定的类读取*/boolean canRead(Class<?> clazz, Nullable MediaType mediaType);/*** 能否以指定的类写*/boolean canWrite(Class<?> clazz, Nullable MediaType mediaType);/*** 返回支持是消息转…...

机器学习笔记之流形模型——标准流模型基本介绍

机器学习笔记之流形模型——标准流模型基本介绍引言回顾&#xff1a;隐变量模型的缺陷标准流(Normalizing Flow\text{Normalizing Flow}Normalizing Flow)思想分布变换的推导过程引言 本节将介绍概率生成模型——标准流模型(Normalizing Flow\text{Normalizing Flow}Normalizi…...

MIT:只需一层RF传感器,就能为AR头显赋予“X光”穿透视力

近年来&#xff0c;AR在仓库、工厂等场景得到应用&#xff0c;比如GlobalFoundries、亚马逊、菜鸟裹裹就使用摄像头扫描定位货品&#xff0c;并使用AR来导航和标记。目前&#xff0c;这种方案主要基于视觉算法&#xff0c;因此仅能定位视线范围内的目标。然而&#xff0c;在一些…...

对 Dom 树的理解

什么是 DOM 从网络传给渲染引擎的 HTML 文件字节流是无法直接被渲染引擎理解的&#xff0c;所以要将其转化为渲染引擎能够理解的内部结构&#xff0c;这个结构就是 DOM。 DOM 提供了对 HTML 文档结构化的表述。 在渲染引擎中&#xff0c;DOM 有三个层面的作用&#xff1a; …...

电商搜索入门

一、搜索用途通常一个电商平台里面的商品&#xff0c;少则几十万多则上千万甚至上亿的sku&#xff0c;在这么多的商品中&#xff0c;如何让用户可以快速查找到自己想要的商品&#xff0c;那么就需要用到搜索功能来实现。通过分析数据发现&#xff0c;接近40%的点击率是直接通过…...

4.3.1初阶数据结构(C语言)(无头不循环单链表)

1.完整的单链表注释&#xff1a; #pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h>typedef int SLTDateType; // 重定义数据类型typedef struct SListNode // 定义结构体类型的节点 {SLTDateType data;str…...

一文深度解读音视频行业技术发展历程

从1948年的香农定律&#xff0c;到音视频的今天。IMMENSE、36氪&#xff5c;作者 北京时间2月28日凌晨&#xff0c;FIFA年度颁奖典礼在巴黎举行。梅西荣膺年度最佳球员&#xff0c;斯卡洛尼当选年度最佳男足主帅&#xff0c;马丁内斯荣获年度最佳男足门将&#xff01;阿根廷因…...

面向对象拓展贴

1. 类和对象的内存分配机制 1.1 分配机制  Java 内存的结构分析 栈&#xff1a; 一般存放基本数据类型(局部变量)堆&#xff1a; 存放对象(Cat cat , 数组等)方法区&#xff1a;常量池(常量&#xff0c;比如字符串)&#xff0c; 类加载信息示意图 [Cat (name, age, price)]…...

Android仿QQ未读消息拖拽粘性效果

效果图原理分析首先是在指定某个位置画一个圆出来&#xff0c;手指按到这个圆的时候再绘制一个可以根据手指位置移动的圆&#xff0c;随着手指的移动两个圆逐渐分离&#xff0c;分离的过程中两圆中间出现连接带&#xff0c;随着两圆圆心距的增大&#xff0c;半径也是根据某一比…...

Linux 打包压缩解压指令 gzip bzip2 tar

总结自鸟哥Linux私房菜 Linux压缩文件的扩展名大多是&#xff1a;“.tar, .tar.gz, .tgz, .gz, .Z, .bz2, *.xz”&#xff0c; 不同压缩文件使用了不同的算法&#xff0c;不能通用压缩或解压 常见扩展名&#xff1a; *.Z compress 程序压缩的文件&#xff1b; *.zip zip 程序…...

系统升级丨分享返佣,助力商企实现低成本高转化营销

秉承助力传统经济数字化转型的长远理念 酷雷曼VR再次在VR全景营销中发力 创新研发“分享返佣”功能 进一步拓宽商企VR全景营销渠道 助力商企搭建低成本、高传播、高转化 的VR营销体系 01、什么是“分享返佣”&#xff1f; ●“分享返佣”即“推广”返佣&#xff0c;是酷…...

机试代码模板

文章目录进制转换高精度加/乘法搜索BFSDFS树二叉树遍历图Dijkstra算法Kruskal算法动态规划最长公共子序列(LCS)最长上升子序列(LIS)KMP算法进制转换 #include <iostream> #include <string> #include <cmath> #include <iomanip> #include <algori…...

Java性能优化-垃圾回收算法-理解CMS回收器

垃圾回收算法 理解 CMS回收器 三个基本操作 1.回收新生代&#xff08;同时暂停所有的应用线程&#xff09; 2.运行并发周期来清理老年代数据 3.如果有必要则FULL GC压缩老年代 当发生新生代回收 &#xff0c; 如果老年代没有足够的空间容纳晋升的对象则执行FULL GC,所有线程停…...

Oracle11G的表空间数据文件大小限制问题处理

1.表空间数据文件容量 oracle11g的表空间数据文件容量与DB_BLOCK_SIZE有关&#xff0c;在初始建库时&#xff0c;DB_BLOCK_SIZE要根据实际需要&#xff0c;设置为 4K,8K、16K、32K、64K等几种大小&#xff0c;ORACLE的物理文件最大只允许4194304个数据块&#xff08;由操作系统…...

计算机三级|网络技术|备考指南|网络系统结构与设计的基本原则|1

一、网络系统结构与设计的基本原则宽带城域网的关键技术p1 p2 p3设计一个宽带城域网涉及“三个平台一个出口”&#xff0c;即网络平台、业务平台、管理平台和城市宽带出口。宽带城域网&#xff1a;宽带城域网划分为三个层次&#xff1a;核心层、汇聚层、接入层。核心层承担高速…...

基于 TI Sitara系列 AM64x核心板——程序自启动说明

前 言 本文主要介绍AM64x的Cortex-A53、Cortex-M4F和Cortex-R5F核心程序自启动使用说明。默认使用AM6442进行测试演示,AM6412测试步骤与之类似。 本说明文档适用开发环境如下: Windows开发环境:Windows 7 64bit、Windows 10 64bit 虚拟机:VMware15.5.5 Linux开发环境:Ubun…...

自学5个月Java找到了9K的工作,我的方式值得大家借鉴 第一部分

我是去年9月22日才正式学习Java的&#xff0c;因为在国营单位工作了4年&#xff0c;在天津一个月工资只有5000块&#xff0c;而且看不到任何晋升的希望&#xff0c;如果想要往上走&#xff0c;那背后就一定要有关系才行。而且国营单位的气氛是你干的多了&#xff0c;领导觉得你…...

微电影广告的内容突破方案

微电影作为新媒体时代背景的产物&#xff0c;深受大众的欢迎&#xff0c;同时&#xff0c;微电影广告在微电影模式环境下应运而生&#xff0c;以自己独特的传播优势&#xff0c;俘获了大量企业主的青睐&#xff0c;也获得了广大青年群体的喜爱。微电影广告欲确保可持续发展&…...

茌平区为什么越来越多的企业由请高新技术企业?山东同邦科技分享

茌平区为什么越来越多的企业由请高新技术企业?山东同邦科技分享 近年来&#xff0c;越来越多的企业开始申报高新技术企业&#xff0c;认定为国家高新技术企业能获得非常多的好处&#xff0c;那么具体都有哪些呢? 一、国际高新技术企业认定的好处: 1、财政补贴: 获得高新企业…...

谷歌优化排名怎么做出来的?谷歌排名多久做上去?

本文主要分享谷歌排名的算法机制&#xff0c;让你很容易地用更短的时间把Google的自然排名做到首页。 本文由光算创作&#xff0c;有可能会被剽窃和修改&#xff0c;我们佛系对待这种行为吧。 谷歌优化排名怎么做出来的&#xff1f; 答案是&#xff1a;持续更新原创优质内容…...

字节跳动青训营--Webpack

文章目录前言一、为什么要学习Webpack&#xff1f;二、什么是Webpack&#xff1f;1. 产生背景2. 基础概念三、使用Webpack1. 安装2. 编辑配置文件3. 执行编译命令核心流程四、如何使用Webpack流程类配置配置总览五、理解Loader六、理解插件插件钩子课外关注资料前言 此文章仅用…...

微信多媒体文件speex格式转为mp3文件格式

1、安装speex环境 wget https://ftp.osuosl.org/pub/xiph/releases/speex/speex-1.2.0.tar.gz tar -zxvf speex-1.2.0.tar.gz -C /usr/local/ cd /usr/local/speex-1.2.0/ ./configure make make install 2、配置path到/usr/lib 因为安装的speex生成的可执行文件默认在/usr…...

IAP初探

IAP(In-Application Programming)在应用编程&#xff0c;浅显易懂&#xff0c;按照字面意思即是在程序不关闭情况下&#xff0c;对应用进行再次写入程序&#xff0c;对程序的写入需要传输数据&#xff0c;而传输数据的前提是通信&#xff0c; IAP对代码进行更新可以简要分为以…...

【组织架构】中国铁路兰州局集团有限公司

1 公司简介 中国铁路兰州局集团有限公司&#xff0c;是中国国家铁路集团有限公司管理的18个铁路局集团有限公司之一&#xff0c;简称“兰局”。经过59年的发展&#xff0c;现已成为西北地区最大的交通运输企业之一&#xff0c;形成了以兰州为枢纽&#xff0c;由陇海铁路、包兰铁…...

【计算机三级网络技术】 第四篇 路由设计技术基础

文章目录一、分组转发二、路由选择1.理想的路由算法的基本特征2.路由算法的度量标准3.路由算法分类&#xff1a;4.IP路由选择与路由汇聚(重点)三、自治系统与Internet的路由选择协议1.自治系统2.路由选择协议的分类四、内部网关协议1.RIP的基本概念2.RIP的原理3.RIP的运行过程五…...

嵌入式工程师进阶,基于AM64x开发板的IPC多核开发案例分享

前 言 本文档主要说明AM64x基于IPC的多核开发方法。默认使用AM6442进行测试演示,AM6412测试步骤与之类似。 适用开发环境如下: Windows开发环境:Windows 7 64bit、Windows 10 64bit 虚拟机:VMware15.5.5 Linux开发环境:Ubuntu 18.04.4 64bit Linux Processor SDK:ti-proc…...

腾讯安全与锐捷网络战略合作,威胁情报能力“被集成”

2月28日&#xff0c;腾讯安全和锐捷网络在北京联合举办“威胁情报”战略合作发布会。双方发布了一款集成了腾讯安全威胁情报的新一代防火墙&#xff0c;并举办战略合作签约仪式。会上&#xff0c;锐捷网络安全产品事业部总经理项小升、腾讯安全总经理陈龙代表双方签署战略合作协…...

接口自动化测试用例详解

phpunit 接口自动化测试系列 Post接口自动化测试用例 Post方式的接口是上传接口&#xff0c;需要对接口头部进行封装&#xff0c;所以没有办法在浏览器下直接调用&#xff0c;但是可以用Curl命令的-d参数传递接口需要的参数。当然我们还以众筹网的登录接口为例&#xff0c;讲…...

【数据库增删查改进阶版】保姆级教程带大家去学习更加复杂的sql语句,各种各样的约束以及各种各样的查询

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#x1f345;&#x1f345;&#x1f345;&#xff0c;上一篇数据库我们一起学习了基础版本的增删查改&#xff0c;今天我们将接触更高级的增删查改&#xff0c;主要是学习一些约束条件&#xff0c;你们准备好了嘛&#xff1f;开…...

【C#基础】C# 正则表达式

序号系列文章7【C#基础】C# 常用数据结构8【C#基础】C# 面向对象编程9【C# 基础】C# 异常处理操作文章目录前言1&#xff0c;Regex 的概念2&#xff0c;Regex 的创建3&#xff0c;Regex 常用操作4&#xff0c;Regex 类的使用5&#xff0c;学习资源推荐结语前言 &#x1f33c; h…...

企业活动直播如何设置VIP观看席?

阿酷tony / 2023-2-28 / 长沙 / 多图内容企业活动直播如何设置VIP观看席&#xff1f;有意思吧&#xff0c;直播也能设vip席位。在直播间可以分设尊享嘉宾席、特邀VIP以及观众席三个区域&#xff0c;为企业提供多种用户接待模式&#xff0c;不仅能为嘉宾营造尊享VIP体验&#xf…...

线性代数学习-2

线性代数学习-2矩阵消元消元回代消元矩阵置换矩阵逆矩阵本文转载于https://herosunly.blog.csdn.net/article/details/88713747 该文章本人认为十分有用&#xff0c;便自己敲一遍笔记加固印象原文链接 原文这个笔记感觉比我老师讲的更加透彻&#xff0c;清晰。很好的展示了线性…...

Java 类

Java类是Java编程语言中的基本概念之一&#xff0c;用于描述对象的属性和方法。本文将详细介绍Java类的作用、定义和使用&#xff0c;以及在实际工作中的应用。 什么是Java类&#xff1f; Java类是一种用于描述对象的模板或蓝图。它定义了一个对象的属性和方法&#xff0c;以…...