Django利用Channels+websocket开发聊天室

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、什么是Websocket?

2.Python-Django ASGI

3,Django开发聊天室或信息推送


前言

数据库系统课程设计要求,要开发一个B2B的售卖平台,本来开发浅薄的我,粗糙又基础的完成了一些基本的功能,想要开发一个单独的一对一聊天的功能(类似于微信这类),查阅了不少资料,依旧没思路,但是却知晓了服务器推送信息和聊天室的开发,记个笔记。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是Websocket?

1,Websocket的诞生背景:网站为了实现推送技术,用的基本是轮询,轮询是基于浏览器不断对服务器发出HTTP请求,服务器范围最新数据给客户端浏览器,这种模式缺点明显,带宽浪费严重,在这种背景下,HTML5诞生了Websocket协议,能更好的节省服务器资源并实现通讯。

2,WebSocket特点:WebSocket是单个TCP连接上的全双工通信,浏览器和服务器只需要完成一次握手,就可以创建持久性的连接,实现数据的双向传输。

2.Python-Django ASGI

1,WSGI:Python Web Server Gateway Interface,就是Web服务器网关接口,主要是规范了Web服务器和Web应用之间的交互,WSGI将Django分成了三类,服务器,APP,中间件。服务器就是用来监听某端口,APP用来调用某个函数,而中间件则位于两者中间,相当于一道门,起审核承接等作用。但是WSGI始终是为同步世界编写的,无法编写异步对象。因此,ASGI诞生了。

2,ASGI:Async Sever Gateway Interface,说白了,就是相当于WSGI+异步功能,而要调用WebSocket,Django就需要使用ASGI接口。

3,Django开发聊天室或信息推送

第一步:下载Channels模块

pip install channels

第二步:创建Django项目

Django-admin startproject websocket

创建后会看到Django3.0以后自存在asgi.py文件

第三步:创建一个APP应用

python manage.py startapp websocket_demo

第四步:进入settings.py模块,进行配置

首先在INSTALLED_APPS添加channels和websocket_demo

 然后添加再在settings中添加ASGI应用

 第五步:在创建的APP中创建routing.py文件以及进入asgi.py模块进行修改如下:

import osfrom django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from websocket_demo import routingos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'web_socket.settings')application = ProtocolTypeRouter({"http": get_asgi_application(),"websocket": URLRouter(routing.websocket_urlpatterns),})

图中代码很容易理解:将服务器的请求分成了两类,http请求则走默认的asgi APP流程,是Websocket请求则进入URL路由,即websocket_demo创建的routing.py文件

第六步,在websocket_demo的APP中views视图下创建chat.py并且配置routing.py的文件:

from django.urls import re_path
from websocket_demo.views import chatwebsocket_urlpatterns = [re_path(r'chat/(?P<group>\w+)/$', chat.ChatConsumer.as_asgi()),
]

使用正则路径匹配chat/数字/的路径,是则进入chat.py文件中的CharConsumer函数

第七步,在urls.py中配置路由,指向websocket_demo中的chat.py文件

from django.urls import path, include
from websocket_demo.views import chaturlpatterns = [path('index/', chat.chat)
]

第八步,编写chat.py文件的内容如下:

from django.shortcuts import render
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_sync
from datetime import datetimedef chat(request):group_number = request.GET.get('num')return render(request, 'web/index.html', context)class ChatConsumer(WebsocketConsumer):def websocket_connect(self, message):self.accept()group = self.scope['url_route']['kwargs'].get("group")async_to_sync(self.channel_layer.group_add)(group, self.channel_name)def websocket_receive(self, message):group = self.scope['url_route']['kwargs'].get("group")async_to_sync(self.channel_layer.group_send)(group, {"type": "chat", 'message': message})def chat(self, event):text = event['message']['text']self.send(text)def websocket_disconnect(self, message):group = self.scope['url_route']['kwargs'].get("group")async_to_sync(self.channel_layer.group_discard)(group, self.channel_name)print('客户端断开连接了')raise StopConsumer()

首先第一个函数的意思是,进入index页面后会先进入chat函数,获取URL中请求的参数num,渲染到index.html页面,然后index.html页面使用javascript发起websocket请求,发起websocket请求后,ASGI服务器通过"websocket": URLRouter(routing.websocket_urlpatterns)路由访问routing文件,routing文件指向了ChatConsumer(WebsocketConsumer)类。

第二个函数ChatConsumer(WebsocketConsumer)类对websocket请求进行了处理,接收websocket的请求后获取组号即num的值,然后接收websocket发送的信息后调用chat函数将收到的信息同等的发送回去,websocket_disconnet则是客户端断开请求后触发的函数。

前端index.html的文件如下:

  reset.min.css文件:

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}

style.css文件:

        

*, *:before, *:after {box-sizing: border-box;
}:root {--white: #fff;--black: #000;--bg: #f8f8f8;--grey: #999;--dark: #1a1a1a;--light: #e6e6e6;--wrapper: 1000px;--blue: #00b0ff;
}body {background-color: var(--bg);-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-rendering: optimizeLegibility;font-family: 'Source Sans Pro', sans-serif;font-weight: 400;background-image: url("../img/image.jpg");background-size: cover;background-repeat: none;
}.wrapper {position: relative;left: 50%;width: var(--wrapper);height: 800px;-webkit-transform: translate(-50%, 0);transform: translate(-50%, 0);
}.container {position: relative;top: 50%;left: 50%;width: 80%;height: 75%;background-color: var(--white);-webkit-transform: translate(-50%, -50%);transform: translate(-50%, -50%);
}
.container .left {float: left;width: 37.6%;height: 100%;border: 1px solid var(--light);background-color: var(--white);
}
.container .left .top {position: relative;width: 100%;height: 96px;padding: 29px;
}
.container .left .top:after {position: absolute;bottom: 0;left: 50%;display: block;width: 80%;height: 1px;content: '';background-color: var(--light);-webkit-transform: translate(-50%, 0);transform: translate(-50%, 0);
}
.container .left input {float: left;width: 188px;height: 42px;padding: 0 15px;border: 1px solid var(--light);background-color: #eceff1;border-radius: 21px;font-family: 'Source Sans Pro', sans-serif;font-weight: 400;
}
.container .left input:focus {outline: none;
}
.container .left a.search {display: block;float: left;width: 42px;height: 42px;margin-left: 10px;border: 1px solid var(--light);background-color: var(--blue);background-image: url("../img//name-type.png");background-repeat: no-repeat;background-position: top 12px left 14px;border-radius: 50%;
}
.container .left .people {margin-left: -1px;border-right: 1px solid var(--light);border-left: 1px solid var(--light);width: calc(100% + 2px);
}
.container .left .people .person {position: relative;width: 100%;padding: 12px 10% 16px;cursor: pointer;background-color: var(--white);
}
.container .left .people .person:after {position: absolute;bottom: 0;left: 50%;display: block;width: 80%;height: 1px;content: '';background-color: var(--light);-webkit-transform: translate(-50%, 0);transform: translate(-50%, 0);
}
.container .left .people .person img {float: left;width: 40px;height: 40px;margin-right: 12px;border-radius: 50%;
}
.container .left .people .person .name {font-size: 14px;line-height: 22px;color: var(--dark);font-family: 'Source Sans Pro', sans-serif;font-weight: 600;
}
.container .left .people .person .time {font-size: 14px;position: absolute;top: 16px;right: 10%;padding: 0 0 5px 5px;color: var(--grey);background-color: var(--white);
}
.container .left .people .person .preview {font-size: 14px;display: inline-block;overflow: hidden !important;width: 70%;white-space: nowrap;text-overflow: ellipsis;color: var(--grey);
}
.container .left .people .person.active, .container .left .people .person:hover {margin-top: -1px;margin-left: -1px;padding-top: 13px;border: 0;background-color: var(--blue);width: calc(100% + 2px);padding-left: calc(10% + 1px);
}
.container .left .people .person.active span, .container .left .people .person:hover span {color: var(--white);background: transparent;
}
.container .left .people .person.active:after, .container .left .people .person:hover:after {display: none;
}
.container .right {position: relative;float: left;width: 62.4%;height: 100%;
}
.container .right .top {width: 100%;height: 47px;padding: 15px 29px;background-color: #eceff1;
}
.container .right .top span {font-size: 15px;color: var(--grey);
}
.container .right .top span .name {color: var(--dark);font-family: 'Source Sans Pro', sans-serif;font-weight: 600;
}
.container .right .chat {position: relative;display: none;overflow: hidden;padding: 0 35px 92px;border-width: 1px 1px 1px 0;border-style: solid;border-color: var(--light);height: calc(100% - 48px);justify-content: flex-end;flex-direction: column;
}
.container .right .chat.active-chat {display: block;display: flex;
}
.container .right .chat.active-chat .bubble {transition-timing-function: cubic-bezier(0.4, -0.04, 1, 1);
}
.container .right .chat.active-chat .bubble:nth-of-type(1) {-webkit-animation-duration: 0.15s;animation-duration: 0.15s;
}
.container .right .chat.active-chat .bubble:nth-of-type(2) {-webkit-animation-duration: 0.3s;animation-duration: 0.3s;
}
.container .right .chat.active-chat .bubble:nth-of-type(3) {-webkit-animation-duration: 0.45s;animation-duration: 0.45s;
}
.container .right .chat.active-chat .bubble:nth-of-type(4) {-webkit-animation-duration: 0.6s;animation-duration: 0.6s;
}
.container .right .chat.active-chat .bubble:nth-of-type(5) {-webkit-animation-duration: 0.75s;animation-duration: 0.75s;
}
.container .right .chat.active-chat .bubble:nth-of-type(6) {-webkit-animation-duration: 0.9s;animation-duration: 0.9s;
}
.container .right .chat.active-chat .bubble:nth-of-type(7) {-webkit-animation-duration: 1.05s;animation-duration: 1.05s;
}
.container .right .chat.active-chat .bubble:nth-of-type(8) {-webkit-animation-duration: 1.2s;animation-duration: 1.2s;
}
.container .right .chat.active-chat .bubble:nth-of-type(9) {-webkit-animation-duration: 1.35s;animation-duration: 1.35s;
}
.container .right .chat.active-chat .bubble:nth-of-type(10) {-webkit-animation-duration: 1.5s;animation-duration: 1.5s;
}
.container .right .write {position: absolute;bottom: 29px;left: 30px;height: 42px;padding-left: 8px;border: 1px solid var(--light);background-color: #eceff1;width: calc(100% - 58px);border-radius: 5px;
}
.container .right .write input {font-size: 16px;float: left;width: 347px;height: 40px;padding: 0 10px;color: var(--dark);border: 0;outline: none;background-color: #eceff1;font-family: 'Source Sans Pro', sans-serif;font-weight: 400;
}
.container .right .write .write-link.attach:before {display: inline-block;float: left;width: 20px;height: 42px;content: '';background-image: url("../img/attachment.png");background-repeat: no-repeat;background-position: center;
}
.container .right .write .write-link.smiley:before {display: inline-block;float: left;width: 20px;height: 42px;content: '';background-image: url("../img/smiley.png");background-repeat: no-repeat;background-position: center;
}
.container .right .write .write-link.send:before {display: inline-block;float: left;width: 20px;height: 42px;margin-left: 11px;content: '';background-image: url("../img/send.png");background-repeat: no-repeat;background-position: center;
}
.container .right .bubble {font-size: 16px;position: relative;display: inline-block;clear: both;margin-bottom: 8px;padding: 13px 14px;vertical-align: top;border-radius: 5px;
}
.container .right .bubble:before {position: absolute;top: 19px;display: block;width: 8px;height: 6px;content: '\00a0';-webkit-transform: rotate(29deg) skew(-35deg);transform: rotate(29deg) skew(-35deg);
}
.container .right .bubble.you {float: left;color: var(--white);background-color: var(--blue);align-self: flex-start;-webkit-animation-name: slideFromLeft;animation-name: slideFromLeft;
}
.container .right .bubble.you:before {left: -3px;background-color: var(--blue);
}
.container .right .bubble.me {float: right;color: var(--dark);background-color: #eceff1;align-self: flex-end;-webkit-animation-name: slideFromRight;animation-name: slideFromRight;
}
.container .right .bubble.me:before {right: -3px;background-color: #eceff1;
}
.container .right .conversation-start {position: relative;width: 100%;margin-bottom: 27px;text-align: center;
}
.container .right .conversation-start span {font-size: 14px;display: inline-block;color: var(--grey);
}
.container .right .conversation-start span:before, .container .right .conversation-start span:after {position: absolute;top: 10px;display: inline-block;width: 30%;height: 1px;content: '';background-color: var(--light);
}
.container .right .conversation-start span:before {left: 0;
}
.container .right .conversation-start span:after {right: 0;
}@keyframes slideFromLeft {0% {margin-left: -200px;opacity: 0;}100% {margin-left: 0;opacity: 1;}
}
@-webkit-keyframes slideFromLeft {0% {margin-left: -200px;opacity: 0;}100% {margin-left: 0;opacity: 1;}
}
@keyframes slideFromRight {0% {margin-right: -200px;opacity: 0;}100% {margin-right: 0;opacity: 1;}
}
@-webkit-keyframes slideFromRight {0% {margin-right: -200px;opacity: 0;}100% {margin-right: 0;opacity: 1;}
}

index.js文件:

                

document.querySelector('.chat[data-chat=person2]').classList.add('active-chat');
document.querySelector('.person[data-chat=person2]').classList.add('active');var friends = {list: document.querySelector('ul.people'),all: document.querySelectorAll('.left .person'),name: '' },chat = {container: document.querySelector('.container .right'),current: null,person: null,name: document.querySelector('.container .right .top .name') };friends.all.forEach(function (f) {f.addEventListener('mousedown', function () {f.classList.contains('active') || setAciveChat(f);});
});function setAciveChat(f) {friends.list.querySelector('.active').classList.remove('active');f.classList.add('active');chat.current = chat.container.querySelector('.active-chat');chat.person = f.getAttribute('data-chat');chat.current.classList.remove('active-chat');chat.container.querySelector('[data-chat="' + chat.person + '"]').classList.add('active-chat');friends.name = f.querySelector('.name').innerText;chat.name.innerHTML = friends.name;
}

index.html文件:

{% load static from static %}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>聊天窗口界面</title><link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600" rel="stylesheet">
<link rel="stylesheet" href="{% static 'web/chat/css/reset.min.css' %}">
<link rel="stylesheet" href="{% static 'web/chat/css/style.css' %}"></head>
<body><div class="wrapper"><div class="container"><div class="left"><div class="top"><input type="text" placeholder="Search" /><a href="javascript:;" class="search"></a></div><ul class="people"><li class="person" data-chat="person2"><img src="/static/myadmin/dist/img/user2-160x160.jpg" alt="" /><span class="name">{{admin_name}}</span><span class="preview">I was wondering...</span></li></ul></div><div class="right"><div class="top"><span>To: <span class="name">{{admin_name}}</span></span></div><div class="chat" data-chat="person2" id="chat-send" ><div class="conversation-start"><span>{{time}}</span></div></div><div class="write"><a href="javascript:;" class="write-link attach"></a><input type="text" id="text"/><a href="javascript:;" class="write-link smiley"></a><a onclick="sendMessage()"  class="write-link send"></a></div></div></div>
</div><script  src="{% static 'web/chat/js/index.js' %}"></script>
<script type="text/javascript">var socket=new WebSocket("ws://127.0.0.1:8000/chat/{{group_number}}/");socket.onopen = function(event){var tag=document.getElementById("chat-send");var d=document.createElement("div");d.className="bubble you";d.innerHTML ="连接成功";tag.appendChild(d);}function sendMessage(){let text=document.getElementById("text");var tag=document.getElementById("chat-send");var d=document.createElement("div");d.className="bubble me";d.innerHTML =text.value;tag.appendChild(d);socket.send(text.value);text.value=" ";}socket.onclose = function(){var tag=document.getElementById("chat-send");var d=document.createElement("div");d.className="bubble you";d.innerHTML ="服务器主动断开连接";tag.appendChild(d);
}
socket.onmessage=function(event){var tag=document.getElementById("chat-send");var d=document.createElement("div");d.className="bubble you";d.innerHTML =event.data;tag.appendChild(d);}
</script>
<div style="text-align:center;margin:1px 0; font:normal 14px/24px 'MicroSoft YaHei';">
</div>
</body>
</html>

主要看javascript使用的函数,首先进行Websocket请ws://127.0.0.1:8000/chat/{{group_number}}/,然后分别的通过websocket发送信息,接受信息。

第九步,启动manage.py文件,同时打开两个页面观看效果:

        

可以看到,某个用户发送的信息,将会被服务器发送到同一聊天室的所有客户端,实现了信息推送的功能。 

但是要实现一对一聊天的功能,目前实现是没有思路,有大神看到烦请指点指点。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《3D打印:正在到来的工业革命(第2版)》——2.2节材料挤出技术

本节书摘来自异步社区《3D打印&#xff1a;正在到来的工业革命&#xff08;第2版&#xff09;》一书中的第2章&#xff0c;第2.2节材料挤出技术&#xff0c;作者 【英】Christopher Barnatt&#xff08;克里斯多夫&#xff09;&#xff0c;更多章节内容可以访问云栖社区“异步社…

【每日新闻】9家虚拟运营商与中国移动签约首批牌照有望近期下发 | 澳大利亚正考虑禁止采购华为5G设备...

点击关注中国软件网 最新鲜的企业级干货聚集地 趋势洞察 坚持是种信念&#xff0c;努力是种精神&#xff01; 2018中国软件生态大会 趋势洞察 工信部王卫明&#xff1a;人工智能正在成为推进供给侧结构性改革的新动能 工业和信息化部科技司副司长王卫明表示&#xff1a;人工智…

大咖云集,EI稳定检索,第14届机器学习与计算国际会议(ICMLC 2022)

14th - ICMLC 2022 第14届机器学习与计算国际会议 2月18-21日 | 中国广州 关于我们 机器学习是人工智能及模式识别领域的共同研究热点&#xff0c;其理论和方法已被广泛应用于解决工程应用和科学领域的复杂问题。为了给机器学习与计算研究领域的专家学者提供一个交流相关领域…

艾伦·麦席森·图灵

艾伦麦席森图灵 艾伦麦席森图灵&#xff08;英语&#xff1a;Alan Mathison Turing&#xff0c;1912年6月23日—1954年6月7日&#xff09;&#xff0c;英国数学家、逻辑学家&#xff0c;被称为计算机科学之父&#xff0c;人工智能之父。1931年图灵进入剑桥大学国王学院&#x…

人机交互-1-人机交互概述

Lec1-人机交互概述 1. 相关术语 Man-Machine Interaction (MMI) / Human-Machine Interaction (HMI) “Man-Machine Interaction” politically incorrectStudy of the ways how humans use machines Man-Computer Interaction (MCI) / Human-Computer Interaction (HCI)Comp…

学习A-level课程能申请哪些国家

在许多学生和学生家长的感觉中A-level课程内容是外国的考試&#xff0c;只可以申请办理英国的大学。实际上这一看法是不规范的&#xff0c;A-level是一个十分全球化的课程内容&#xff0c;被全世界许多我国的顶级高校接收和认同。 要想考A-Level,先明确A-Level适不适宜自身。A-…

世界环境日 | 始祖数字化可持续发展峰会就在6.5!

2022年世界环境日始祖数字化可持续发展峰会将于6月5日北京时间14:00全球线上举行&#xff0c;将邀请来自工业、数字化科技、环境建筑、时尚等领域的嘉宾共同探讨相关议题&#xff0c;推动数字化生态互联&#xff0c;助力可持续发展。 我们诚挚地邀请大家和我们共聚在下午的峰会…

【Energy Reports期刊发表】2022年能源与环境工程国际会议(CFEEE 2022)

【Energy Reports】 【广西大学主办】 2022年能源与环境工程国际会议&#xff08;CFEEE 2022&#xff09; 重要信息 会议网址&#xff1a;www.cfeee.org 会议时间&#xff1a;2022年12月16-18日 召开地点&#xff1a;广西-北海 截稿时间&#xff1a;2022年11月10日 录用…

Neurology:肚子越大,脑子越小-肚子胖与大脑萎缩相关

医林研究院-让医学更简单&#xff01; 肥胖&#xff0c;既是一种特征&#xff0c;也是一种疾病&#xff0c;肥胖是世界卫生组织确定的十大慢性疾病之一&#xff0c;肥胖者更易患代谢性疾病和心脑血管疾病和慢性肾脏病等。 全世界有近40%的人超重&#xff0c;13%的人肥胖&#x…

交中IB课程中心2022届早申阶段录取成果汇总

2022届早申阶段录取成果汇总截至2022年2月19日 最是一年春好处&#xff0c;交中IB录取的佳音随着春风次第而来。在刚刚过去的海外大学早申请阶段&#xff0c;交中IB学子凭借超群实力&#xff0c;斩获了多所世界顶尖名校的录取。正是对知识的渴求、对梦想的执着、对未来的坚定&…

【会议分享】2022年智能车国际会议(ICoIV 2022)

2022年智能车国际会议(ICoIV 2022) 重要信息 会议网址&#xff1a;www.icoiv.org 会议时间&#xff1a;2022年10月14-16日 召开地点&#xff1a;中国成都 截稿时间&#xff1a;2022年8月30日 录用通知&#xff1a;投稿后2周内 收录检索&#xff1a;EI,Scopus 会议简介 ★…

CSP-J第一轮常考知识点

一、OSI模型 (1)中文名 ​ 开放式通信系统互联参考模型 (2)层次 ​ 物理层->数据链路层->网络层->传输层->会话层->表示层->应用层 (3)介绍 ​ 物理层: 将数据转换为可通过物理介质传送的电子信号 相当于邮局中的搬运工人。 ​ 数据链路层: 决定访问网…

【Energy Reports期刊发表】 2022年能源与环境工程国际会议(CFEEE 2022)

【Energy Reports期刊发表】 2022年能源与环境工程国际会议&#xff08;CFEEE 2022&#xff09; 重要信息 会议网址&#xff1a;www.cfeee.org 会议时间&#xff1a;2022年12月16-18日 召开地点&#xff1a;广西-北海 截稿时间&#xff1a;2022年11月1日 录用通知&#x…

世界上最健康的程序员作息表「值得一看」

昨晚看了一篇“传说中”的“世界上最健康的作息时间表”&#xff0c;开始纠结自己还要不要5点半起床。 都说程序员这一行&#xff0c;猝死概率极高&#xff0c;究其原因还是加班太狠、作息不规律、缺乏运动.... 今天和大家分享一下这篇文章&#xff0c;还是非常值得参考的&…

周五了,世界上ZUI健康的工程师作息表!

关注、星标公众号&#xff0c;直达精彩内容 链接&#xff1a;https://sleepyocean.github.io/pages/55d148/ 996已经为很多行业的常态&#xff0c;近些年来&#xff0c;经常会看到新闻报道年轻人猝死的事情&#xff0c;究其原因还是很难有很好的作息规律。 今天给大家带来“传说…

世界上最健康的程序员作息表!

都说程序员这一行&#xff0c;猝死概率极高&#xff0c;究其原因还是很难有很好的作息规律。 今天给大家带来“传说中”的“世界上最健康的作息时间表”&#xff08;仅供参考&#xff09;&#xff0c;随时提醒自己吧&#xff0c;毕竟身体可是自己的哦。 原文链接&#xff1a;ht…

超高频RFID无人机仓库库存管理

1.项目背景 Intelligent Energy做为行业的供应链库存解决方案提供商&#xff0c;签署了为无人机提供燃料电池系统的交易。 拉夫堡 英国 3月23日Intelligent Energy跟PINC公司做了一个交易&#xff0c;为它们提供无人机的冷却燃料电池系统&#xff0c;这是Intelligent Energy初…

卡迪夫大学计算机硕士专业怎么样,卡迪夫大学计算机硕士专业

卡迪夫大学计算机硕士课程的学生会得到一个第1手的了解软件解决跨学科问题的机会,以及计算系统可以实现什么。学生将学习、实践和演示软件工程师所需的专业技能,单独或作为一个团队的一部分开发一个软件的方案。 卡迪夫大学计算机硕士专业课程 核心课程 Web Application Develo…

机器学习32道选择题

1. 丰巢柜中有A、B、C、D、E、F六个人的快递&#xff0c;每个人各有两个快递。现在随机取出5个快递&#xff0c;那么5个快递中至少有2个快递属于同一个人的概率是多少&#xff1f;&#xff08;0.757575757575758&#xff09; 2. 假设有三个人同时参加这场笔试&#xff0c;假设满…

这13本豆瓣高分算法书,必读!

“算法到底应该怎么学&#xff1f;” “程序员必须掌握哪些算法&#xff1f;” “大公司笔试、面试都有哪些经典算法题目&#xff1f;” 这一系列在知乎上受到关注众多的算法提问&#xff0c;一方面反映出大家学习算法的热情非凡&#xff0c;另一方面也看得出大家苦于没有系统的…