Docker-compose 八步部署Django + Uwsgi + Nginx + MySQL + Redis升级篇

Django在生产环境的部署还是比较复杂的, 令很多新手望而生畏, 幸运的是使用Docker容器化技术可以大大简化我们Django在生产环境的部署并提升我们应用的可移植性。Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux机器上。

 

前文我们介绍了如何使用docker-compose八步部署Django + Uwsgi + Nginx + MySQL + Redis (多容器组合),但该教程里有很多值得改进的地方,比如:

 

  • MySQL的数据库名,用户名和密码明文写在docker-compose.yml里,实际是可以由.env文件创建的;
  • MySQL使用的版本比较老,为5.7。如果你使用MySQL 8,那么相关配置文件需要做较大修改;
  • Nginx配置文件没有挂载,每次修改需要手动将配置文件从宿主机复制一份到容器内;
  • 容器间通信使用了–links选项,这个docker已不推荐使用。本例将使用networks实现容器间通信;
  • 原文每次web容器服务启动后,需要手动进入容器内部进行数据迁移并启动uwsgi服务;
  • 原文教程排错机制讲的较少,本文将仔细讲下如何在Docker部署时排错。

本文将是docker-compose部署Django + Uwsgi + Nginx + MySQL + Redis教程的升级版,将完善前面教程不足的地方,很多配置文件将会有非常大的参考价值,建议先收藏再阅读。

 

注意:本文侧重于Docker技术在部署Django时的实际应用,而不是Docker基础教程。对Docker命令不熟悉的读者们建议先学习下Docker及Docker-compose基础命令。

Docker-compose 八步部署Django + Uwsgi + Nginx + MySQL + Redis升级篇

什么是docker-compose及docker-compose工具的安装

Docker-compose是一个用来定义和运行复杂应用的 Docker 工具。使用 docker-compose 后不再需要使用 shell 脚本来逐一创建和启动容器,还可以通过 docker-compose.yml 文件构建和管理复杂多容器组合。

Docker-compose的下载和安装很简单,网上有很多教程,我就不再详述了。这里只记录下ubuntu系统下docker-compose的安装过程。

 # Step 1: 以ubuntu为例,下载docker-compose $ sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose # Step 2: 给予docker-compose可执行权限 $ sudo chmod +x /usr/local/bin/docker-compose # Step 3: 查看docker-compose版本 $ docker-compose --version

注意:安装docker-compose前必需先安装好docker。

Django + Uwsgi + Nginx + MySQL + Redis组合容器示意图

本例中我们将使用docker-compose编排并启动4个容器,这更接近于实际生成环境下的部署。

  1. Django + Uwsgi容器:核心应用程序,处理动态请求

  2. MySQL 容器:数据库服务

  3. Redis 容器:缓存服务

  4. Nginx容器:反向代理服务并处理静态资源请求

这四个容器的依赖关系是:Django+Uwsgi 容器依赖 Redis 容器和 MySQL 容器,Nginx 容器依赖Django+Uwsgi容器。为了方便容器间的相互访问和通信,我们使用docker-compose时可以给每个容器取个别名,这样访问容器时就可以直接使用别名访问,而不使用Docker临时给容器分配的IP了。

这四个容器的别名及通信端口如下图所示:

Docker-compose 八步部署Django + Uwsgi + Nginx + MySQL + Redis升级篇

Docker-compose部署Django项目布局树形图

我们新建了一个compose文件夹,专门存放用于构建其它容器镜像的Dockerfile及配置文件。compose文件夹与django项目的根目录myproject同级。这样做的好处是不同的django项目可以共享compose文件夹。

myproject_docker # 项目根目录├── compose # 存放各项容器服务的Dockerfile和配置文件│   ├── mysql│   │   ├── conf│   │   │   └── my.cnf # MySQL配置文件│   │   └── init│   │       └── init.sql # MySQL启动脚本│   ├── nginx│   │   ├── Dockerfile # 构建Nginx镜像所的Dockerfile│   │   ├── log # 挂载保存nginx容器内日志log目录│   │   ├── nginx.conf # Nginx配置文件│   │   └── ssl # 如果需要配置https需要用到│   ├── redis│   │   └── redis.conf # redis配置文件│   └── uwsgi # 挂载保存django+uwsgi容器内uwsgi日志├── docker-compose.yml # 核心编排文件└── myproject # 常规Django项目目录    ├── Dockerfile # 构建Django+Uwsgi镜像的Dockerfile    ├── apps # 存放Django项目的各个apps    ├── manage.py    ├── myproject # Django项目配置文件    │   ├── asgi.py    │   ├── __init__.py    │   ├── settings.py    │   ├── urls.py    │   └── wsgi.py    ├── pip.conf # 非必需。pypi源设置成国内,加速pip安装    ├── requirements.txt # Django项目依赖文件    ├── .env # 环境变量文件    ├── start.sh # 启动Django+Uwsgi容器后要执行的脚本    ├── media # 用户上传的媒体资源,如果没有需手动创建    ├── static #搜集项目的静态文件夹,如果没有需手动创建    └── uwsgi.ini # uwsgi配置文件

下面我们开始正式部署。

第一步:编写docker-compose.yml文件

修改过的docker-compose.yml的核心内容如下。我们定义了4个数据卷,用于挂载各个容器内动态生成的数据,比如MySQL的存储数据,redis生成的快照、django+uwsgi容器中收集的静态文件以及用户上传的媒体资源。这样即使删除容器,容器内产生的数据也不会丢失。

我们还定义了3个网络,分别为nginx_network(用于nginx和web容器间的通信),db_network(用于db和web容器间的通信)和redis_network(用于redis和web容器间的通信)。

整个编排里包含4项容器服务,别名分别为redis, db, nginxweb,接下来我们将依次看看各个容器的Dockerfile和配置文件。

version: "3"
volumes: # 自定义数据卷  db_vol: #定义数据卷同步存放容器内mysql数据  redis_vol: #定义数据卷同步存放redis数据  media_vol: #定义数据卷同步存放web项目用户上传到media文件夹的数据  static_vol: #定义数据卷同步存放web项目static文件夹的数据
networks: # 自定义网络(默认桥接), 不使用links通信  nginx_network:    driver: bridge  db_network:    driver: bridge  redis_network:     driver: bridge
services:  redis:    image: redis:latest    command: redis-server /etc/redis/redis.conf # 容器启动后启动redis服务器    networks:      - redis_network    volumes:      - redis_vol:/data # 通过挂载给redis数据备份      - ./compose/redis/redis.conf:/etc/redis/redis.conf # 挂载redis配置文件    ports:      - "6379:6379"    restart: always # always表容器运行发生错误时一直重启
  db:    image: mysql    env_file:        - ./myproject/.env # 使用了环境变量文件    networks:        - db_network    volumes:      - db_vol:/var/lib/mysql:rw # 挂载数据库数据, 可读可写      - ./compose/mysql/conf/my.cnf:/etc/mysql/my.cnf # 挂载配置文件      - ./compose/mysql/init:/docker-entrypoint-initdb.d/ # 挂载数据初始化sql脚本    ports:      - "3306:3306" # 与配置文件保持一致    restart: always
  web:    build: ./myproject    expose:      - "8000"    volumes:      - ./myproject:/var/www/html/myproject # 挂载项目代码      - static_vol:/var/www/html/myproject/static # 以数据卷挂载容器内static文件      - media_vol:/var/www/html/myproject/media # 以数据卷挂载容器内用户上传媒体文件      - ./compose/uwsgi:/tmp # 挂载uwsgi日志    networks:      - nginx_network      - db_network        - redis_network     depends_on:      - db      - redis    restart: always    tty: true    stdin_open: true
  nginx:    build: ./compose/nginx    ports:      - "80:80"      - "443:443"    expose:      - "80"    volumes:      - ./compose/nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf # 挂载nginx配置文件      - ./compose/nginx/ssl:/usr/share/nginx/ssl # 挂载ssl证书目录      - ./compose/nginx/log:/var/log/nginx # 挂载日志      - static_vol:/usr/share/nginx/html/static # 挂载静态文件      - media_vol:/usr/share/nginx/html/media # 挂载用户上传媒体文件    networks:      - nginx_network    depends_on:      - web    restart: always

第二步:编写Web (Django+Uwsgi)镜像和容器所需文件

构建Web镜像(Django+Uwsgi)的所使用的Dockerfile如下所示:

# 建立 python 3.9环境FROM python:3.9
# 安装netcatRUN apt-get update && apt install -y netcat
# 镜像作者大江狗MAINTAINER DJG
# 设置 python 环境变量ENV PYTHONDONTWRITEBYTECODE 1ENV PYTHONUNBUFFERED 1
# 可选:设置镜像源为国内COPY pip.conf /root/.pip/pip.conf
# 容器内创建 myproject 文件夹ENV APP_HOME=/var/www/html/myprojectRUN mkdir -p $APP_HOMEWORKDIR $APP_HOME
# 将当前目录加入到工作目录中(. 表示当前目录)ADD . $APP_HOME
# 更新pip版本RUN /usr/local/bin/python -m pip install --upgrade pip
# 安装项目依赖RUN pip install -r requirements/production.txt
# 移除r in windowsRUN sed -i 's/r//' ./start.sh
# 给start.sh可执行权限RUN chmod +x ./start.sh
# 数据迁移,并使用uwsgi启动服务ENTRYPOINT /bin/bash ./start.sh

本Django项目所依赖的requirements.txt内容如下所示:

# djangodjango==3.2# uwsgiuwsgi==2.0.18# mysqlmysqlclient==1.4.6# redisdjango-redis==4.12.1redis==3.5.3# for imagesPillow==8.2.0 

start.sh脚本文件内容如下所示。最重要的是最后一句,使用uwsgi.ini配置文件启动Django服务。

#!/bin/bash# 从第一行到最后一行分别表示:# 1. 等待MySQL服务启动后再进行数据迁移。nc即netcat缩写# 2. 收集静态文件到根目录static文件夹,# 3. 生成数据库可执行文件,# 4. 根据数据库可执行文件来修改数据库# 5. 用 uwsgi启动 django 服务# 6. tail空命令防止web容器执行脚本后退出while ! nc -z db 3306 ; do    echo "Waiting for the MySQL Server"    sleep 3done
python manage.py collectstatic --noinput&&python manage.py makemigrations&&python manage.py migrate&&uwsgi --ini /var/www/html/myproject/uwsgi.ini&&tail -f /dev/null
exec "$@"

uwsgi.ini配置文件如下所示: 

[uwsgi]
project=myprojectuid=www-datagid=www-database=/var/www/html
chdir=%(base)/%(project)module=%(project).wsgi:applicationmaster=Trueprocesses=2
socket=0.0.0.0:8000chown-socket=%(uid):www-datachmod-socket=664
vacuum=Truemax-requests=5000
pidfile=/tmp/%(project)-master.piddaemonize=/tmp/%(project)-uwsgi.log
#设置一个请求的超时时间(秒),如果一个请求超过了这个时间,则请求被丢弃harakiri = 60post buffering = 8192buffer-size= 65535#当一个请求被harakiri杀掉会,会输出一条日志harakiri-verbose = true
#开启内存使用情况报告memory-report = true
#设置平滑的重启(直到处理完接收到的请求)的长等待时间(秒)reload-mercy = 10
#设置工作进程使用虚拟内存超过N MB就回收重启reload-on-as= 1024

第三步:编写Nginx镜像和容器所需文件

构建Nginx镜像所使用的Dockerfile如下所示:

# nginx镜像compose/nginx/Dockerfile
FROM nginx:latest
# 删除原有配置文件,创建静态资源文件夹和ssl证书保存文件夹RUN rm /etc/nginx/conf.d/default.conf && mkdir -p /usr/share/nginx/html/static && mkdir -p /usr/share/nginx/html/media && mkdir -p /usr/share/nginx/ssl
# 设置Media文件夹用户和用户组为Linux默认www-data, 并给予可读和可执行权限,# 否则用户上传的图片无法正确显示。RUN chown -R www-data:www-data /usr/share/nginx/html/media && chmod -R 775 /usr/share/nginx/html/media
# 添加配置文件ADD ./nginx.conf /etc/nginx/conf.d/
# 关闭守护模式CMD ["nginx", "-g", "daemon off;"]

Nginx的配置文件如下所示

# nginx配置文件# compose/nginx/nginx.conf
upstream django {    ip_hash;    server web:8000; # Docker-compose web服务端口}
# 配置http请求,80端口server {    listen 80; # 监听80端口    server_name 127.0.0.1; # 可以是nginx容器所在ip地址或127.0.0.1,不能写宿主机外网ip地址
    charset utf-8;    client_max_body_size 10M; # 限制用户上传文件大小
    access_log /var/log/nginx/access.log main;    error_log /var/log/nginx/error.log warn;
    location /static {        alias /usr/share/nginx/html/static; # 静态资源路径    }
    location /media {        alias /usr/share/nginx/html/media; # 媒体资源,用户上传文件路径    }
    location / {        include /etc/nginx/uwsgi_params;        uwsgi_pass django;        uwsgi_read_timeout 600;        uwsgi_connect_timeout 600;        uwsgi_send_timeout 600;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_redirect off;        proxy_set_header X-Real-IP  $remote_addr;       # proxy_pass http://django;  # 使用uwsgi通信,而不是http,所以不使用proxy_pass。    }}

第四步:编写Db (MySQL)容器配置文件

启动MySQL容器我们直接使用官方镜像即可,不过我们需要给MySQL增加配置文件。

# compose/mysql/conf/my.cnf[mysqld]user=mysqldefault-storage-engine=INNODBcharacter-set-server=utf8secure-file-priv=NULL # mysql 8 新增这行配置default-authentication-plugin=mysql_native_password  # mysql 8 新增这行配置
port            = 3306 # 端口与docker-compose里映射端口保持一致#bind-address= localhost #一定要注释掉,mysql所在容器和django所在容器不同IP
basedir         = /usrdatadir         = /var/lib/mysqltmpdir          = /tmppid-file        = /var/run/mysqld/mysqld.pidsocket          = /var/run/mysqld/mysqld.sockskip-name-resolve  # 这个参数是禁止域名解析的,远程访问推荐开启skip_name_resolve。
[client]port = 3306default-character-set=utf8
[mysql]no-auto-rehashdefault-character-set=utf8

我们还需设置MySQL服务启动时需要执行的脚本命令, 注意这里的用户名和password必需和docker-compose.yml里与MySQL相关的环境变量(.env)保持一致。

# compose/mysql/init/init.sqlAlter user 'dbuser'@'%' IDENTIFIED WITH mysql_native_password BY 'password';GRANT ALL PRIVILEGES ON myproject.* TO 'dbuser'@'%';FLUSH PRIVILEGES;

.env文件内容如下所示:

MYSQL_ROOT_PASSWORD=123456MYSQL_USER=dbuserMYSQL_DATABASE=myprojectMYSQL_PASSWORD=password

第五步:编写Redis 容器配置文件

启动redis容器我们直接使用官方镜像即可,不过我们需要给redis增加配置文件。大部分情况下采用默认配置就好了,这里我们只做出了如下几条核心改动:

 # compose/redis/redis.conf # Redis 5配置文件下载地址 # https://raw.githubusercontent.com/antirez/redis/5.0/redis.conf
 # 请注释掉下面一行,变成#bind 127.0.0.1,这样其它机器或容器也可访问 bind 127.0.0.1
 # 取消下行注释,给redis设置登录密码。这个密码django settings.py会用到。 requirepass yourpassword

第六步:修改Django项目settings.py

在你准备好docker-compose.yml并编排好各容器的Dockerfile及配置文件后,请先不要急于使用Docker-compose命令构建镜像和启动容器。这时还有一件非常重要的事情要做,那就是修改Django的settings.py, 提供mysql和redis服务的配置信息。最重要的几项配置如下所示:

 # 生产环境设置 Debug = False Debug = False
 # 设置ALLOWED HOSTS ALLOWED_HOSTS = ['your_server_IP', 'your_domain_name']
 # 设置STATIC ROOT 和 STATIC URL STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATIC_URL = "/static/"
 # 设置MEDIA ROOT 和 MEDIA URL MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = "/media/"
 # 设置数据库。这里用户名和密码必需和docker-compose.yml里mysql环境变量保持一致 DATABASES = {     'default': {         'ENGINE': 'django.db.backends.mysql',         'NAME': 'myproject', # 数据库名         'USER':'dbuser', # 你设置的用户名 - 非root用户         'PASSWORD':'password', # # 换成你自己密码         'HOST': 'db', # 注意:这里使用的是db别名,docker会自动解析成ip         'PORT':'3306', # 端口     } }
 # 设置redis缓存。这里密码为redis.conf里设置的密码 CACHES = {     "default": {         "BACKEND": "django_redis.cache.RedisCache",         "LOCATION": "redis://redis:6379/1", #这里直接使用redis别名作为host ip地址         "OPTIONS": {             "CLIENT_CLASS": "django_redis.client.DefaultClient",             "PASSWORD": "yourpassword", # 换成你自己密码         },     } }

第七步:使用docker-compose 构建镜像并启动容器组服务

现在我们可以使用docker-compose命名构建镜像并启动容器组了。

 # 进入docker-compose.yml所在文件夹,输入以下命令构建镜像 sudo docker-compose build # 启动容器组服务 sudo docker-compose up

如果一切顺利,此时你应该可以看到四个容器都已经成功运行了。

Docker-compose 八步部署Django + Uwsgi + Nginx + MySQL + Redis升级篇此时打开你的浏览器,输入你服务器的ip地址或域名指向地址,你就应该可以看到网站已经上线啦。

第八步:排错

初学者使用Docker或Docker-compose部署会出现各种各样的错误,本文教你如何排错。

Nginx容器排错

容器已启动运行,网站打不开,最有用的是查看Nginx的错误日志error.log。由于我们对容器内Nginx的log进行了挂载,你在宿主机的/compose/nginx/log目录里即可查看相关日志。

 # 进入nginx日志目录,一个access.log, 一个error.log cd compose/nginx/log # 查看日志文件 sudo cat error.log

绝大部分网站打不开,Nginx日志显示nginx: connect() failed (111: Connection refused) while connecting to upstreamNginx 502 gateway的错误都不是因为nginx自身的原因,而是Web容器中Django程序有问题或则uwsgi配置文件有问题。

在进入Web容器排错前,你首先要检查下Nginx转发请求的方式(proxy_pass和uwsgi_pass)以及转发端口与uwsgi里面的监听方式以及端口是否一致。

uWSGI和Nginx之间有3种通信方式unix socket,TCP socket和http如果Nginx以proxy_pass方式转发请求,uwsgi需要使用http协议进行通信。如果Nginx以uwsgi_pass转发请求,uwsgi建议配置socket进行通信。

更多关于Nginx和Uwsgi的配置介绍见个人博客:

  • https://pythondjango.cn/python/tools/6-uwsgi-configuration/

  • https://pythondjango.cn/python/tools/5-nginx-configuration/

Web容器排错

Web容器也就是Django+UWSGI所在的容器,是最容易出现错误的容器。如果Nginx配置没问题,你应该进入web容器查看运行脚本命令时有没有报错,并检查uwsgi的运行日志。uwsgi的日志非常有用,它会记录Django程序运行时发生了哪些错误或异常。一旦发生了错误,uwsgi的进程虽然不会停止,但也无法正常工作,自然也就不能处理nginx转发的动态请求从而出现nginx报错了。 

 # 查看web容器日志 $ docker-compose logs web # 进入web容器执行启动命令,查看有无报错 $ docker-compose exec web /bin/bash start.sh # 或则进入web柔情其,逐一执行python manage.py命令 $ docker-compose exec web /bin/bash  # 进入web容器,查看uwsgi是否正常启动 $ ps aux | grep uwsgi  # 进入uwsgi日志所在目录,查看Django项目是否有报错 cd /tmp

另外一个常发生的错误是 docker-compose生成的web容器执行脚本命令后立刻退出(exited with code 0), 这时的解决方案是在docker-compose.yml中包含以下2行,  另外脚本命令里加入tail -f /dev/null是容器服务持续运行。

 stdin_open: true tty: true

有时web容器会出现不能连接到数据库的报错,这时需要检查settings.py中的数据库配置信息是否正确(比如host为db),并检查web容器和db容器是否通过db_network正常通信(比如进入db容器查看数据表是否已经生成)。在进行数据库迁移时web容器还会出现if table exists or failed to open the referenced table ‘users_user’,  inconsistent migration history的错误, 可以删除migrations目录下文件并进入MySQL容器删除django_migrations数据表即可。

数据库db容器排错

我们还需要经常进入数据库容器查看数据表是否已生成并删除一些数据,这时可以使用如下命令:

 $ docker-compose exec db /bin/bash # 登录 mysql -u usernmae -p; # 选择数据库 USE dbname; # 显示数据表 SHOW tables; # 清空数据表 DELETE from tablenames; # 删除数据表,特别是Django migrationstable DROP TABLE tablenames;

小结

本文详细地介绍了如何使用docker-compose工具分七步在生成环境下部署Django + Uwsgi + Nginx + MySQL + Redis。过程看似很复杂,但很多Dockerfile,项目布局及docker-compose.yml都是可以复用的。花时间学习并练习本章内容是非常值得的,一但你学会了,基本上可以10分钟内完成一个正式Django项目的部署,而且可以保证在任何一台Linux机器上顺利地运行。本文最后的排错文章更会助你一臂之力。

注意:整个部署过程如果遇到问题,可以给我们留言或发信息,可以节省你的时间。

相关阅读

Docker部署Django由浅入深系列(下): 八步部署Django+Uwsgi+Nginx+MySQL+Redis

如何在阿里云Ubuntu服务器通过uWSGI和Nginx部署Django项目教程-大江狗原创出品

转自:https://mp.weixin.qq.com/s?__biz=MjM5OTMyODA4Nw==&mid=2247486903&idx=1&sn=5d2172f66c0357ffaefac7c783c80867&chksm=a73c6d8f904be4999d7844a7f70f9d3aa8cc460cd18089f13924711a3261cd4c69d1c7b6933e&scene=132#wechat_redirect

一位上海外卖小哥之死

疫情真的是在瓷器店捉老鼠吗?为什么现在老鼠没捉到,上海却像瓷器一样摔了个稀碎呢?

(壹)

4月22日凌晨,上海静安区延长中路700号左右,临近久乐苑北门的地方,一个外卖小哥发生了车祸,他骑着电瓶车不小心撞向了路边,电瓶车摔倒在非机动车道上,他的头狠狠的撞向了路边的树干后倒在人行道上,鲜血不断的涌出来,流了一地。

一位上海外卖小哥之死

(血流不止的小哥,图片来自微博网友@superpuer)

封城的夜里,路上人烟稀少,警察赶到了,后来小哥的妻子也赶到了,但唯独120迟迟未来,小哥的脑袋泡在一滩血中,鲜血还在不断的往外流,除了专业的抢救人员,没有人敢轻举妄动。随着时间的流逝,小哥和妻子还是迟迟看不到120的救护车,小哥身下的血越来越多,气息也越来越微弱,妻子开始绝望和崩溃。

一位上海外卖小哥之死

(路人拍摄的视频截图,图片来自网络)

根据住在旁边被隔离在家的居民讲述,她听到了小区门口一个女声哭了快半小时,声音之凄惨绝望,一开始还以为是感染了但不愿意去方舱,后来看小区群里才知道是外卖小哥送外卖时撞到了树上,头部出血将近一个小时,整整一个小时血都快流干了也等不来一台120。

妻子在孤独和绝望中痛哭大喊”救救他吧”,在出事一个小时后,120终于来了,外卖小哥被宣告死亡。

一位上海外卖小哥之死

(姗姗来迟的120,图片来自微博网友@假的庄Hlai)

有路人说120优先去接阳性病人去了,所以延误了一个小时才过来,但这个说法无法核实真伪,也不知道有没有机会核实真伪。

(贰)

荒谬的是,从外卖小哥出事的地方(延长中路700号)沿着延长中路向南北高架方向走700米,就是上海市第十人民医院(延长中路301号),一个北上海知名的大三甲。

一位上海外卖小哥之死

(两者相距约700米,图片来自百度地图)

而就在几天前,十院刚刚发布了《十院医疗救治不断线》的公告,里面清晰写到了为保障市民群众在疫情期间的就医需求,首先急救绿色通道24小时开放,安排专业医护团队值守;其次不会因无核酸阴性报告而延误患者治疗,在诊治的同时做抗原和核酸检测即可;最后医院联络渠道畅通,会在第一时间内响应。

一位上海外卖小哥之死

(上海十院官微公告截图)

你能想象吗?2022年,在上海,在一个人民医院为人民的大三甲附近,一个为生活奔波的普通人活活在自己的鲜血中等了1个小时,最后没有等来120,而是先等来了自己的死亡…我无法想象,但它就是活生生的发生了,发生在这片我们曾经骄傲的土地上。

凌晨1点,上海下了场大雨,现场的血迹被冲刷的一干二净,仿佛这场死亡从来没发生过一样。同样第二天也没有新闻报道这个事情,社交媒体上也看不到这个小哥的身影,零星有几个附近居民在网友发出一些现场照片,但基本都被删除完毕,点进去之后,黑色的提示框映出我面无表情的脸——有人会记得他吗?有人会为他的死感到负罪吗?有人会对此承担责任吗?难道一个鲜活生命就这么悄无声息的死在上海4月的春天里?

他是一个人,一个在此之前活生生的人,跟你我一样,他有自己的名字,有自己的家人,有自己在乎和被在乎的人,有自己的情感和生活,有自己的爱好甚至理想,他不是报表里的一个数字,不是政策文件中的代价,不是某种非必要就不要的东西。

一直以来,我觉得作为一个社会人应该明白一件事情,就是你听到的看到的发生在别人身上的事情,都有可能某天发生在自己身上。这位外卖小哥之死,每个人都不能觉得跟自己无关,这件事情能发生在这个外卖小哥身上,就有概率发生在你身上。

如果这件事真的发生在了你身上,此情此景下你有办法避免死亡吗?你扪心自问,真的有吗?

(叁)

这次上海封城,于我而言,最大的震撼在于一些一直以来约定俗成的机制、习以为常的认知全都崩塌了:

出了车祸一定有人来救你吗?不一定。即使你倒在一个大三甲附近,5分钟的路120也有可能走1小时,死神捷足先登,奇迹并不会虽迟但到;

急症复发去医院一定有办法吗?不一定。即使你侥幸活着等来了120,但拉了三个地方可能都没有医院会接收你,那个疼痛钻心难捱的夜晚,有人从高楼一跃而下;

饿了一定有东西吃吗?不一定。如果没有大量囤积食物,如果支付不起成倍高价求东问西的团购,那么你真的有可能在非战争时期中国最大的城市中挨饿,甚至可以说遭遇准饥荒;

生活离无政府状态很遥远吗?不一定。一座曾被评为全球最安全之一的样板间城市,一座“安全有序,已成为金字招牌”的国际大都市,几天之内就肉眼可见的陷入无序和混乱,而且这种混乱可以说是无处不在;

计划经济模式已成历史了吗?不一定。从市场经济回滚到计划时代仅需要短短一周,一个居委主任也能决定哪些人有饭吃哪些人要饿肚皮,哪些人可以吃到好东西哪些人只能收到过期烂货;

饿了无饭可食,病了无医可救,大小买办大发民难财无人监管,普通民众被无情剥削无路可走,部分社区成为孤岛无人管理,邻居一个个排着队变阳也无人问津,传说中的城市管理天花板一夜之间跌成地板,各种利益勾当以次充好趁火打劫一个不少,这就是疫情中的上海。

一种信任被彻底毁掉了,而且从最近其他城市的表现来看,这种不信任、恐慌已经在传染,风声鹤唳的不安全感会通过WiFi传递到每一个通网的地方。

我只是一个普通的底层小市民,但心中也有无穷的问号,回到我开头的疑问,在瓷器店里捉老鼠,没想到老鼠还没捉到,文明和秩序连同我们的生活和价值观就像瓷器一样破成千万块碎片——这到底是为什么?

缅怀这位在上海四月天雨夜去世的外卖小哥,希望大家记住他,世上没有白走的路,更不要有白走的人。

走好。

 

转自:https://mp.weixin.qq.com/s/mMKDL72bwcWicEwPIT9PJA

上海急诊告急,急在哪里

作者 | 魏晞 李强  胡紫纯(实习生)

编辑 | 从玉华

4月,上海交通大学医学院附属仁济医院东院区的急诊科每天要涌进两三百名病人,有一天仅救护车就开来114辆,是往常的两倍多。这是仁济东院急诊科没经历过的时刻。最多时,门口排队入院的救护车就有6辆。

在浦东新区的这家三甲医院里,急诊科的固定床位早已满员,大厅睡满了病人。新病人到来,护士用记号笔在纸板上写一个数字,挂在输液架上,就新增一张临时床位。4月初,护士们花时间画出急诊床位图——化验室门口睡了72、80、90号病人,抢救室后走廊睡了76、70、97号病人。

4月21日那天,新来的病人拿到的号码是351号,但床位图已经没时间画了,由于新冠“阳性病人”的陆续出现,其他病人四处挪动,护士找病人也成了新难题。她们有时急得“大吼大叫”,在急诊室内外到处寻找。

30余名急诊科医生、165名护士,以及30余名从其他科室临时调来的医生,极力支撑着这个已经处于“超饱和状态”的急诊科。干完一天工作,医护有时苦恼,明天再来病人,应该怎么“塞”?更何况,病人们多数是“在家扛到没法再拖”,不得已才来医院,病情近乎危重,不能不救。 

撑着的急诊科医护人员

上海急诊告急,急在哪里

4月16日,上海浦东新区,一名脊柱外科医生在仁济东院急诊入口值班。中青报·中青网记者 李强/摄

急诊科副主任医师熊剑飞已经忙到没空去记住任何一个病人的脸。

他形容,以往接诊,看完一个病人,写好医嘱,再接着看下一个病人。但现在,病人实在太多了,一个接着一个,等他一股脑全看完,准备坐下来写医嘱时,又会听到叫声,“这个又气喘了,医生!”“医生,胸痛!”

有一天中午,急诊科来了一位胸痛病人。他辗转多家医院,跑了3个小时,才被仁济东院急诊科接收。刚准备做检查时,病人心跳突然停了。熊剑飞穿着笨重的防护服,为患者做心肺复苏按压近一个小时,但没能救回来。

同一时间,隔壁床又来了一个大面积心梗的病人,意识模糊,心律失常。熊剑飞刚抢救了一个病人,又转到隔壁床为病人做心肺复苏。

结束时,熊剑飞看了一眼表,晚上八点半,早已过了他的下班时间,防护服里的衣服湿透了。他清楚记得,那天夜里风有点凉,他没能从死神手里抢回这两个病人。

护士曹燕有时感觉,快要淹没在病人和家属的招呼声里。急诊大厅里那些临时设置的床位没有床头铃,只能依靠病人家属呼叫护士。她经常正忙着,同时能听到来自不同方位的病床的呼叫声。

病人多的时候,有医生着急得都要哭了,“没有那么多双手”。有护士说,恨不得有三头六臂。急诊科的工作向来争分夺秒,很多时候,私家车或救护车刚开到急诊楼前,医护人员就奔过去就地抢救。

一位待在急诊科的病人家属说,她每天听到医护人员说得最多的一句话是,“快,快,快!”

但穿上防护服,“就像背上一层盔甲”,他们的行动变得迟缓,灵敏度下降,视野与说话也受限,得扯着嗓子喊。有个老年人怕护士听不见,忍不住凑到跟前,扯下口罩说话。“快戴回去!”周围人马上提醒。后来,急诊科给护士配备了随身的麦克风。而原先八小时的一个班,现在干四个小时就容易累。于是,急诊科一个班的时间最短缩至4小时,这也是防护服的最佳使用时限。

此时,救治一位急危重病人,意味着医护人员要投入数倍的精力。而留守本院的急诊医护力量很难应付数量翻倍的急诊病人。

“我们原先一天救护车量是30至40辆,多的时候,会有50多辆。”仁济医院东院门急诊办公室主任张斌渊告诉中青报·中青网记者,“现在基本上每天八九十辆,厉害的时候要超过100辆。”

张斌渊说,以往,上海病人数量、医疗机构数量和120救护车数量,基本处于紧平衡的状态。但当越来越多医院改为定点医院以后,非定点医院急诊科的压力陡然变大。如今,他也一下子搞不清楚,在上海,有哪些医院的急诊科还是开着的,是可以接诊的。

不少病人向记者反映,当他们呼叫120救护车时,时常被告知,需要排队等待,有时排到的号是200多,有时排到的是500多。

急诊科副主任刘黎发现,“上海发布”(记者注:上海市政府新闻办公室社交账号)公布的医院开诊信息,有时是滞后的。她听到有病人说,根据这个开诊信息去某个医院后,发现医院正在消杀,无法接诊。

一位上海120救护车司机在接受媒体采访时也提过类似的事:运送病人时,他曾遇到医院上午还开着,下午却在消杀,只能跨区往其他医院转运。上海医疗急救中心组织了一个专班通过电话了解各医院收治的情况,但是信息变化快,很多时候他们无法实时跟医院互联互通。

据媒体报道,上海全市层面市级医院的门急诊业务量激增。相比4月初,36家市级医院的急诊量增长了65%。而上海市120急救业务量也大幅增长。

上海市医疗急救中心曾向媒体介绍,120调度指挥中心单日呼入电话数高达9.1万个,是去年日均来电量的12.3倍,日均派车近5000次,这突破了120业务历史峰值,处于超负荷运转状态。

仁济东院的医生们有时怀疑,急救中心的调配系统出了问题,尤其在4月初到4月中旬的半个月里,他们感觉,浦东新区的救护车似乎只往仁济东院的急诊科跑。

张斌渊有时还看到配药的志愿者,拿着装满一个小区慢性病人的病例卡的袋子到门诊开药,开完背着满满一蛇皮袋药回去。

这些原本在互联网医院、社区医院就能解决的诊疗问题,也在挤占这家三甲医院的医疗资源。张斌渊发现,推行多年的互联网医院与分级诊疗没能发挥更大的作用。许多肿瘤病人需要打皮下针,可以协调社区医生上门打针,“这种时候,能不来医院,最好不来。”

急诊团队很快发现,仅依靠本科室的医护力量,已经吃不消。新的人手临时抽调到急诊。呼吸科、消化科、心内科、肾内科等专科医生前来支援,然而面对急诊科的工作,有人哭了。有些护士得靠安眠药才能入睡,太累,头痛。

急诊科副主任刘黎说,由于疫情,她已经一个月没能回家,她问孩子,为什么极少联系她,是不是不想她?

孩子回答:“我还能和你说什么,你那么忙,谁让你是医生呢?”

拥挤的急诊大厅

上海急诊告急,急在哪里

4月18日,上海市浦东新区,仁济东院急诊科走廊里靠墙两侧都摆着病床,只留下供人行走的小道。中青报·中青网记者 李强/摄

2月26日以来,上海暴发新一轮本土新冠肺炎疫情,截至4月25日,上海累计报告本土感染者已超过50万例。上海的许多医院不得不关停,转为新冠肺炎定点医院,越来越多的方舱医院临时建起来,用于收治新冠肺炎感染者。

因疫情防控需要,仁济东院急诊于3月7日至3月9日8时、3月16日至3月23日8时闭环管理,共计闭环管理9天。自3月23日起至今,仁济医院东院急诊科就再没停过。

3月28日,上海市浦东新区开始“封控管理”。医院接到浦东“封控”的通知是3月27日晚上,正在值班的刘黎挨个给医生打电话,把家在浦西的连夜叫到医院来。“封了,万一不能从浦西到浦东来上班,怎么办?否则明天急诊不能正常运转了。急诊是关不了的。”那天晚上,许多医生拉着行李箱赶到医院,之后就再也没回过家。

与此同时,仁济医院也抽调许多医护力量支援新冠肺炎定点医院、方舱医院。由于许多医院转为“新冠肺炎定点医院”,大量的非新冠病人无处就医,一时间成为难题。医生们眼见着浦东新区的病人们,往仁济东院急诊科涌来。

张斌渊发现,最近来急诊的老人多了,慢性病患者也多了,比如癌症病人、血透病人、糖尿病病人,甚至包括肺癌晚期的病人,“很多就是屏(撑)不住送到我们急诊来的”。

急诊科14床住着一个99岁的老人,在家发烧半个月,进急诊科时已经意识昏迷。76床是一位56岁的慢性肾病患者,往常血透的医院改为“新冠肺炎定点医院”,他辗转了3家医院后,最终在仁济东院做上了透析,脸上才恢复血色。即便如此,由于血透资源紧张,他每周三次的透析,只能改为两次。

“最近,无论是救护车拉来的,还是自己过来的病人,病情都很重。”护士胡秋颖告诉记者,她常听到很多人跟她讲,“我们本来想扛一扛,等到解封再来看(病)。实在是扛不过去了。”

新病人接踵而至。护士曹燕最开始给病人找担架床当临时床位,后来找了许多轮椅当“病床”。最后,轮椅也用光了,只好给病人找张椅子坐。有家属则自己购买躺椅在一旁陪护,原价100多元的躺椅,被炒到近300元。还有一些独居老人,一个人孤零零地被救护车送来,护士还得联系警察,帮忙找家属。

在急诊科,欠费卡最近多了4张。4个欠费的病人,全是独居老人。一个90多岁的老年痴呆患者被救护车送来,说不清话,连警察也联系不上家属,只能由护士陪着做各项检查。还有个糖尿病患者,因并发症发作进了ICU,女儿不愿意缴费,也不愿意陪护,来医院后大吵大闹,还顺走了周围病床十几个充电器。

刘黎说,“社会的缩影其实在这里。”但他们也遇到过一个住在德州路的病人的儿子,病人可以出院了,但由于浦东新区交通尚未恢复,社区也没人来接,更打不到车,他走了五公里路,“背着他老爸回去的”。也有一位病人家属看到,一个女孩拿着厕所的公用拖把,拖完父亲的病床下方,顺手也把医院过道也拖了一遍。

夜晚,急诊科灯光不灭。蓝色的布屏风把急诊大厅分隔成一个个私密的空间。病人家属用脸盆接水,擦拭身体,把洗的衣服晾在急诊室外的树上。

即便住进急诊室,这群病人还面临着另一个问题,附近餐馆关门,很难买到盒饭。网上最近可以点到外卖,但大多数上了年纪的、不会使用智能手机的病人还是在吃泡面,有病人家属花5天时间托朋友筹集来一箱物资,有人饼干就水。

急诊科住得最久的一位病人,在14年前的一场自行车比赛中发生意外,导致高位截瘫,脖子以下无法动弹,要靠呼吸机维持生命。多年以来,他的父母都在病床边照顾。

他的父亲在这场疫情中感染了新冠病毒,被送去方舱医院隔离,母亲顶替了父亲照顾他的位置,不久母亲也“阳”了,相熟的护工也感染了。

这是14年来,他第一次离开父母,第一个晚上他偷偷掉了眼泪。

护士们和同病房的病人家属担起照顾他的任务——叫醒、喂饭、打开电脑和眼动仪、清理大便。

急诊科的“阳性病人”

上海急诊告急,急在哪里

4月18日,上海浦东新区,在仁济东院急诊科,一名病人在急诊留观,她白发苍苍的母亲牵着她的手陪床。她原本接受治疗的医院因疫情停诊,家属把她送到仁济东院急诊接受救治。中青报·中青网记者 李强/摄

在仁济东院的急诊科,C108室,是一个特殊的存在,专为“阳性”危重症患者进行治疗。

“即使他是阳性我们也会进行救治”。急诊科副主任医师熊剑飞说,他遇到一位尿毒症患者,已经意识模糊,出现心衰症状,且急需进行气管插管,但病人是密接者,家人有“阳性”。他们还是没犹豫,立即予以紧急插管抢救。后来,病人核酸检测结果确实呈“阳性”。

尽管这会增加医护人员的暴露风险,但疫情暴发以来,仁济医院急诊科有一个原则,“不能因为核酸耽误病人的病情。”仁济医院护理部主任奚慧琴说,“这个是我们的天性。”

护士胡秋颖经常遇到这样的情况,病人送来时已经心跳停止,她们会就地抢救,来不及考虑病人的核酸检测结果是阴是阳。她也曾在后半夜,站在急诊入口,为深夜就诊的患者提供问询服务。

站在门前,患者最爱问的是,“里面有没有阳性?”胡秋颖会根据当天的实际情况,如实作答。有病人得知“有”后,开始犹豫,也有人会冒着感染的风险继续就医,这时胡秋颖会提醒他们做好防护措施。

护士金莉听到病人讲得最多的是,“我的核酸报告是阴性”“我有居委会报告”“我可以看病”。有时,金莉只是循例问一句,有没有发烧?病人就马上掏出健康码、行程码。她只好耐心解释,只是登记,即使是阳性,急诊科也不会拒接。

起初,有48小时核酸检测结果的病人,走正常的入院通道。医院为没有48小时核酸检测的病人在急诊楼右侧设置了“危重症患者缓冲区”,并尽量安置在单人单间的环境下进行救治。在确定某位病人是阳性后,会对其停留接触过的地方进行彻底消杀。

但到了4月中旬,缓冲区已经起不上缓冲的作用。刘黎察觉到,来急诊科就诊的病人中,“阳性”越来越多。在缓冲区等待核酸报告结果的病人里,有时混杂着“阴”与“阳”。医院每天都会给病人进行核酸检测,但此前最多时,急诊科一天查出三四十个阳性病人。

医务处每天都要联系方舱或者新冠肺炎定点医院,把阳性病人转走。但很快新的问题又出现,方舱医院接收的病人以轻症、无症状感染者为主,不接收有基础疾病的病人,而许多定点医院床位爆满。4月19日,一位在医院住了4天的尿毒症患者“阳了”,4月21日晚,病人才被转运至定点医院接受治疗。

“我们不怕接诊阳性病人,就怕阳性病人转不走。”刘黎告诉记者,那些滞留在急诊科的阳性病人会增加医护人员和其他病人的暴露风险。

急诊室内,患者家属也表现出对于阳性病人的恐惧,有人穿着“二级防护”进入医院,被误认为是医护人员,有人穿着雨披、雨鞋、雨衣入院,口罩戴了双层,有人连防毒面罩也用上了。为了透透气,一些病人跑到外面,露天输液。

每天到下午,出核酸检测结果的时候,是急诊科医护人员最紧张的时刻。“开奖了,开奖了!”护士会互相半开玩笑地说道,只有结果是阴性,他们才会离开医院,回到住处休息。

张斌渊告诉记者,“医务人员的防护没什么问题”,但可能是初期在院外感染,“医务人员也是社会的一部分”,也可能是在极度疲劳状态下院内感染。这一定程度上造成了,急诊科医护的“非战斗减员”。

尽管如此,在有同事感染的情况下,那些作为密切接触者的医生们,选择穿着防护服继续战斗。后来,那些封控在家的医护人员,只要家中没有“阳性”也被召回,经在院隔离观察后返回岗位。医院在员工管理上开始变得“不讲人情”。奚慧琴说,“不管你家里有老有小,不能再流动了,全部在(医院)这里。吃饭间隔两米,吃完就走。”

最近,奚慧琴听到了一个好消息,早期在社区感染新冠肺炎的其他科室医护人员,已经有人重新回到医院上班了。

积压在急诊科的病人

上海急诊告急,急在哪里

4月18日,上海浦东新区,仁济东院急诊科一楼电梯口,一位患有免疫系统疾病的病人靠输液维持,等待更专业的治疗。病人家属告诉记者,病人血小板最低时达到个位数,由于原本想转去的医院转为新冠肺炎定点医院,病人只好在急诊室维持治疗,以免出现突发状况来不及抢救。中青报·中青网记者 李强/摄

在急诊科工作了15年的护士金莉明显感觉到,因各小区封闭管理,出车祸进急诊的人少了,被送来的醉酒者少了、打架斗殴受伤的人也少了。进入急诊室的,多是濒危或危重的“一二类病人”,急症、非急症病的“三四类病人”少了。

一些原本不常出现在急诊科的病人,如今正在急诊科等待着诊疗。

刘黎告诉记者,她遇到过一位心脏病病人,起初只是心绞痛、胸闷,由于封控管理,一直没能到医院看,“等到实在屏(撑)不住来看已经大面积心梗。”

许多人都在“屏”。

熊剑飞最近发现,来急诊科的糖尿病病人,有两个极端。“一个血糖很高,一个血糖很低。”前者是封控后,病人断药后一时间配不到药,停药多天后,血糖升高;后者是药没停,但食物短缺,吃的少了,血糖降低。还有一位女患者,因为买不到蔬菜,连吃了两顿肉,“进食油腻,胰腺炎发作”。

急诊科一楼电梯厅的墙边,住着一对年轻的夫妻,女人无力地躺在躺椅上。男人告诉记者,他的妻子患有免疫系统疾病,最糟糕的时候,妻子的血小板低至个位数。正常情况下,他们可以转移到仁济南院,在那里得到更专业的医生的会诊,但仁济南院如今转为新冠肺炎定点医院。他的妻子只好在仁济东院的急诊待着,以免出现突发出血感染状况,来不及抢救。但长期待在急诊室,他们存在感染新冠肺炎的可能性。

“我相信上海不止我们家有这个情况。”男人说。

“真正的重病人都在我们这边,需要抢救的,需要及时救治的。所以我们的压力可能更大。”张斌渊说,方舱医院面对的病人数量多,人群庞杂,“可能疏导,服务方面的工作多一些。”

还有许多事情,是急诊科解决不了的。

让刘黎印象深刻的是一位老先生,当他可以出院时,女儿也不希望他回家,因为家里有小孩,担心老人把病毒带回来。那时,这位老人的核酸检测结果一直是阴性,但他只好一直住在急诊科里,“直到4月10日转‘阳’了”。另一对早已康复的老夫妻原先住在养老院,但养老院封闭管理,他们也回不去。

那些已经康复却因各种原因滞留急诊科的病人,成了医生的心结。刘黎曾寄希望于二级医院、社区医院能接收一些康复的病人,但大多下级医院认为病人风险较高,无法接收。“进来的多,出去的少。”刘黎说,这就造成急诊病人积压在急诊室,而新的病人被120急救车送来很可能没有床睡,除非120把救护车上的床留在这里。

4月12日,急诊科医护人员收到了急诊病房11床的来信。11床住着一位71岁的老先生,陪伴他的是同龄的老伴,两人年轻时去安徽当知青,而后生活在上海。

老太太在信里表达了对“奥密克戎”的恐惧:看着急诊科的病房昨天转走一只“羊”,今天又转走一只“羊”,不知道哪天轮到她要被“牵走”。

于是,她和老先生商量决定,“无论我们夫妻双方有一方变‘羊’,能不能关在一起,我们永远不分开”。并且,为了感谢医护人员的照顾,两人决定把遗体捐献给医院,“如果这事办妥了,我也不害怕了,随时随地做好准备。”

刘黎看到这封信,哭了一场,但她知道,按照防疫规定,这个“‘阴’‘阳’不分离”的诉求很难实现——“如果转定点医院和方舱,只能阳性病人去”。

奥密克戎始终没有打扰这对恩爱的夫妻。但4月23日晚上快10点的时候,老先生因基础疾病,走了,“走得很平静”。病区医生联系了红十字会,对方回复:疫情期间暂不办理遗体捐献。

急诊科的大夫都没预想到,这场仗会持续到现在。张斌渊时常看到,那些从病区脱掉防护服走出来的医生、护士,“身上都湿透了”“大家还是咬着牙,硬顶着”。

“大家还在坚持。没人说不想干了,或者逃避。”刘黎说,有的医护孩子还很小,甚至刚刚断奶,有的孩子跟妈妈视频时,在手机那头哭着找妈妈,妈妈也在电话这头哭。急诊病房护士长的儿子今年夏天参加中考,但她现在完全顾不上孩子的学习。

如今,他们一边等待着这非常时期的急诊室回归日常,一边日复一日地在那24小时不灭灯的急诊室奔命。

医院里曾十分红火的咖啡馆已经关门许久,但大家偶尔还能听到从医院门诊楼传来的钢琴声。4月的一天傍晚,一名穿着白大褂的医务人员在此弹了一曲《River Flows In You》。

(中青报·中青网记者马志强对本文亦有贡献)

– END –
中国青年报·中国青年网出品
转自:https://mp.weixin.qq.com/s/0HK1HGBFfoeh-gQYQhIaKQ

【每天五分钟,学会C++】27:比高斯快——for语句应用(小学生也能学的C++入门教程)

这是为小朋友们准备的一个C++入门系列教程,推荐小学高年级以上(四年级以上)或者对计算机编程有兴趣的朋友观看,内容浅显易懂,和小朋友一起学起来吧。

小胖发现重复敲代码很低效率,想找一个更好的解决办法。结果使用了新的for语句,试着运行一下,哇塞,感觉比数学家还要快速。

有不明白的地方,可以留言,谢谢!

也可以加老师微信号 zimugo2021,详细沟通。

回复消息 devc 后获得视频中使用的 C++ 开发工具 DEV C++ 的百度网盘下载链接。

少儿学编程的一千个理由

  • 2017年,国务院印发《新一代人工智能发展规划》中要求推广编程教育;
  • 2017年,浙江宣布把编程加入高考的选考科目;
  • 2018年,教育部将编程语言、算法等划入高中新课程标准;
  • 2018年,教育部《教育信息化2.0行动计划》中提出高中小学生和老师的信息技术素养。
  • 2019年,《青少年编程能力等级》标准正式发布。
  • …………

【每天五分钟,学会C++】27:比高斯快——for语句应用(小学生也能学的C++入门教程)

感谢您的阅读与观看

 

【每天五分钟,学会C++】27:比高斯快——for语句应用(小学生也能学的C++入门教程)

加油,奥力给!

若文章对您有帮助,请毫不犹豫地关注、转发、点赞、在看,毕竟人间那么值得,就缺您的三连!

转自:https://mp.weixin.qq.com/s/TrZDja1qeB-lQ26TFipxdg

我在上海,盼解封,又怕解封!

我在上海,盼解封,又怕解封!

原创:张明扬

来源:冰川思享号(ID:icereview)

文章已获授权

追求更好的生活当然是人的本能,也是一种天赋权利,但在某些特殊的时刻,你不得不真心的劝说自己接受现实:以前的那种生活方式再也回不来了。

在被封了一个月之后,上海何时解封仍然是一个盲盒。

但或早或晚,五月初,五月中,五月底……上海总会解封,哪怕中间还有反复,但我们总会出关。

等到那一天到来时,我们很多人会奔向街头,哪怕站在路边喝上一杯咖啡或啤酒,都会觉得喝出了自由的味道。

但是,短暂的狂欢过后,我们总要回到现实,然后惊愕地发现:就连现实也回不到过去,我们和我们熟悉的那个世界之间已经变得如此陌生。

被改变的不仅是上海人,只要你体会过封控是什么。

我们再也回不去了。

01

我想,本轮疫情对很多人最大的改变是:囤货。

一般而论,这一代中国年轻人(含中年人)并没有囤货的习惯,很多人受“断舍离”文化的影响,崇尚简单生活。

在他们看来,老一辈基于饥馑记忆的囤货本能是一个前现代的陋习,在消费文化上属于鄙视链的底端。

但经过这一轮封控,即使是那些暂时没有受到封控之累的国内年轻人也开始明白:囤货并没有过时,它超越了时空。

前一段时间,公号上五花八门的“囤货指南”虽然良莠不齐,但不知道产生了多少个百万加十万加,年轻人知耻而后勇,如饥似渴地填补着生命的空白。

被很多年轻人鄙视的“老人电器”冰柜,随之也成为了网红电器,每一个新售出的冰柜里都装着一个年轻人的囤货绮梦。

我在上海,盼解封,又怕解封!

▲即将送货到家的冰柜(图/网络)

从此,像“润学”一样,“囤学”应运而生,成为了中国年轻人的最新思想资源。

最惨的是上海年轻人。封控在家的他们英雄无用武之地,悔不当初,只能暗暗下决心,待到出关之日一定理论联系实际,在自己家中建立“战略储备”。

02

囤学背后,是我们正在流逝的安全感。

安全感是一种信念,它建立在“我们的生活会越来越好”的进步主义之上,它更是一种“相信相信的力量”。

安全感依赖于我们相信过去几十年的既往美好,依赖于我们相信正规资讯,依赖于我们相信城市文明,依赖于我们相信市场的自发力量,依赖于我们相信经济增长是永不可逆的……

但午夜梦回,当你看着可望而不可及的窗外,看着冰箱里的胡萝卜、土豆、包菜和洋葱,才发现这一切都那么不真实。

想喝上一杯咖啡解压,且不说有没有,想到社交媒体上“封在家还想喝咖啡呢”类似的嘲讽,只能苦笑着对自己说“我不配”。

我在上海,盼解封,又怕解封!

▲网友囤菜(图/网络)

我甚至在想,待到解封之日,看到那些我们完全不能操控的宏大叙事:薪水不降么?工作还有么?生意还做得下去么?股市还跌么?GDP增速还能保五么……

我们会不会回过头来“怀念”封控的日子:至少这段时间我们只用操心明天吃啥菜,晦暗不明的未来被口腹之欲暂时遮蔽了,这或许是一种鸵鸟式的幸福。

03

在这轮疫情以前,我们很容易把一切生活中的小美好视作理所当然。将一切视作理所当然,是未遭生活凌虐的天真。

比如快递,我们享受了太多年的“隔日达”甚至“当日达”,从未想过快递可能是一个按周甚至按月计算的时间周期;但因此我们也开始重新审视快递和外卖小哥,重新审视电商和外卖行业。

这些基于开放市场的美好原来对我们珍视的生活方式如此重要,但却又如此脆弱——甚至经受不起物业居委会的几句口头警告。

曾几何时,我们中的很多人沉溺于“互联网巨头不要惦记着老百姓菜篮子那点事”的反资本叙事,但在封控期间,我们却如此盼望互联网巨头能够惦记我们的菜篮子。羌笛何须怨杨柳春风不度玉门关。

我们彷佛第一次发现,现代都市的运行是一个缺一不可的链条,任何一环出了问题都会把我们的生活打入尘埃。特别是在封控期间,下水道堵塞、停水停电停气、冰箱坏了没办法修、买不到药……任何一点纰漏都将是噩梦。

其实,哪怕是你家里的垃圾三天没人收,你苦心维系的一切体面、尊严和美好就将坍塌在你眼前。

安全感并不仅仅是一个宏大叙事,它就在你身边。就像氧气一样,它在的时候你浑然不觉,不在的时候你只能在绝望中窒息。

04

生命总会找到出路的。

我们用自我调整来适应新环境。在熟悉的生活世界开始崩之时,很多人会在身边寻找答案,或者说,自救。

在封控最缺菜的时候,我们发现了团购,发现了上海最可爱的人——团长,重新发现了邻居,重新发现了邻里关系。

很多年轻人以前会觉得,“宅”是他们对抗这个世界最决绝的反叛姿态。但他们在疫情中发现,自己决定的“宅”才是一种姿态,被迫的“宅”反而是一种对自由的妥协,更不用说,在无远弗届的大时代面前,“宅”是一种奢念,存货吃完了你还是得向邻居求助。

我在上海,盼解封,又怕解封!

▲团长帮助集中采购(图/网络)

但对于中年人来说,向年轻人学习低欲望生活可能是后疫情时代他们不得不放下的身段。

待到解封之日,当百业凋零扑面而来,中年中产不得不接受的现实是,必须降低自己的生活预期,必须像囤货一样开始储蓄。

追求更好的生活当然是人的本能,也是一种天赋权利,但在某些特殊的时刻,你不得不真心的劝说自己接受现实:以前的那种生活方式再也回不来了。

如果你还想坚持所谓的高品质和中产体面,那就是给自己的生活里埋藏着一颗定时炸弹,它在某一天会毁掉你的一切。

这些道理或许你比我还要懂,说的比我还要好,但是,你确定你是真的打算这么做,还是心存侥幸地只是说说?

从择业、创业、换工作、买房、孩子教育投入、举债、奢侈品消费……一切的一切,我们其实这些年一直在变,但过去那些美好年代积累的惯性让我们始终不愿作一决绝的割舍。

以工作为例,对换工作和创业慎之又慎自然是第一铁律,以往那种因为和上司几句口角式的“拍桌子辞职”基本可以视作上一个时代的情绪了。

当然,如果你真的想辞职,得确保已经有了下家;如果你真的想创业,也千万别再寄予什么改变世界的情怀,就以一个灵活就业者的心态“现金流优先”吧。

而投资呢,就更加要转换思维,此刻比任何时候都要记住,赚快钱的妄念更可能将你引向不归路。很多人也许会认为,未来通胀不是会更厉害么,不要更加通过投资来战胜通胀么?

我在上海,盼解封,又怕解封!

图/图虫创意

你说的没错,通胀很可能会比较严重,但“跑赢通胀”这样的想法你怎么敢有,把它留给那些金融高手去得了,你一个连存款准备金率都搞不懂的投资小白坦然负利率点就得了,还真把自己当个人物了,通胀是普通人(中产)可以战胜的么?

但其实你心里都明白的,对么?

生活的大变局其实已经拉开。你难道忘了,2020年以前,你曾经一年出国旅游一次或几次,将海滩作为人生的必需品,但时至今日,如果不是我特别提醒,你是不是觉得这种生活已经离你特别遥远?

从解封之日起,你将不再是你,以往的一切春天都无法复原。

转自:https://mp.weixin.qq.com/s/yj3dj5dvhVxMPUPEQ9OH4A