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

【UniApp开发小程序】私聊功能uniapp界面实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】

文章目录

  • 效果显示
  • WebSocket连接
    • 使用全局变量
    • WebSocket连接细节
  • 最近和自己聊天的用户信息
    • 界面效果
    • 界面代码
      • 最近的聊天内容太长
      • 日期时间显示
      • 未读消息数量显示
  • 私聊界面
    • 界面展示
    • 代码实现
      • 英文长串不换行问题
      • 聊天区域自动滑动到底部
      • 键盘呼出,聊天区域收缩,聊天区域滑动到底部
      • 通知WebSocket服务器哪两个用户开始聊天

效果显示

在这里插入图片描述

WebSocket连接

使用全局变量

本小程序在用户浏览首页的时候创建WebSocket连接,并将连接获得的WebSocket对象存储到全局变量中,方便其他页面来使用WebSocket

首先在项目的main.js文件中声明全局变量socket

在这里插入图片描述

Vue.prototype.$socket = null

对全局变量进行赋值

Vue.prototype.$socket = this.$socket;

后续如果需要使用全局变量,直接使用this.$socket即可

WebSocket连接细节

下面的代码中有一个headbeat方法,该方法主要用来定时给WebSocket服务器发送一个信号,告诉WebSocket服务器当前客户端还处于连接状态。当心跳停止的时候(比如客户端断网),后端服务就会将用户信息从连接中移除

/*** 创建websocket连接*/
initWebsocket() {// console.log("this.socket:" + this.$socket)if (this.$socket == null || this.$socket.readyState != 1) {this.$socket = uni.connectSocket({url: "ws://10.23.17.146:8085/websocket/" + uni.getStorageSync("curUser").userName,success(res) {console.log('WebSocket连接成功', res);},})// console.log("this.socket:" + this.$socket)// 监听WebSocket连接打开事件this.$socket.onOpen((res) => {console.log("websocket连接成功")Vue.prototype.$socket = this.$socket;// 连接成功,开启心跳this.headbeat();});// 连接异常this.$socket.onError((res) => {console.log("websocket连接出现异常");// 重连this.reconnect();})// 连接断开this.$socket.onClose((res) => {console.log("websocket连接关闭");// 重连this.reconnect();})}
},
/*** 重新连接*/
reconnect() {console.log("重连");// 防止重复连接if (this.lockReconnect == true) {return;}// 锁定,防止重复连接this.lockReconnect = true;this.initWebsocket();// 连接完成,设置为falsethis.lockReconnect = false;
},
// 开启心跳
headbeat() {console.log("websocket心跳");var that = this;setTimeout(function() {if (that.$socket.readyState == 1) {// websocket已经连接成功that.$socket.send({data: JSON.stringify({status: "ping"})})// 调用启动下一轮的心跳that.headbeat();} else {// websocket还没有连接成功,重连that.reconnect();}}, that.heartbeatTime);
},

最近和自己聊天的用户信息

界面效果

在这里插入图片描述

界面代码

<template><view class="container"><scroll-view @scrolltolower="getMoreChatUserVo"><view v-for="(chatUserVo,index) in chatUserVoList" :key="index" @click="trunToChat(chatUserVo)"><view style="height: 10px;"></view><view class="chatUserVoItem"><view style="display: flex;align-items: center;"><uni-badge class="uni-badge-left-margin" :text="chatUserVo.unReadChatNum" absolute="rightTop"size="small"><u--image :showLoading="true" :src="chatUserVo.userAvatar" width="50px" height="50px":fade="true" duration="450"><view slot="error" style="font-size: 24rpx;">加载失败</view></u--image></uni-badge></view><view style="margin: 10rpx;"></view><viewstyle="line-height: 20px;width: 100%;display: flex;justify-content: space-between;flex-direction: column;"><view style="display: flex;	justify-content: space-between;"><view><view class="nickname">{{chatUserVo.userNickname}}</view><view class="content">{{chatUserVo.lastChatContent}}</view></view><view class="date">{{formatDateToString(chatUserVo.lastChatDate)}}</view></view><!-- <view style="height: 10px;"></view> --><u-line></u-line></view></view></view></scroll-view></view>
</template><script>import {listChatUserVo} from "@/api/market/chat.js";import {listChat} from "@/api/market/chat.js"export default {data() {return {chatUserVoList: [],page: {pageNum: 1,pageSize: 15},}},created() {},methods: {/*** 滑动到底部,自动加载新一页的数据*/getMoreChatUserVo() {this.page.pageNum++;this.listChatUserVo();},listChatUserVo() {listChatUserVo(this.page).then(res => {// console.log("res:"+JSON.stringify(res.rows))// this.chatUserVoList = res.rows;for (var i = 0; i < res.rows.length; i++) {this.chatUserVoList.push(res.rows[i]);}})},/*** 格式化日期* @param {Object} date*/formatDateToString(dateStr) {let date = new Date(dateStr);// 今天的日期let curDate = new Date();if (date.getFullYear() == curDate.getFullYear() && date.getMonth() == curDate.getMonth() && date.getDate() == curDate.getDate()) {// 如果和今天的年月日都一样,那就只显示时间return this.toDoubleNum(date.getHours()) + ":" + this.toDoubleNum(date.getMinutes());} else {// 如果年份一样,就只显示月日return (curDate.getFullYear() == date.getFullYear() ? "" : (date.getFullYear() + "-")) + this.toDoubleNum((date.getMonth() + 1)) +"-" +this.toDoubleNum(date.getDate());}},/*** 如果传入的数字是两位数,直接返回;* 否则前面拼接一个0* @param {Object} num*/toDoubleNum(num) {if (num >= 10) {return num;} else {return "0" + num;}},/*** 转到私聊页面*/trunToChat(chatUserVo) {let you = {avatar: chatUserVo.userAvatar,nickname: chatUserVo.userNickname,username: chatUserVo.userName}uni.navigateTo({url: "/pages/chat/chat?you=" + encodeURIComponent(JSON.stringify(you))})},/*** 接收消息*/receiveMessage() {this.$socket.onMessage((response) => {// console.log("接收消息:" + response.data);let message = JSON.parse(response.data);// 收到消息,将未读消息数量加一for (var i = 0; i < this.chatUserVoList.length; i++) {if (this.chatUserVoList[i].userName == message.from) {this.chatUserVoList[i].unReadChatNum++;// 显示对方发送的最新消息listChat(message.from, {pageNum: 1,pageSize: 1}).then(res => {this.chatUserVoList[i].lastChatContent = res.rows[0].content});break;}}})},},onLoad(e) {this.receiveMessage();},onShow: function() {this.chatUserVoList = [];this.listChatUserVo();},}
</script><style lang="scss">.container {padding: 20rpx;.chatUserVoItem {display: flex;margin: 0 5px;.nickname {font-weight: 700;}.content {color: #A7A7A7;font-size: 14px;/* 让消息只显示1行,超出的文字内容使用...来代替 */overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 1;-webkit-box-orient: vertical;}.date {color: #A7A7A7;font-size: 12px;}}// .uni-badge-left-margin {// 	margin-left: 10px;// }}
</style>

最近的聊天内容太长

当最近的一条聊天内容太长的时候,页面不太美观,缺少整齐的感觉
在这里插入图片描述
解决的方式非常简单,只需要添加以下样式即可

.content {/* 让消息只显示1行,超出的文字内容使用...来代替 */overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 1;-webkit-box-orient: vertical;
}

在这里插入图片描述

日期时间显示

本文显示日期时间的时候,遵循以下原则:

  • 如果上次聊天时间的年月日和今天一致,那就只显示时间,即显示 时:分
  • 如果上次聊天时间的年份和今年一致,那就只显示月-日
  • 如果上面的条件都不满足,就显示年-月-日

在显示月、日、时、分的时候,如果数字是一位数字,就在前面补一个零,具体操作如方法toDoubleNum

/*** 格式化日期* @param {Object} date*/
formatDateToString(dateStr) {let date = new Date(dateStr);// 今天的日期let curDate = new Date();if (date.getFullYear() == curDate.getFullYear() && date.getMonth() == curDate.getMonth() && date.getDate() == curDate.getDate()) {// 如果和今天的年月日都一样,那就只显示时间return this.toDoubleNum(date.getHours()) + ":" + this.toDoubleNum(date.getMinutes());} else {// 如果年份一样,就只显示月日return (curDate.getFullYear() == date.getFullYear() ? "" : (date.getFullYear() + "-")) + this.toDoubleNum((date.getMonth() + 1)) +"-" +this.toDoubleNum(date.getDate());}
},
/**
* 如果传入的数字是两位数,直接返回;* 否则前面拼接一个0* @param {Object} num*/
toDoubleNum(num) {if (num >= 10) {return num;} else {return "0" + num;}
},

未读消息数量显示

未读消息数量显示使用角标组件,即uni-badge,使用该组件需要下载安装插件,下载链接,下载之前需要看广告,哈哈哈,当然有钱可以不看

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

<uni-badge class="uni-badge-left-margin" :text="chatUserVo.unReadChatNum" absolute="rightTop"size="small"><u--image :showLoading="true" :src="chatUserVo.userAvatar" width="50px" height="50px":fade="true" duration="450"><view slot="error" style="font-size: 24rpx;">加载失败</view></u--image>
</uni-badge>

私聊界面

界面展示

【微信公众平台模拟的手机界面】
在这里插入图片描述
【手机端,键盘呼出之后的聊天区域】
在这里插入图片描述

代码实现

<template><view style="height:100vh;"><!-- @scrolltoupper:上滑到顶部执行事件,此处用来加载历史消息 --><!-- scroll-with-animation="true" 设置滚动条位置的时候使用动画过渡,让动作更加自然 --><scroll-view :scroll-into-view="scrollToView" scroll-y="true" class="messageListScrollView":style="{height:scrollViewHeight}" @scrolltoupper="getHistoryChat()":scroll-with-animation="!isFirstListChat" ref="chatScrollView"><view v-for="(message,index) in messageList" :key="message.id" :id="`message`+message.id"style="width: 750rpx;min-height: 60px;"><view style="height: 10px;"></view><view v-if="message.type==0" class="messageItemLeft"><view style="width: 8px;"></view><u--image :showLoading="true" :src="you.avatar" width="50px" height="50px" radius="3"></u--image><view style="width: 7px;"></view><view class="messageContent left">{{message.content}}</view></view><view v-if="message.type==1" class="messageItemRight"><view class="messageContent right">{{message.content}}</view><view style="width: 7px;"></view><u--image :showLoading="true" :src="me.avatar" width="50px" height="50px" radius="3"></u--image><view style="width: 8px;"></view></view></view></scroll-view><view class="messageSend"><view class="messageInput"><u--textarea v-model="messageInput" placeholder="请输入消息内容" autoHeight></u--textarea></view><view style="width:5px"></view><view class="commmitButton" @click="send()">发 送</view></view></view></template><script>import {getUserProfileVo} from "@/api/user";import {listChat} from "@/api/market/chat.js"let socket;export default {data() {return {webSocketUrl: "",socket: null,messageInput: '',// 我自己的信息me: {},// 对方信息you: {},scrollViewHeight: undefined,messageList: [],// 底部滑动到哪里scrollToView: '',page: {pageNum: 1,pageSize: 15},isFirstListChat: true,loadHistory: false,// 消息总条数total: 0,}},created() {this.me = uni.getStorageSync("curUser");},beforeDestroy() {console.log("执行销毁方法");this.endChat();},onLoad(e) {// 设置初始高度this.scrollViewHeight = `calc(100vh - 20px - 44px)`;this.you = JSON.parse(decodeURIComponent(e.you));uni.setNavigationBarTitle({title: this.you.nickname,})this.startChat();this.listChat();this.receiveMessage();},onReady() {// 监听键盘高度变化,以便设置输入框的高度uni.onKeyboardHeightChange(res => {let keyBoardHeight = res.height;console.log("keyBoardHeight:" + keyBoardHeight);this.scrollViewHeight = `calc(100vh - 20px - 44px - ${keyBoardHeight}px)`;this.scrollToView = '';setTimeout(() => {this.scrollToView = 'message' + this.messageList[this.messageList.length - 1].id;}, 150)})},methods: {/*** 发送消息*/send() {if (this.messageInput != '') {let message = {from: this.me.userName,to: this.you.username,text: this.messageInput}// console.log("this.socket.send:" + this.$socket)// 将组装好的json发送给服务端,由服务端进行转发this.$socket.send({data: JSON.stringify(message)});this.total++;let newMessage = {// code: this.messageList.length,type: 1,content: this.messageInput};this.messageList.push(newMessage);this.messageInput = '';this.toBottom();}},/*** 开始聊天*/startChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "start"}// 告诉服务端要开始聊天了this.$socket.send({data: JSON.stringify(message)});},/*** 结束聊天*/endChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "end"}// 告诉服务端要结束聊天了this.$socket.send({data: JSON.stringify(message)});},/*** 接收消息*/receiveMessage() {this.$socket.onMessage((response) => {// console.log("接收消息:" + response.data);let message = JSON.parse(response.data);let newMessage = {// code: this.messageList.length,type: 0,content: message.text};this.messageList.push(newMessage);this.total++;// 让scroll-view自动滚动到最新的数据那里// this.$nextTick(() => {// 	// 滑动到聊天区域最底部// 	this.scrollToView = 'message' + this.messageList[this// 		.messageList.length - 1].id;// });this.toBottom();})},/*** 查询对方和自己最近的聊天数据*/listChat() {return new Promise((resolve, reject) => {listChat(this.you.username, this.page).then(res => {for (var i = 0; i < res.rows.length; i++) {this.total = res.total;if (res.rows[i].fromWho == this.me.userName) {res.rows[i].type = 1;} else {res.rows[i].type = 0;}// 将消息放到数组的首位this.messageList.unshift(res.rows[i]);}if (this.isFirstListChat == true) {// this.$nextTick(function() {// 	// 滑动到聊天区域最底部// 	this.scrollToView = 'message' + this.messageList[this// 		.messageList.length - 1].id;// })this.toBottom();this.isFirstListChat = false;}resolve();})})},/*** 滑到最顶端,分页加一,拉取更早的数据*/getHistoryChat() {// console.log("获取历史消息")this.loadHistory = true;if (this.messageList.length < this.total) {// 当目前的消息条数小于消息总量的时候,才去查历史消息this.page.pageNum++;this.listChat().then(() => {})}},/*** 滑动到聊天区域最底部*/toBottom() {// 让scroll-view自动滚动到最新的数据那里this.scrollToView = '';setTimeout(() => {// 滑动到聊天区域最底部this.scrollToView = 'message' + this.messageList[this.messageList.length - 1].id;}, 150)}}}
</script><style lang="scss">.messageListScrollView {background: #F5F5F5;overflow: auto;.messageItemLeft {display: flex;align-items: flex-start;justify-content: flex-start;.messageContent {max-width: calc(750rpx - 10px - 50px - 15px - 10px - 50px - 15px);padding: 10px;// margin-top: 10px;border-radius: 7px;font-family: sans-serif;// padding: 10px;// 让view只包裹文字width: auto;// display: inline-block !important;// display: inline;// 解决英文字符串、数字不换行的问题word-break: break-all;word-wrap: break-word;}}.messageItemRight {display: flex;align-items: flex-start;justify-content: flex-end;.messageContent {max-width: calc(750rpx - 10px - 50px - 15px - 10px - 50px - 15px);padding: 10px;// margin-top: 10px;border-radius: 7px;font-family: sans-serif;// padding: 10px;// 让view只包裹文字width: auto;// display: inline-block !important;// display: inline;// 解决长英文字符串、数字不换行的问题word-wrap: break-word;}}.right {background-color: #94EA68;}.left {background-color: #ffffff;}}.messageSend {display: flex;background: #ffffff;padding-top: 5px;padding-bottom: 15px;.messageInput {border: 1px #EBEDF0 solid;border-radius: 5px;width: calc(750rpx - 65px);margin-left: 5px;}.commmitButton {height: 38px;border-radius: 5px;width: 50px;display: flex;align-items: center;justify-content: center;color: #ffffff;background: #3C9CFF;}}
</style>

英文长串不换行问题

在这里插入图片描述

这个问题属于是整串英文被以为是一个单词了,所以没有换行,看下面的句子,英文单词可以比较短的,所以会自动换行
在这里插入图片描述

解决这个问题只需要添加下面的css即可

// 解决长英文字符串、数字不换行的问题
word-wrap: break-word;

下面是添加之后的效果

在这里插入图片描述

聊天区域自动滑动到底部

在聊天的时候,无论是发送一条新的消息,还是接收到一条新的消息,聊天区域都需要自动滑动到最新的消息那里。本文使用scroll-view组件来包裹显示聊天消息,在scroll-view组件中,可以通过给scroll-into-view属性赋值来指定聊天区域所显示到的位置。使用时需要注意如下问题:

  • 需要先给每一条消息设置一个id属性,id属性存储的内容不能以数字开头,因此本文在id之间拼接了一个字符串’message’
  • scroll-view需要被设置好高度,本文通过绑定一个变量来设置高度,如:style="{height:scrollViewHeight}",因为手机端使用小程序打字时键盘呼出会影响聊天区域的高度

在这里插入图片描述

后续通过给scrollToView设置不同的值即可控制聊天区域的滑动,比如每接收到一条新的消息,就调用toBottom方法,该方法通过设置scrollToView为'message' + this.messageList[this.messageList.length - 1].id将聊天区域滑动到最新的消息处。需要注意的是,在进行该值的设置之前,需要延迟一段时间,否则滑动可能不成功,本文延迟150ms,读者也可以探索不同的值,该值不能太大或者太小。

通过设置scroll-view的属性scroll-with-animation的值为true,可以让消息区域在滑动的时候使用动画过渡,这样滑动更加自然。

键盘呼出,聊天区域收缩,聊天区域滑动到底部

当键盘呼出时,需要将聊天区域的高度减去键盘的高度。同时将scrollToView赋值为最后一条消息的id。需要注意的是,在设置scrollToView之前,需要先将scrollToView设置为空字符串,否则滑动效果可能不成功

onReady() {// 监听键盘高度变化,以便设置输入框的高度uni.onKeyboardHeightChange(res => {let keyBoardHeight = res.height;console.log("keyBoardHeight:" + keyBoardHeight);this.scrollViewHeight = `calc(100vh - 20px - 44px - ${keyBoardHeight}px)`;this.scrollToView = '';setTimeout(() => {this.scrollToView = 'message' + this.messageList[this.messageList.length - 1].id;}, 150)})
},

通知WebSocket服务器哪两个用户开始聊天

为了便于后端在存储聊天数据的时候辨别消息是否为已读状态。比如,在小王开始聊天之前,需要先告诉后端:“小王要开始和小明聊天了”,如果正好小明也告诉后端:“我要和小王聊天了”,那小王发出去的消息就会被设置为已读状态,因为他们两个此时此刻正在同时和对方聊天,那小王发出去的消息就默认被小明看到了,因此设置为已读状态

/**
* 开始聊天
*/
startChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "start"}// 告诉服务端要开始聊天了this.$socket.send({data: JSON.stringify(message)});
},
/*** 结束聊天*/
endChat() {let message = {from: this.me.userName,to: this.you.username,text: "",status: "end"}// 告诉服务端要结束聊天了this.$socket.send({data: JSON.stringify(message)});
},

相关文章:

【UniApp开发小程序】私聊功能uniapp界面实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】

文章目录 效果显示WebSocket连接使用全局变量WebSocket连接细节 最近和自己聊天的用户信息界面效果界面代码最近的聊天内容太长日期时间显示未读消息数量显示 私聊界面界面展示代码实现英文长串不换行问题聊天区域自动滑动到底部键盘呼出&#xff0c;聊天区域收缩&#xff0c;聊…...

【BASH】回顾与知识点梳理(三十六)

【BASH】回顾与知识点梳理 三十六 三十六. 认识与分析登录档36.1 什么是登录档CentOS 7 登录档简易说明登录档的重要性Linux 常见的登录档档名登录档所需相关服务 (daemon) 与程序CentOS 7.x 使用 systemd 提供的 journalctl 日志管理 登录档内容的一般格式 36.2 rsyslog.servi…...

十三、pikachu之暴力破解

文章目录 1、暴力破解概述2、基于表单的暴力破解3、验证码的绕过3.1 验证码的认证流程3.2 验证码绕过&#xff08;on client&#xff09;3.3 验证码绕过&#xff08;on server&#xff09;3.4 token防爆破&#xff1f; 1、暴力破解概述 “暴力破解”是一攻击具手段&#xff0c;…...

用手势操控现实:OpenCV 音量控制与 AI 换脸技术解析

基于opencv的手势控制音量和ai换脸 HandTrackingModule.py import cv2 import mediapipe as mp import timeclass handDetector():def __init__(self, mode False, maxHands 2, model_complexity 1, detectionCon 0.5, trackCon 0.5):self.mode modeself.maxHands max…...

【leetcode 力扣刷题】移除链表元素 多种解法

移除链表元素的多种解法 203. 移除链表元素解法①&#xff1a;头节点单独判断解法②&#xff1a;虚拟头节点解法③&#xff1a;递归 203. 移除链表元素 题目链接&#xff1a;203.移除链表元素 题目内容&#xff1a; 理解题意&#xff1a;就是单纯的删除链表中所有值等于给定的…...

leetcode503. 下一个更大元素 II 单调栈

思路&#xff1a; 与之前 739、1475 单调栈的问题如出一辙&#xff0c;唯一不同的地方就是对于遍历完之后。栈中元素的处理&#xff0c;之前的栈中元素因无法找到符合条件的值&#xff0c;直接加入vector中。而这里需要再重头遍历一下数组&#xff0c;找是否有符合条件的&…...

Oracle中列的维护

由于商业环境中&#xff0c;数据是不断变化的&#xff0c;客户的需求也是不断变化的&#xff0c;所以当一个表用了一段时间后&#xff0c;其结构就有可能需要变化。 而在Oracle中&#xff0c;提供了alter table这种方式来改变列。 从Oracle9.2版本之后&#xff1a; 如果需要变…...

后端项目开发:分页功能的实现(Mybatis+pagehelper)

分页查询是项目中的常用功能&#xff0c;此处我们基于Mybatis对分页查询进行处理。 引入分页依赖 <!-- pagehelper --> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId>…...

SpringBoot集成Drools

一:简介 规则引擎全称为业务规则管理系统(Business Rule Management System)简称BRMS,主要思想是将应用程序中的业务决策部分分离开来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。 其实就是将计算逻辑写在脚本中,通过Jav…...

React创建组件的三种方式及其区别是什么?

在React中&#xff0c;创建组件的三种主要方式是函数式组件、类组件和使用React Hooks的函数式组件。以下是对每种方式的详细解释以及它们之间的区别&#xff1a; 1、函数式组件&#xff1a; 函数式组件是使用纯粹的JavaScript函数来定义的。它接收一个props对象作为参数&…...

W6100-EVB-PICO进行UDP组播数据回环测试(九)

前言 上一章我们用我们的开发板作为UDP客户端连接服务器进行数据回环测试&#xff0c;那么本章我们进行UDP组播数据回环测试。 什么是UDP组播&#xff1f; 组播是主机间一对多的通讯模式&#xff0c; 组播是一种允许一个或多个组播源发送同一报文到多个接收者的技术。组播源将…...

Qt 阴影边框

阴影边框很常见&#xff0c;诸如360以及其他很多软件都有类似效果&#xff0c;了解CSS3的同学们应该都知道box-shadow&#xff0c;它就是来设定阴影效果的&#xff0c;那么Qt呢&#xff1f;看过一些资料&#xff0c;说是QSS是基于CSS2的&#xff0c;既然如此&#xff0c;box-sh…...

前端面试:【性能优化】页面加载性能、渲染性能、资源优化

嗨&#xff0c;亲爱的前端开发者&#xff01;在今天的Web世界中&#xff0c;用户期望页面加载速度快、交互流畅。因此&#xff0c;前端性能优化成为了至关重要的任务。本文将探讨三个关键方面的性能优化&#xff1a;页面加载性能、渲染性能以及资源优化&#xff0c;以帮助你构建…...

从按下电源键到进入系统,CPU在干什么?

本专栏更新速度较慢&#xff0c;简单讲讲计算机的那些事&#xff0c;简单讲讲那些特别散乱杂的知识&#xff0c;欢迎各位朋友订阅专栏啊 感谢一路相伴的朋友们 浅淡操作系统系列第2篇 目录 通电 保护模式和实模式 内存管理单元MMU 逻辑地址&#xff1f;物理地址&#xff1…...

TypeScript初体验

1.安装编译TS工具包 npm i -g typescript 2. 查看版本号 tsc -v 3.创建ts文件 说明&#xff1a;创建一个index.ts文件 4.TS编译为JS tsc index.ts 5.执行JS代码 node index.js 6.简化TS的步骤 6.1安装 npm i -g ts-node 6.2执行 ts-node index.ts...

基于 Alpine 环境源码构建 alibaba-tengine(阿里巴巴)的 Docker 镜像

About Alpine&#xff08;简介&#xff09; Alpine Linux 是一款极其轻量级的 Linux 发行版&#xff0c;基于 busybox&#xff0c;多被当做 Docker 镜像的底包&#xff08;基础镜像&#xff09;&#xff0c;在使用容器时或多或少都会接触到此系统&#xff0c;本篇文章我们以该镜…...

政府网站定期巡检:构建高效、安全与透明的数字政务

在数字时代&#xff0c;政府网站已不仅仅是一个信息发布窗口&#xff0c;更是政府与公众互动的桥梁、政务服务的主要渠道以及数字化治理的重要平台。因此&#xff0c;确保政府网站的高效运行、信息安全与透明公开就显得尤为重要。在此背景下&#xff0c;定期的网站巡检与巡查成…...

C++信息学奥赛1138:将字符串中的小写字母转换成大写字母

#include<bits/stdc.h> using namespace std; int main() {string arr;// 输入一行字符串getline(cin, arr);for(int i0;i<arr.length();i){if(arr[i]>97 and arr[i]<122){char aarr[i]-32; // 将小写字母转换为大写字母cout<<a; // 输出转换后的字符}els…...

leetcode1475. 商品折扣后的最终价格 【单调栈】

简单题 第一次错误做法 class Solution { public:vector<int> finalPrices(vector<int>& prices) {int n prices.size();stack<int> st;unordered_map<int, int> mp;int i 0;while(i ! prices.size()) {int t prices[i];if (st.empty() || t …...

macOS M1使用TensorFlow GPU加速

本人是在pycharm运行代码&#xff0c;安装了tensorflow版本2.13.0 先运行代码查看有没有使用GPU加速&#xff1a; import tensorflow as tf# Press the green button in the gutter to run the script. if __name__ __main__:physical_devices tf.config.list_physical_dev…...

GNU-gcc编译选项-1

include目录 -I &#xff0c;比如: -I. -I ./Platform/include -I ./Platform/include/prototypes -I ./tpm/include -I ./tpm/include/prototypes -I ./Simulator/include -I ./Simulator/include/prototypes 编译选项 在GCC编译器中&#xff0c;-D是一个编译选项&…...

【DEVOPS】Jenkins使用问题 - 控制台输出乱码

0. 目录 1. 问题描述2. 解决方案3. 最终效果4. 总结 1. 问题描述 部门内部对于Jenkins的使用采取的是Master Slave Work Node的方式&#xff0c;即作为Master节点的Jenkins只负责任务调度&#xff0c;具体的操作由对应的Slave Work Node去执行。 最近团队成员反馈一个问题&a…...

logback-spring.xml

<?xml version"1.0" encoding"UTF-8"?> <configuration> <appender name"stdout" class"ch.qos.logback.core.ConsoleAppender"> <encoder> <springProfile name"dev"> <pattern>%d{…...

华为OD机试之报文重排序【Java源码】

题目描述 对报文进行重传和重排序是常用的可靠性机制&#xff0c;重传缓中区内有一定数量的子报文&#xff0c;每个子报文在原始报文中的顺序已知&#xff0c;现在需要恢复出原始报文。 输入描述 输入第一行为N&#xff0c;表示子报文的个数&#xff0c;0 &#xff1c;N ≤ …...

回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效…...

DPU在东数西算背景下如何赋能下一代算力基础设施 中科驭数在未来网络发展大会论道

以ChatGPT为代表的人工智能大模型的快速发展&#xff0c;对网络信息技术创新发展提出了新的挑战&#xff0c;我国东数西算重大工程也在加速布局。以确定性网络、算力网络为代表的未来网络核心技术&#xff0c;正成为决定未来经济和产业发展的关键。 8月23日&#xff0c;第七届…...

2021年12月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:移动路线 桌子上有一个m行n列的方格矩阵,将每个方格用坐标表示,行坐标从下到上依次递增,列坐标从左至右依次递增,左下角方格的坐标为(1,1),则右上角方格的坐标为(m,n)。 小明是个调皮的孩子,一天他捉来一只蚂蚁,不小心把蚂蚁的右脚弄伤了,于是蚂蚁只能向上或向右…...

ArcGIS Serve Windows下用户密码变更导致Server服务无法启动问题

问题&#xff1a; 因未知原因Windows下的Server安装账户密码变更&#xff0c;但是又忘记了密码&#xff0c;导致&#xff0c;Server服务启动失败&#xff0c;错误1069&#xff1a; 解决方法&#xff1a; 在账户管理界面&#xff0c;重置对应的arcgis账户的密码&#xff0c;…...

React 面试题集锦

目录 如果想要在组件第一次加载后获取该组件的dom元素&#xff0c;应当在以下哪个生命周期中进行 React支持的键盘事件是 使用严格模式&#xff08;Strict Mode&#xff09;优点 React 动态引入组件 当使用ReactDOM.unmountComponentAtNode从DOM中卸载组件时 说一下useS…...

xargs命令解决“Argument list too long”

一、xargs命令概述 xargs命令是给其他命令传递参数的一个过滤器&#xff0c;也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数&#xff0c;xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。空格是其默认定界符&#xff0c;管道传递给xargs的输入…...

R语言中<- 的含义

一般语言的赋值是 号&#xff0c;但是 R 语言是数学语言&#xff0c;所以赋值符号与我们数学书上的伪代码很相似&#xff0c;是一个左箭头 <- &#xff1a; 举个例子&#xff1a; a <- 12 b <- 45 print(a b) 以上代码执行结果&#xff1a;57 这个赋值符号是 R …...

知识图谱Neo4j安装到实践全过程

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 在本次实战中&#xff0c;我们将一起完成知识图谱Neo4j安装到实践全过程&#xff0c;探索其中的关系和属性。知识图谱是一种以三元组形式存储的数据结构&#xff0c;由实体、关系和属性组成&#xff0c;能够帮助我们更好地…...

贪心算法:简单而高效的优化策略

在计算机科学中&#xff0c;贪心算法是一种简单而高效的优化策略&#xff0c;用于解决许多组合优化问题。虽然它并不适用于所有问题&#xff0c;但在一些特定情况下&#xff0c;贪心算法能够产生近似最优解&#xff0c;而且计算成本较低。在本文中&#xff0c;我们将深入探讨贪…...

一生一芯6——ubuntu rpm软件安装

ubuntu不支持rpm&#xff0c;需要将rpm软件安装包转成deb进行安装 安装alien sudo apt-get install alien格式转换 sudo alien xxx.rpm 在目录下会生成deb的安装包 软件安装 sudo dpkg -i xxx_amd64.deb 安装完成...

Python练习 函数取列表最小数

练习2&#xff1a;构造一个功能函数&#xff0c;可以解决如下问题&#xff1a; 要求如下&#xff1a; 1&#xff0c;任意输入一个列表&#xff0c;函数可以打印出列表中最小的那个数&#xff0c; 例&#xff1a;输入: 23,56,67,4,17,9 最小数是 &#xff1a;4 方法一: #内置函…...

五种重要的 AI 编程语言

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建3D应用场景 简而言之&#xff1a;决定从哪种语言开始可能会令人生畏。 不用担心&#xff01;本文将解释 AI 中使用的最流行编程语言背后的基础知识&#xff0c;并帮助您决定首先学习哪种语言。对于每种语言&#xff0c;我们将…...

【linux】2 make/Makefile和gitee

文章目录 一、Linux项目自动化构建工具-make/Makefile1.1 背景1.2 实例代码1.3 原理1.4 项目清理 二、linux下第一个小程序-进度条2.1 行缓冲区2.2 进度条 三、git以及gitee总结 ヾ(๑╹◡╹)&#xff89;" 人总要为过去的懒惰而付出代价ヾ(๑╹◡╹)&#xff89;" 一…...

db-gpt安装指南(docker版本)

1 下载源码 下载v0.3.5的源码&#xff0c;截止今天&#xff08;20230823&#xff09;建议安装这个“稳定”版本。 2 构建镜像 依照自己硬件环境&#xff0c;看看是否要调整一下启动参数。 bash docker/build_all_images.sh \ --base-image nvidia/cuda:11.7.1-devel-ubuntu…...

「Java」《深度解析Java Stream流的优雅数据处理》

《深度解析Java Stream流的优雅数据处理》 一、引言1.1 背景1.2 Stream流的意义 二、Stream流的基本概念2.1 什么是Stream流2.2 Stream与传统集合的对比 三、创建Stream流3.1 通过集合创建Stream3.2 使用Arrays和Stream.of创建Stream3.3 从文件和网络流创建Stream 四、 中间操作…...

【云驻共创】华为云之手把手教你搭建IoT物联网应用充电桩实时监控大屏

文章目录 前言1.什么是充电桩2.什么是IOT3.什么是端、边、云、应用协同4.什么是Astro轻应用 一、玩转lOT动态实时大屏&#xff08;线下实际操作&#xff09;1.Astro轻应用说明1.1 场景说明1.2 资费说明1.3 整体流程 2.操作步骤2.1 开通设备接入服务2.2 创建产品2.3 注册设备2.4…...

Hadoop分布式计算与资源调度:打开专业江湖的魔幻之门

文章目录 版权声明一 分布式计算概述1.1 分布式计算1.2 分布式&#xff08;数据&#xff09;计算模式1.3 小结 二 MapReduce概述2.1 分布式计算框架 - MapReduce2.2 MapReduce执行原理2.3 小结 三 YARN概述3.1 YARN & MapReduce3.2 资源调度3.3 程序的资源调度3.4 YARN的资…...

为什么叫源表?源表是如何四象限工作的?

为何称呼为源表&#xff1f; “源”为电压源和电流源&#xff0c;“表”为测量表&#xff1b; “源表”即指一种可作为四象限的电压源或电流源提供精确的电压或电流&#xff0c;同时可同步测量电流值或电压值的测量仪表。&#xff08;恒流源时测电压&#xff0c;恒压源时测电…...

云原生周刊:Kubernetes v1.28 正式发布 | 2023.8.21

开源项目推荐 kurt 一个 Kubernetes 插件&#xff0c;可提供 Kubernetes 集群中重启内容的上下文信息。 Kubean Kubean 是一个基于 kubespray 的 Kubernetes 集群生命周期管理工具。 k8sgpt k8sgpt 是一款用简单的英语扫描 Kubernetes 集群、诊断和分流问题的工具。 它将…...

Git基础——基本的 Git本地操作

本文涵盖了你在使用Git的绝大多数时间里会用到的所有基础命令。学完之后&#xff0c;你应该能够配置并初始化Git仓库、开始或停止跟踪文件、暂存或者提交更改。我们也会讲授如何让Git忽略某些文件和文件模式&#xff0c;如何简单快速地撤销错误操作&#xff0c;如何浏览项目版本…...

PythonJS逆向解密——实现翻译软件+语音播报

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用: python 3.8 pycharm 模块使用: requests --> pip install requests execjs --> pip install PyExecJS ttkbootstrap --> pip install ttkbootstrap pyttsx3 --> pip install pyttsx3 第三…...

gPRC与SpringBoot整合教程

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

Hadoop Yarn 配置多队列的容量调度器

文章目录 配置多队列的容量调度器多队列查看 配置多队列的容量调度器 首先&#xff0c;我们进入 Hadoop 的配置文件目录中&#xff08;$HADOOP_HOME/etc/hadoop&#xff09;&#xff1b; 然后通过编辑容量调度器配置文件 capacity-scheduler.xml 来配置多队列的形式。 默认只…...

c语言练习题28:杨氏矩阵

杨氏矩阵 从左到右增加 从上到下增加 思路&#xff1a; 代码&#xff1a; #include<stdio.h> int findNum(int(*arr)[3], int x, int y, int k) {int i 0;int j y - 1;while (i<x&&j>0) {if (arr[i][j] > k) {j--;}else if (arr[i][j] < k) {i;…...

梳理系统学习R语言1-R语言实战-使用ggplot进行高阶绘图

以下为书中代码&#xff0c;会添加一些理解 library("ggplot2") ggplot(datamtcars,aes(xwt,ympg))geom_point()geom_point(pch17,color"blue",size2)geom_smooth(method"lm",color"red",linetype2)labs(title"Automobile Data&…...

测试框架pytest教程(2)-用例依赖库-pytest-dependency

对于 pytest 的用例依赖管理&#xff0c;可以使用 pytest-dependency 插件。该插件提供了更多的依赖管理功能&#xff0c;使你能够更灵活地定义和控制测试用例之间的依赖关系。 Using pytest-dependency — pytest-dependency 0.5.1 documentation 安装 pytest-dependency 插…...