Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)


作者:大江狗

来源:Python Web与Django开发

大家好,我是猫哥。今天分享一篇文章,作者利用Django 3.0 +Redis 3.4 +Celery 4.4开发了个小应用。应用不复杂,但知识点很多,非常适合新手练手。项目需求如下:

  • 创建两个页面,一个用于创建页面,一个用于动态展示页面详情,并提供静态HMTL文件链接

  • 一个页面创建完成后,使用Celery异步执行生成静态HTML文件的任务

  • 使用redis作为Celery的Broker

  • 使用flower监控Celery异步任务执行情况

Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)

项目完成后演示见下面动画。本项目的GitHub源码地址在最后,请耐心阅读。

Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)

 

第零步:pip设置国内源

国内用户使用pip安装python包特别慢,这主要是应为国内连接国外网络不稳定。为加速python包的安装,首先将pip安装源设置为国内的镜像,比如阿里云提供的镜像。

linux系统修改 ~/.pip/pip.conf (没有就创建一个), 内容如下:

[global]index-url = https://mirrors.aliyun.com/pypi/simple/

windows系统直接在user目录中创建一个pip目录,如:C:Usersxxpip,新建文件pip.ini,内容如下:

[global]index-url = http://mirrors.aliyun.com/pypi/simple/

第一步:安装Django并创建项目myproject

使用pip命令安装Django.

 pip install django==3.0.4 # 安装Django,所用版本为3.0.4

使用django-admin startproject myproject创立一个名为myproject的项目

 django-admin startproject myproject

整个项目完整目录机构如下所示, 项目名为myproject, staticpage为app名。

Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)

第二步:安装redis和项目依赖的第三方包

项目中我们需要使用redis做Celery的中间人(Broker), 所以需要先安装redis数据库。redis网上教程很多,这里就简要带过了。

  • Windows下载地址:https://github.com/MSOpenTech/redis/releases

  • Linux下安装(Ubuntu系统):$ sudo apt-get install redis-server

本项目还需要安装如下依赖包,你可以使用pip命令逐一安装。

 pip install redis==3.4.1
 pip install celery==4.4.2
 pip install eventlet # celery 4.0+版本以后不支持在windows运行,还需额外安装eventlet库

你还可以myproject目录下新建requirements.txt加入所依赖的python包及版本,然后使用pip install -r requirements.txt命令安装所有依赖。本教程所使用的django, redis和celery均为最新版本。

 django==3.0.5
 redis==3.4.1
 celery==4.4.2  
 eventlet # for windows only

第三步:Celery基本配置

  1. 修改settings.py新增celery有关的配置。celery默认也是有自己的配置文件的,名为celeryconfig.py, 但由于管理多个配置文件很麻烦,我们把celery的配置参数也写在django的配置文件里。

 # 配置celery时区,默认时UTC。
 if USE_TZ:
     timezone = TIME_ZONE
 
 # celery配置redis作为broker。redis有16个数据库,编号0~15,这里使用第1个。
 broker_url = 'redis://127.0.0.1:6379/0'
 
 # 设置存储结果的后台
 result_backend = 'redis://127.0.0.1:6379/0'
 
 # 可接受的内容格式
 accept_content = ["json"]
 # 任务序列化数据格式
 task_serializer = "json"
 # 结果序列化数据格式
 result_serializer = "json"
 
 # 可选参数:给某个任务限流
 # task_annotations = {'tasks.my_task': {'rate_limit': '10/s'}}
 
 # 可选参数:给任务设置超时时间。超时立即中止worker
 # task_time_limit = 10 * 60
 
 # 可选参数:给任务设置软超时时间,超时抛出Exception
 # task_soft_time_limit = 10 * 60
 
 # 可选参数:如果使用django_celery_beat进行定时任务
 # beat_scheduler = "django_celery_beat.schedulers:DatabaseScheduler"
 
 # 更多选项见
 # https://docs.celeryproject.org/en/stable/userguide/configuration.html
  1. settings.py同级目录下新建celery.py,添加如下内容:

 # coding:utf-8
 from __future__ import absolute_import, unicode_literals
 import os
 from celery import Celery
 
 # 指定Django默认配置文件模块
 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
 
 # 为我们的项目myproject创建一个Celery实例。这里不指定broker容易出现错误。
 app = Celery('myproject', broker='redis://127.0.0.1:6379/0')
 
 # 这里指定从django的settings.py里读取celery配置
 app.config_from_object('django.conf:settings')
 
 # 自动从所有已注册的django app中加载任务
 app.autodiscover_tasks()
 
 # 用于测试的异步任务
 @app.task(bind=True)
 def debug_task(self):
     print('Request: {0!r}'.format(self.request))
 
 
  1. 打开settings.py同级目录下的__init__.py,添加如下内容, 确保项目启动时即加载Celery实例

 # coding:utf-8
 from __future__ import absolute_import, unicode_literals
 
 # 引入celery实例对象
 from .celery import app as celery_app
 __all__ = ('celery_app',)

网上很多django redis + celery的教程比较老了, 坑很多。比如新版原生的Celery已经支持Django了,不需要再借助什么django-celery和celery-with-redis这种第三方库了, 配置参数名也由大写变成了小写,无需再加CELERY前缀。另外当你通过app = Celery('myproject')创建Celery实例时如果不指定Broker,很容易出现[ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused这个错误。

第四步:启动redis,测试celery是否配置成功

在Django中编写和执行自己的异步任务前,一定要先测试redis和celery是否安装好并配置成功。

首先你要启动redis服务。windows进入redis所在目录,使用redis-server.exe启动redis。Linux下使用./redis-server redis.conf启动,也可修改redis.conf将daemonize设置为yes, 确保守护进程开启。

启动redis服务后,你要先运行python manage.py runserver命令启动Django服务器(无需创建任何app),然后再打开一个终端terminal窗口输入celery命令,启动worker。

 # Linux下测试
 Celery -A myproject worker -l info
 
 # Windows下测试
 Celery -A myproject worker -l info -P eventlet

如果你能看到[tasks]下所列异步任务清单如debug_task,以及最后一句celery@xxxx ready, 说明你的redis和celery都配置好了,可以开始正式工作了。

 
 -------------- celery@DESKTOP-H3IHAKQ v4.4.2 (cliffs)
 --- ***** -----
 -- ******* ---- Windows-10-10.0.18362-SP0 2020-04-24 22:02:38
 
 - *** --- * ---
 - ** ---------- [config]
 - ** ---------- .> app:         myproject:0x456d1f0
 - ** ---------- .> transport:   redis://127.0.0.1:6379/0
 - ** ---------- .> results:     redis://localhost:6379/0
 - *** --- * --- .> concurrency: 4 (eventlet)
   -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
   --- ***** -----
    -------------- [queues]
                .> celery           exchange=celery(direct) key=celery
 
 
 [tasks]
  . myproject.celery.debug_task
 
 [2020-04-24 22:02:38,484: INFO/MainProcess] Connected to redis://127.0.0.1:6379/0
 [2020-04-24 22:02:38,500: INFO/MainProcess] mingle: searching for neighbors
 [2020-04-24 22:02:39,544: INFO/MainProcess] mingle: all alone
 [2020-04-24 22:02:39,572: INFO/MainProcess] pidbox: Connected to redis://127.0.0.1:6379/0.
 [2020-04-24 22:02:39,578: WARNING/MainProcess] c:usersmissenkapycharmprojectsdjango-static-html-generatorvenvlibsite-packagesceleryfixupsdjango.py:203: UserWarning: Using sett
 ings.DEBUG leads to a memory
            leak, never use this setting in production environments!
  leak, never use this setting in production environments!''')
 [2020-04-24 22:02:39,579: INFO/MainProcess] celery@DESKTOP-H3IHAKQ ready.

第五步:Django中创建新应用staticpage

cd进入myproject文件夹,使用python manage.py startapp staticpage创建一个名为staticpage的app。我们将创建一个简单的Page模型,并编写两个视图(对应两个URLs),一个用于添加页面,一个用于展示页面详情。staticpage目录下我们将要编辑或创建5个.py文件,分别是models.py, urls.py, views.py, forms.py和tasks.py,其中前4个都是标准的Django项目文件,内容如下所示。最后一个tasks.py用于存放我们自己编写的异步任务,稍后我会详细讲解。

 # staticpage/models.py
 from django.db import models
 import os
 from django.conf import settings
 
 class Page(models.Model):
     title = models.CharField(max_length=100, verbose_name="标题")
     body = models.TextField(verbose_name="正文")
 
     def __int__(self):
         return self.title
 
     # 静态文件URL地址,比如/media/html/page_8.html
     def get_static_page_url(self):
         return os.path.join(settings.MEDIA_URL, 'html', 'page_{}.html'.format(self.id))
 
 # staticpage/urls.py
 from django.urls import path, re_path
 from . import views
 
 
 urlpatterns = [
 
     # Create a page 创建页面
     path('', views.page_create, name='page_create'),
 
     # Page detail 展示页面详情。动态URL地址为/page/8/
     re_path(r'^page/(?P<pk>d+)/

page_create视图函数中你可以看到我们在一个page实例存到数据库后调用了generate_static_page函数在后台完成静态HTML页面的生成。如果我们不使用异步的化,我们要等静态HTML文件完全生成后才能跳转到页面详情页面, 这有可能要等好几秒。generate_static_page就是我们自定义的异步任务,代码如下所示。Celery可以自动发现每个Django app下的异步任务,不用担心。

 # staticpage/tasks.py
 
 import os, time
 from django.template.loader import render_to_string
 from django.conf import settings
 from celery import shared_task
 
 @shared_task
 def generate_static_page(page_id, page_title, page_body):
     # 模拟耗时任务,比如写入文件或发送邮件等操作。
     time.sleep(5)
 
     # 获取传递的参数
     page = {'title': page_title, 'body': page_body}
     context = {'page': page, }
 
     # 渲染模板,生成字符串
     content = render_to_string('staticpage/template.html', context)
 
     # 定义生成静态文件所属目录,位于media文件夹下名为html的子文件夹里。如目录不存在,则创建。
     directory = os.path.join(settings.MEDIA_ROOT, "html")
     if not os.path.exists(directory):
         os.makedirs(directory)
 
     # 拼接目标写入文件地址
     static_html_path = os.path.join(directory, 'page_{}.html'.format(page_id))
 
     # 将渲染过的字符串写入目标文件
     with open(static_html_path, 'w', encoding="utf-8") as f:
             f.write(content)
 

本例中我们生成的静态HTML文件位于media文件夹下的html子文件夹里,这样做有两个好处:

  • 与Django的静态文件存储规范保持一致:用户产生的静态文件都放在media文件下,网站本身所依赖的静态文件都放于static文件夹下。

  • 把所有产生的静态文件放在一个目录里与动态文件相分开,利于后续通过nginx部署。

本项目中还用到了3个模板,分别是base.html, detail.html和template.html。base.html和detail.html是没有任何样式的, 仅用于动态显示内容,template.html是用来生成静态文件的模板,是带样式的,这样你就可以很快区分动态页面和静态页面。由于我们后台生成静态文件至少需要5秒钟,我们在detail.html用了点javascript实现等5秒倒计时完成后显示生成的静态HTML文件地址。

3个模板均位于staticpage/templates/staticpage/文件夹下,代码如下所示:

 # base.html
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>添加页面</title>
 </head>
 <body>
      <h2>添加页面</h2>
      <form name="myform"  method="POST" action=".">
          {% csrf_token %}
        {{ form.as_p }}
          <button type="submit">Submit</button>
      </form>
 </body>
 </html>
 
 # detail.html
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>{{ page.title }}</title>
 </head>
 <body>
      <h2>{{ page.title }}</h2>
      <p>{{ page.body }}</p>
 
      <p>倒计时: <span id="Time">5</span></p>
      <p id="static_url" style="display:none;"> <small><a href='{{ page.get_static_page_url }}'>跳转到静态文件</a></small></p>
 
 
 <script>
  //使用匿名函数方法
  function countDown(){
  var time = document.getElementById("Time");
  var p = document.getElementById("static_url");
  //获取到id为time标签中的内容,现进行判断
  if(time.innerHTML == 0){
  //等于0时, 显示静态HTML文件URL
  p.style.display = "block";
  }else{
  time.innerHTML = time.innerHTML-1;
  }
  }
  //1000毫秒调用一次
  window.setInterval("countDown()",1000);
  </script>
 
 </body>
 </html>
 
 # template.html 生成静态文件模板
 {% load static %}
 <html lang="en">
 <head>
 <title>{% block title %}Django文档管理{% endblock %} </title>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
 </head>
 
 <body>
 <nav class="navbar navbar-inverse navbar-static-top bs-docs-nav">
 
   <div class="container">
     <div class="navbar-header">
         <button type="button" class="navbar-toggle" >
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>                        
       </button>
         <a class="navbar-brand" href="#"><strong>Django + Celery + Redis异步生成静态文件</strong></a>
      </div>
 
       <div class="collapse navbar-collapse" id="myNavbar">
        <ul class="nav navbar-nav navbar-right">
  {% if request.user.is_authenticated %}
 
           <li class="dropdown">
               <a class="dropdown-toggle btn-green" href="#"><span class="glyphicon glyphicon-user"></span> {{ request.user.username }} <span class="caret"></span></a>
             <ul class="dropdown-menu">
               <li><a  href="#">My Account</a></li>
               <li><a  href="#">Logout</a></li>
             </ul>
           </li>  
          {% else %}  
             <li class="dropdown"><a class="dropdown-toggle btn-green" href="#"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
 <li class="dropdown"><a class="dropdown-toggle" href="#" ><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
  {% endif %}
        </ul>
 
     </div>
 
   </div>
 </nav>    
 
  <!-- Page content of course! -->
 <main id="section1" class="container-fluid">
 
 <div class="container">
     <div class="row">
      <div class="col-sm-3 col-hide">
          <ul>
              <li> <a href="{% url 'page_create' %}">添加页面</a> </li>
          </ul>
      </div>
 
      <div class="col-sm-9">
           <h3>{{ page.title }}</h3>
          {{ page.body }}
      </div>
 </div>
 
 </div>
 </main>

 <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
 
 </body>
 </html>

第六步:在Django中注册app并添加app的URLConf

 # 修改myproject/settings.py,添加如下内容
 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'staticpage',
 ]
 
 # 设置STATIC_URL和STATIC_ROOT
 STATIC_URL = '/static/'
 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
 
 # 设置MEDIA_ROOT和MEDIA_URL
 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
 MEDIA_URL = '/media/'
 
 # 修改myproject/urls.py,添加如下内容
 from django.contrib import admin
 from django.urls import path, include
 
 from django.conf import settings
 from django.conf.urls.static import static
 
 
 urlpatterns = [
     path('admin/', admin.site.urls),
     path('', include("staticpage.urls")),
 ]
 
 # Django自带服务器默认不支持静态文件,需加入这两行。
 if settings.DEBUG:
     urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
     urlpatterns = urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

第七步:启动Django服务器和并安装Celery异步任务监控工具

如果一切顺利,连续使用如下命令, 即可启动Django测试服务器。打开http://127.0.0.1:8000/即可看到我们项目开头的动画啦。注意:请确保redis和celery已同时开启。

 python manage.py makemigrations
 python manage.py migrate
 python manage.py runserver

如果你要监控异步任务的运行状态(比如是否成功,是否有返回结果), 还可以安装flower这个Celery监控工具。

 pip install flower

安装好后,你有如下两种方式启动服务器。启动服务器后,打开http://localhost:5555即可查看监控情况。

 # 从terminal终端启动, proj为项目名
 $ flower -A proj --port=5555  
 # 从celery启动
 $ celery flower -A proj --address=127.0.0.1 --port=5555

 

监控异步任务还是很重要的,强烈建议安装flower。比如下图中有些任务就失败了。

Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)

源码地址

https://github.com/shiyunbo/django-static-page-generator-celery-redis

Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)

送书活动

Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)

 

本书共13章,主要内容涵盖Python语法及数据分析方法。章主要介绍数据分析的概念,使读者有一个大致的印象,并简单介绍本书频繁使用的Python的5个第三方库。第2章主要做一些准备工作,手把手带读者搭建Python环境,包括Python 3.7.6的安装和pip的安装。第3章介绍Python编程基础。第4章到第7章介绍使用Python进行简单数据分析的基础库,包括NumPy、Pandas和Matplotlib库,并介绍使用正则表达式处理数据的方法。第8章到3章属于进阶内容,但也是Python数据分析的基础,结合机器学习介绍一些常见的用于数据分析的机器学习算法及常用的数学模型。

赠书规则

赠书本数本次共包邮送书 

参与方式:在Python猫读者群抽奖,仅限群友参与。后台发“交流群”,获取入群方式。
开奖时间:2021年5月20日18:00

 

 

, views.page_detail, name=’page_detail’),
 
    ]
 
 # staticpage/views.py
 from django.shortcuts import render, redirect, get_object_or_404
 from django.urls import reverse
 from .forms import PageForm
 from .models import Page
 from .tasks import generate_static_page
 
 def page_create(request):
     if request.method == ‘POST’:
         form = PageForm(request.POST)
         if form.is_valid():
             page = form.save()
             generate_static_page.delay(page.id, page.title, page.body)
             return redirect(reverse(‘page_detail’, args=[str(page.pk)]))
     else:
         form = PageForm()
 
     return render(request, ‘staticpage/base.html’, {‘form’: form})
 
 
 def page_detail(request, pk):
     page = get_object_or_404(Page, id=pk)
     return render(request, ‘staticpage/detail.html’, {‘page’: page})
 
 # staticpage/forms.py
 from django import forms
 from .models import Page
 
 
 class PageForm(forms.ModelForm):
     class Meta:
         model = Page
         exclude = ()

page_create视图函数中你可以看到我们在一个page实例存到数据库后调用了generate_static_page函数在后台完成静态HTML页面的生成。如果我们不使用异步的化,我们要等静态HTML文件完全生成后才能跳转到页面详情页面, 这有可能要等好几秒。generate_static_page就是我们自定义的异步任务,代码如下所示。Celery可以自动发现每个Django app下的异步任务,不用担心。

 

本例中我们生成的静态HTML文件位于media文件夹下的html子文件夹里,这样做有两个好处:

  • 与Django的静态文件存储规范保持一致:用户产生的静态文件都放在media文件下,网站本身所依赖的静态文件都放于static文件夹下。

  • 把所有产生的静态文件放在一个目录里与动态文件相分开,利于后续通过nginx部署。

本项目中还用到了3个模板,分别是base.html, detail.html和template.html。base.html和detail.html是没有任何样式的, 仅用于动态显示内容,template.html是用来生成静态文件的模板,是带样式的,这样你就可以很快区分动态页面和静态页面。由于我们后台生成静态文件至少需要5秒钟,我们在detail.html用了点javascript实现等5秒倒计时完成后显示生成的静态HTML文件地址。

3个模板均位于staticpage/templates/staticpage/文件夹下,代码如下所示:

 

第六步:在Django中注册app并添加app的URLConf

 

第七步:启动Django服务器和并安装Celery异步任务监控工具

如果一切顺利,连续使用如下命令, 即可启动Django测试服务器。打开http://127.0.0.1:8000/即可看到我们项目开头的动画啦。注意:请确保redis和celery已同时开启。

 

如果你要监控异步任务的运行状态(比如是否成功,是否有返回结果), 还可以安装flower这个Celery监控工具。

 

安装好后,你有如下两种方式启动服务器。启动服务器后,打开http://localhost:5555即可查看监控情况。

 

 

监控异步任务还是很重要的,强烈建议安装flower。比如下图中有些任务就失败了。

Django 3.0+Redis 3.4+Celery 4.4 应用开发(附源码)

源码地址

https://github.com/shiyunbo/django-static-page-generator-celery-redis

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

当下与未来,两个最大的基本面

编者按:本文根据格隆博士近日在某一线城市企业家协会年会上的演讲录音整理而成,未经本人校对。刊飨于此,以供争鸣。

 

 

1

 

 

大家好,我是格隆。我已经很少出来讲座了,一是无需讲。在发生什么,摆在那,一点也不复杂。二是无须讲。懂的人自然知道该做什么,不懂的人讲再多也没用,徒然扰人清梦。

 

但岭南是我第二故乡,你们秘书长说在座有300多位企业家,几乎囊括和代表了这块土地上最核心的经济实力,所以我是抱着自家人唠嗑的心态过来的。如果唠完,都能有所收获,皆大欢喜。唠完了,一无所获,也不必怨艾,当我没来过,大家相忘江湖,快马加鞭,各奔前程好了。

 

今天我们脚下的这块热土,是中国GDP最高的省份,也是中国第一个GDP跨越11万亿门槛的省份,也是中国人口最多的省份。

 

最新七普数据,人口仍在源源不断涌入。过去十年,广东人口净新增超过2169万人,这个数字,是净新增排名第二、第三、第四的浙江、江苏、山东三省的总和。

 

当下与未来,两个最大的基本面

 

此心安处是吾乡。人们自己知道该去往哪里。

 

但事实上,在中国有文字记载的3600年历史上,岭南绝大多数时候都只是一个“衡阳雁去无留意”的烟瘴蛮荒之地,只是因为官员贬谪才偶尔见诸于史籍。如果没有魏晋时期汉民族那段充满血泪、堪称史诗级的大逃亡大迁徙,有无今日岭南之繁盛,殊未可知。

 

汉民族在历史上有过多次危急时刻,但最接近亡种的时候,就是魏晋南北朝时期。魏晋南北朝上承秦汉大帝国的消亡,下启隋唐盛世的兴起,长达360余年的时间,汉人如鼠豚一样被肆意驱赶、屠戮,永嘉之乱后北方两大中心洛阳与长安被几度屠城,几乎被夷为平地,华北地区人口在永嘉之乱后八年之内消失90%。所谓千里累白骨,万里无鸡鸣,十室九空如是。

 

那是一段民族大崩溃、大迁徙、大分化、大动荡、大融合的历史。贫穷,战争、屠戮、饥荒、瘟疫,几乎所有贬义词都可以用来形容它。富者良田千陌,贫者无立锥之地。一个在云端享受着神一般的生活,放荡自由,一个在地狱承受着万蛊吞噬,生不如死。一段既糟糕又华丽,冰与火共舞,黑暗与光明并存的时代。

 

同于政治黑暗,时事动荡,不同于经济凋敝,民不聊生。魏晋思想、文学、诗人,都堪称中国历史最优之一。竹林七子自不必说,那个时代的女诗人也一个个才华横溢,蔡琰、苏若兰、左芬、谢道韫、鲍令辉、韩兰英…,是中国历史上少有的一笔恢弘亮色。其中的佼佼者谢道韫,聪慧过人,因实在接受不了夫婿王凝之(王羲之次子,善草书,先后任江州刺史、左将军)的“平庸”,在回家省亲时闷闷不乐,谢安问何故?谢道韫是这样回答的:“一门叔父,有阿大(谢尚)、中郎(谢据)。群从兄弟复有“封、胡、羯、末”,不意天壤之中,乃有王郎!”

 

“不意天壤之中,乃有王郎”——恃才放旷,溢于言表,以致一千多年后,同病相怜的秋瑾还在赋诗为她抱不平:可怜谢道韫,不嫁鲍参军。

 

但就是这样一个才高八斗的才女,在晋末孙恩之乱时,夫婿王凝之为会稽内史,守备不利被杀。谢道韫听闻敌至,举措自若,拿刀出门,杀敌数人才就虏。匪首孙恩感其节义,赦免谢道韫及族人。王凝之死后,谢道韫在会稽独居,终身未改嫁。

 

苦难中浸淫出来的人和事,出乎意料地比同时代的其他东西优秀得多。有晋一朝,有大批能力有志向改变时局的人,他们在苦难中挣扎救世,不屑入世的人,则依旧保持自己的高傲风骨,出淤泥而不染。

 

魏晋不只有暴乱、动荡、战争、死亡,还有累累白骨砌成的魏晋风骨。

 

任何一个民族在发展过程中,均不可能一帆风顺。总会遇到各种天然的灾难和人为的灾难。当灾难降临之时,民族是否具有自我修复能力,是一个民族是否可以延续民族生存及民族发展的根本标志。

 

修复靠什么?

 

骨子里的气节与底线,是谓风骨。

 

 

2

 

 

我们回到经济。

 

当下做生意也好,做投资也罢,你要考虑的最大国情是什么?

 

我直接说答案:两个。

 

一个是通胀,一个是人口。前者决定了未来3年我们环境的氧含量,后者则决定未来30年,乃至几代人能拥有什么样的生活。

 

先说通胀。

 

4月信贷和社融数据出来后,很多人问我:说好的货币政策不急转弯的呢?这不是不急转弯,是哐当一家伙直接砸地上啊:

 

当下与未来,两个最大的基本面

 

我回答:再不收,通胀会比瘟疫还不可控。

 

听者不以为然,说我们哪来的通胀?CPI温和得像只小绵羊:

 

当下与未来,两个最大的基本面

 

怎么说呢?得感谢二师兄的鼎力支持。但千万不要被他的障眼法骗了。很多人都被货币银行学的入门教材带偏了,以为天经地义且只应该用CPI度量通胀。

 

不是的。理论学者习惯于用CPI研究通胀,但没有一个央行行长会盯着CPI制定货币政策。他们盯的是PPI。CPI是结果。如果等CPI起来了才采取动作,黄花菜都凉了。

 

基本的经济学逻辑是:人类经济活动,生产在消费之前。对任何一个经济或者货币周期而言,PPI肯定比CPI先行,且除非经济体有巨大脑血栓或者肠梗阻,否则,PPI一定传导到CPI。

 

那么,PPI什么表现?

 

当下与未来,两个最大的基本面

 

CPI与PPI之间,高达600个点的巨大缺口。

 

6.8%的PPI意味着什么呢?

 

知名学者CCER助教采用了几个不同计算。

 

最简单的入门级处理,本月PPI环比0.9%,折一下年率,大概PPI能到11.4%。

 

有没有更精细一点的做法呢?

 

有的,环比毕竟波动大,如果一个月波动很大,再折年其实并不太妥,我们用相对平均(3个月或者6个月)的数据去年化。结果是,过去3个月,PPI累计增长了3.3%,那么折年大概在14%左右。过去6个月,PPI累计增长了6%,折年率在12% 左右。

 

更进一步,就有点工作量了,就是计算每月的新涨价,做一个定基数,把前一年的12月作为100,然后累计上去。结果是什么呢?

 

当下与未来,两个最大的基本面

 

很明显,今年1-5月的上涨速度极其惊人。我们的历史上还从来没有一个高通胀年份有过这么快的PPI上涨。上面这个图告诉我们,即使到今天为止,后面7个多月,所有价格都不再上涨,今年的PPI涨幅也超过历史上任何一年。

 

稍微来点计量软件,通过季节调整,再做个3个月折年率,那么最近3个月的PPI实际达到了20%:

 

当下与未来,两个最大的基本面

 

这个速度,是1995年以来的最高,我们正在经历26年以来最快的通胀。CCER助教预测5月PPI应该加快到9%附近,如果没有任何措施,年底可以到15%甚至以上。

 

其实根本不用这么严谨和复杂的理论研究,随便看看那些看得见的商品走势,就知道我们正在经历什么:

 

当下与未来,两个最大的基本面

 

沪铝13年新高,沪铜15年新高,铁矿石历史新高。过去7个月,螺纹钢涨79%,动力煤涨73%,玻璃涨84%。

 

过剩得不能再过剩,夕阳得不能再夕阳的钢铁这么涨,是对产业进化发展规律的羞辱。不出意外,上游企业的狂欢,很快将转化为下游企业的停产潮,甚至破产潮。

 

没有几家下游企业扛得住。

 

接着会轮到CPI。

 

很快你会发现,你会吃不起一串羊肉串。

 

不是羊肉涨价。

 

羊肉可以免费奉送。是串肉的铁签子和烤碳太贵了。

 

再重复一遍结论:

1、我们正在经历过去26年来最快的通胀;

2、加息在路上,不以人的意志为转移,无论美国,还是中国;

3、过去这些年,全球央行联合放水打造的资产泡沫浴,或要收场;

4、保护好你的财富,向硬资产、硬通货靠。

 

 

3

 

 

再来谈谈人口。

 

七普数据,很多人说数据有问题,问我怎么看?

 

确实有些数据无法自洽。

 

但统计学的意义在于提供模糊的正确。如果挑统计局的刺,意味着完全放弃统计局的庞大数据,这于投资而言,肯定是极不划算的。

 

至于数据本身,怎么说呢,除了答记者问时口头公布的生育率、人口性别比例有所改善外,官方正式公布的七普数据,几乎无一例外都在指向一个严峻的事实:中国正在发生剧烈的人口变动,这必将影响中国未来几十年的经济、社会和地缘政治前景。

 

人口形势的严峻表现在:

1、越来越少子化(0—14岁人口);

2、劳动适龄人口(15—59岁人口)加速减少;

3、老龄化迅速加深(60岁以上人口);

4、家庭规模加速萎缩。

 

具体数据我不列举了,有兴趣的朋友可以去找找我前期的另一篇演讲稿《中国的近忧与远虑》,那里都有。

 

其实多数人都已注意到了人口的前面三个问题,我重点讨论第四个。

 

极少有人理解家庭规模的迅速萎缩,会对中国社会与经济产生多么重大的冲击和深远的影响。

 

给大家看一张图:

 

当下与未来,两个最大的基本面

 

从上图可以很清晰看出,改开以来40年(1979—2019)中国的经济繁荣,与大家庭关系网壮大的趋势不谋而合。

 

这个并不意外。

 

在过去40年,数量庞大的处于劳动年龄的亲兄弟姐妹、表堂兄弟姐妹和叔伯姨妈,为彼此提供打工、创业的途径,同时有效庇护家族成员平稳度过发展期中的大多数惊涛骇浪,同时承担中国脆弱的社会保障体系外最关键的养老、育儿角色。

 

从我们有文字记载的历史算起,由各种非正式社会关系(主要就是家庭与血缘)组成的人脉网络就是我们经济最大的润滑剂与微观扩张基础。它帮助人与人之间产生必要的信任与互助,通过减小不确定性和简化交易过程来平滑和降低交易成本,帮助那些最能干和谦逊的人做成生意。

 

人类之所以群居,是因为群体以自身的粘性与能力加持能最大程度消除不确定性。儒家的宗法社会,礼乐,就是其规则与粘性之一。孔子说慎终怀远,民德归厚,孟子说乡人守望相助,疾病相扶持,都是在小群体为了存续而必须坚守的规范与道德。人在小群体中有相互有预期,因此才能够为小群体做出牺牲,为他人做出牺牲——自己为宗族而死,妻子孩子都不用操心,大家都会管。华夏文明未灭,跟这种宗族、宗法制度关系很大,哪怕在汉民族最悲戚的魏晋五胡乱华时代,北方豪族结堡自守,子弟兵战斗力爆表,也能护佑宗族和一方平安。

 

可以这么说,再怎么强调大家庭在中国过去40年经济奇迹中的作用,都不为过。没有了大家庭的隐性支撑与润滑,中国想象过去40年那样获得那么庞大和廉价数量的劳动力,几乎不可能。

 

但这个独立于政府体系外的家族互助网络,在被迅速打散和塌陷。

 

最新数据显示,中国家庭户均规模4.8已降到2.62:

 

当下与未来,两个最大的基本面

 

中国30-39岁人群拥有的堂表亲数量,则已从最高峰的57.29回落到51.38。

 

回到前面那张表亲数量图。如果我们假设未来中国生育率稳定在1.2(2020年是1.3,考虑到这几年巨大的二孩堆积效应,1.2的假设是理性且合理的),出生性别比例从118一路下降到2040年的107,人均寿命按73.5岁,则中国30-39岁人群拥有的堂表亲数量,30年后会一路崩落到仅仅7个左右的水平:

 

当下与未来,两个最大的基本面

 

到2050年,中国30岁以下年轻人拥有的表唐兄弟姐妹数量将只有现在年轻的五分之一,几乎六分之一的儿童就根本没有表唐兄妹,且60岁以上的老人中大约一半的人将只有一个在世子女。在中国的下一代人中,将会有相当数量的人,在从学校到工作到退休的一生中,根本就不会经历中国传统文化中不可或缺的大家庭。他们这一代人将是实际见证2500年儒家大家庭传统日渐式微的一代人。

 

这意味着大家庭从基础开始塌陷,中国传统的家族、宗族、亲属关系的大幅萎缩——这将极大增加个人闯荡社会的风险与成本,背负沉重的经济负担,使其无力迁徙与冒险创业。

 

而未来血亲数量的大幅下降,极大概率会严重削弱我们的经济增长潜能。随着家庭成员的减少,人们承担风险的能力与意愿都会大幅下降。人们会逃避创业,并减少和阻滞人口流动与阶层变动——推动中国城市化与经济增长的流动人口往往要依赖可靠的人脉去寻找工作和住所,如果在城里没有堂表亲提供住所,在农村没有亲(老)人帮忙照顾小孩,过去多年驱动城市化的引擎还能不能有效,大概率存疑。

 

再过一代人的时间,中国大概率会比现在更加富有。但老年人的迅速增长以及家庭的加速萎缩,会迫使我们在未来几十年把自己转变成一个庞大的社会福利国家——这意味着,我们能动用发展经济的资源会变少,而我们变富的速度也会越来越慢。

 

全社会上下,未来核心要做的唯二的两件事,一是鼓励生育,二,还是鼓励生育。

 

少弄那些没意义的抵制、争执、争吵,有用吗?有劲吗?

 

在座的诸位是幸运的,你们事实上享受了中国五千年历史上前无古人,大概率也后无来者的最大一波人口红利。你们赚到了钱,也是开始该反哺社会的时候。

 

未来诸位的钱,要么不投,要投,就请尽量投向能帮助、促进、润滑、刺激生育和人口增长的领域,坚决回避那些会增加生育焦虑、增加生养成本的领域。

 

当下与未来,两个最大的基本面

 

刚才课下讨论,还有人在问我能不能投K12教育?

 

你说能不能投?政府不找你,天下父母也联手会灭了你——躺平,根本不给你生,看你到哪找娃上补习班?

 

 

4

尾声

 

 

时间差不多了。我最后讲点题外话。

 

无论投资,还是做生意,赚快钱的时候肯定过去了。环球的含氧量都在变低。但这并不意味着我们不能做些力所能及的事,去让族群更强大,让生意更持久。

 

要求并不高,保持你的智慧,保持你的独立思考。

 

我很喜欢下面这段话,睿智而深刻,送给大家:

 

“当接触到挑战自己认知甚至颠覆三观的新观点和新事物时,首先不要急于否定,而是问问自己,你所知道的是不是大多数地球人都知道的?既然你和大多数人地球人获取信息的能力以及渠道没什么差别,你又是哪里来的自信去反驳平庸的你所不认可的东西呢?”

 

“就因为人多?在股市里,散户也人多,但他们总是输!”

 

从制度经济学角度,一个社会最可怕的长远危机是什么?

 

不是人口,不是科技。这些都只是后置结果,而非前置变量。

 

是人群的盲从。

 

所有社会个体如同工厂模块浇铸出来的机器,没有学习,没有思考,没有质疑。有的,只是服从与执行。同时这些机器会自觉集体攻击、扼杀任何独立思考与质疑。

 

这会把一个社会的创造力侵蚀消弭殆尽,并令整个社会丧失纠错能力,以致各种吃过的苦、受过的罪,会一茬一茬,一遍又一遍地轮回。

 

盲从,是一个群体最大的恶与堕落,也是他们自己能给到自己的最大的伤害。

 

当下与未来,两个最大的基本面

 

转自:https://mp.weixin.qq.com/s/CFnE-B5r1AKKPwaKkd0rvg

如何自学一个领域?

作者 l Lachel   编辑 l 易小飒 

来源 l L先生说(ID:lxianshengmiao

分享 l 粥左罗(ID:fangdushe520)

以前分享过不少跟学习相关的文章,但大都是集中于某个点,欠缺系统性。
今天这篇文章,想把「学习」这个问题,系统性地梳理一下。尤其适合新接触某个领域的同学,希望通过这篇文章帮助你快速入门。
超详细!如何自学一个领域?这篇文章讲透了
01
  框架:
初步了解一个领域
解决what、why、how三个问题
 
 
不少朋友问过我“刚刚入门一个领域,什么都不懂,怎么学?”,我的回答永远都是一样的:
 
一定要先从搭框架开始。
 
什么叫搭框架呢?
 
简而言之,就是给你的大脑一个铺垫,让它准备好,告诉它:在未来的日子里,我们将会大量吸收这个领域的知识,请做好理解和储存它们的准备。
 
举个例子:
 
当你撰写一份策划方案、报告时,你第一步是不是先有一个整体构思,列一个大纲:我先写什么,然后写什么,最后写什么——接下去才开始动手?
 
学习也是一样的。
 
如果缺少了框架,你所有获取的知识,就只是碎片信息而已。它们会孤零零地漂浮在记忆里,难以稳固存在,也难以被你所调用、组织、整合。
 
那么,如何搭建框架,令我们的学习更加体系化呢?
 
我建议的方法,是去搜寻这个领域相关的经典教材,大约3-5本,整体读一遍。无需一字不漏地精读,这太花时间了。大致翻一遍、通读一遍,就可以。
 
在这个过程中,你需要思考和回答这三个问题:
 
What:这个领域研究的对象是什么?有哪些主要流派和分支?有哪些常用的术语?
 
Why:这个领域存在的意义是什么?为了解决什么问题?现在进展到哪里?
 
How:这个领域的主要方法是什么?有哪些被广泛承认和应用的基本成果?
 
举个例子。

很多读者问「如何入门心理学」,我总会推荐几本大部头,像《心理学与生活》《社会心理学》《认知心理学》。
 
很多人看到就会开始打退堂鼓:“好几百页,什么时候才能看完,至少得看一年吧……”
 
其实你需要一页页把它们读完吗?当然不需要,也没有必要。
 
你先读一下前两章,对它们的起源有一个初步了解,再大致翻一下其他章节,了解心理学有哪些分支、分别研究什么、目前有了哪些主要成果;再着重看里面加粗的、或是章末拎出来的术语,大致理解它们的意思。就可以了。
 
再比如学习哲学,你没有必要一页页去翻完《大问题》《西方哲学导论》,你要做的是:
 
整体通读一遍,了解哲学的起源是人对自然的怀疑,主要关注的问题是本体论、认识论和伦理学,大体上可以划分为古希腊哲学、经院哲学、近代哲学、现代哲学,每个阶段都有什么特点——
 
比如近代哲学受文艺复兴和启蒙运动影响,思辨的核心从宗教转变为人文,开始引入成熟的逻辑学、科学,开始变得多元化等等,就可以了。
 
这个阶段,你要做的是什么呢?
 
是博观约取,在心里建立起一幅图景。不要把自己局限在「作者的脉络」里面,而是要以你心里的图景为主,缺什么就补什么。
 
这在心理学上面,就叫做「图式」。是我们认知和理解事物的基础。
 
比如:
你翻完了一本书,知道哲学研究的一个问题是认识论,但你不清楚什么叫认识论。
 
那就再翻到相关的部分多看几遍,或是把书里所有提到认识论的内容整合起来。不必细究每个概念是什么意思、每个结论是怎么推出来的,知道它大概指什么即可。
 
这阶段的首要任务,是把这幅图景补全。一旦成功建立图景,它在你未来的学习里,会起到举足轻重的作用。
 
02
  概念:
快速定位存在疑惑的点
搜索信息逐个击破
 
 
搭建完框架之后,你要做的,就是去把它精细化、补充完善。
 
在搭框架的过程里,你一定会碰到许多术语和概念,停留在「似懂非懂」的程度,很有可能存在偏差。到这个阶段,是时候把它们攻克掉了。
这个阶段,你要采取的方法,就不仅仅局限在经典教材里面了,而是广泛地搜索。
 
比如,学习哲学,你看到一个术语,叫「质料」,翻了一下,发现来自亚里士多德,但书里因为篇幅原因没有详述。那么,你就要自己去搜索这个术语,想办法把它弄通、弄透。
 
你可以去找亚里士多德的哲学导论、解读,翻到相关的部分,尝试着理解它准确的内涵;可以找书,可以在网上搜索,可以看公开课……不拘泥于一切形式。
 
你要做的是:快速定位到你存在疑惑的概念,用尽可能多的信息去攻克它。
 
在这个过程中,你多半又会碰到新的概念,那么,不妨继续顺藤摸瓜,循着「质料」出发,把相关的概念都纳入进来,一起理解清楚。
 
很多朋友常见的困惑是:我怎么控制这个「度」呢?怎么避免自己不断延伸、跳转,陷入新的「概念海洋」里面?
 
我的建议就是:
 
时时刻刻在心里自问一遍:“我是否能够用自己的话,把这个概念解释清楚?”如果可以,并且不涉及新的概念,那就说明是时候停下来了。
 
要时刻记住,自己出发的目的是什么。以目的为导向,给自己划定「边界」。
 
一旦你认为自己足够理解了一个概念,就将它放回到框架里,试着用自己的话去解释它,看是否通顺、合理。如果是,那很好,继续寻找下一个概念,以此类推。
 
慢慢的,当这些概念都弄通透了,你的整个框架,也就更加准确了。
 
03
  网络:
思考知识点之间的联系
形成自己的体系
 
 
到了这一步,你就算是正式开始入门了。
 
经过框架搭建和概念澄清,你会发现,之前看不懂的东西,似乎能够大致理解了;之前想当然的地方,原来是自己的理解不够准确;之前觉得模糊的问题,也似乎有了一些思路了。
 
那么,这个阶段,就可以带着下面这个问题,去阅读、听课、学习了。
 
什么问题呢?
 
始终带着「联系」的思想,时时刻刻思考:我学到了一个什么知识点?它可以跟别的什么知识点联系起来?如何构建这种联系?
 
这才是学习的核心:知识的本质永远不是信息本身,而是信息之间的联系。
 
正是这种联系,涌现出了超越单个信息点总和的「系统性」。
 
如何思考「联系」呢?
 
我自己常用的方式,是把每个知识点看作一个「知识元」,它有三个突触,分别是what、why和how。
 
  • What:话题,结构,类别
  • Why:原理,原因,起源
  • How:应用,解释,结果
举个例子。
 
你读到笛卡尔的「我思故我在」,你发现,他是在解释「自我」—— 那么,就可以把它跟「自我」联系起来。
 
过了一段时间,你也许会读到丹尼尔·丹内特的「多重草稿模型」,你会发现,他从脑科学的角度,提出了一种全新的「自我」观念。那么,同样把它跟「自我」联系起来。
 
这时,你会发现,围绕着「自我」,「我思故我在」和「多重草稿模型」产生了某种联系。
 
什么联系呢?显然,后者是在反驳前者,提出了一种非实体的、分布式的「自我」。那么,你就可以把这两者,建立起一种新的联系。
 
进一步,你还可以去思考:为什么他们的观点会有这样的差异呢?
 
如果你把笛卡尔放回之前建立的「框架」里,不难从宗教和本体论去找到他思想的根基:他的身心二元论,本质上是一种对宗教和科学的调和——那么,你又可以从why出发,去延伸下去。
 
同样,关于丹尼尔·丹内特的理论,从why出发,又可以延伸到脑科学、认知科学……
 
像这样,把浩瀚、繁多的概念节点组合起来,就能够组成一张网络。一张覆盖了种种学科、领域,从底层和表层,巨细靡遗的庞大网络。
 
这就是你的知识体系。
 
04
主题:
聚焦单个“局部网络”
加深认知
 
在上面的例子中,如果我们把目光,聚焦到「自我」这个概念上,会怎么样呢?
 
你也许会想到「我思故我在」,想到「多重草稿」,想到休谟的「自我不过是一连串印象的集合」……
 
这些被你嵌入知识网络中的节点,会全部显现出来,映入你的视野。
 
那么,你不妨去思考一下:
围绕着这个主题,这些不同的人、不同的观点,能够如何整合起来?他们的发展脉络是什么样的?彼此之间是什么样的关系?为何会产生这些差异点和共同点?
 
这就是「主题」——聚焦到我们庞大知识网络中的某个细节,去拎出一个「局部网络」
比如,「证实偏差」和「信息茧房」,是同一个领域的知识吗?其实不是。前者属于心理学,后者属于传播学。但没有关系。在「偏见」这个主题下面,它们就是互相补充的。
 
这就是「主题」的力量。
 
围绕一个主题,你可以把一个复杂的、抽象的过程提炼出来,变成一个新的节点;你同样可以把不同领域的知识点放到一起,按照它们内在的相似点和共性,去总结出一个新的、更高层次的结论。
 
举个例子。
 
如果说知识网络就像一栋房子,那么「主题」,就是你在这栋房子里面,可以进行的种种活动:聚会,工作,吃饭,看电影,等等。
 
这些种种主题,就构成了我们对世界的认知。
 
05
  迁移:
积累到一定程度之后
要学会应用
 
终于说到了迁移。
 
如果说前四点,都属于「知识的积累」;那么到这里,就正式进入了「知识的应用」
 
什么叫迁移?
 
它的意思其实就是:把旧的、已知的规律、模式,迁移到新的问题、情境上面。
 
这个阶段最重要的是什么呢?是理解和拆解外部情境的能力。
 
比如这个问题:博物馆着火了,你应该救一幅名画还是救一只猫?
 
当你看到这个问题时,就应该透过表象去思考它的实质:这个问题的实质是什么呢?是一个两难选择。
 
两难之处在哪里?一端是价值(名画),一端是道德(生命)。
 
那么,你或许就会发现:它的本质是什么呢?其实就是被说滥的「电车难题」的变体而已。
 
再进一步,当我们面临道德和价值的两难抉择时,应该如何思考呢?我们不妨求助于伦理学。
 
伦理学有两个观点,分别是目的论和义务论。前者着眼于事物的「效用」和「价值」,后者着眼于行为的动机和行为本身,只要出发点是善的,行为就是善的。
 
那么很显然,把伦理学的知识迁移过来,我们就会知道:这类两难问题并不存在答案。但透过这类问题,我们可以做的是,反思自己的立场和观念。
 
比如,你是一位功利主义者,那么不妨想一想:你真的能接受一条生命在你面前消失吗?你是一位义务论者,那么不妨想一想,你的行为真的是发自内心的吗?是否会受到外界的影响和干预?
 
当然,如果你用别的知识去迁移,那得出的可能又会是别的结论。
 
这就是一种迁移。具体来说,就是三步:
 
1.在前四步积累知识时,为知识预留出「接口」;
 
2.遇到新情境、新问题时,通过对问题进行拆解,找出它背后的核心;
 
3.把问题核心跟「接口」做对比,利用已有的知识,去应用到新问题上面。
 
同样,假如你在学习编程,最重要的一步是什么?
 
就是对你想实现的效果去「拆解」,把它们用计算机能够理解的流程、模式,描述出来,再对应到自己积累的编程知识,去「调用」已有的知识来解决问题。
 
假如我想在一群人里做一个「一对一匹配」的小活动,可以如何来拆解这个问题呢?
 
不妨思考,它最终的目的是什么?是使到相似的人尽可能地匹配上。那如何让电脑理解「相似」呢?我们知道,计算机是不理解语言的,它只能理解数字。所以,我们只能通过数字,来实现「相似」。
 
那么,一个简单的思路就是:
我们事先定义出若干个分类,再让参与活动的人做一个问卷,依据问卷结果,把他们分配到不同的分类里面(给每个人贴上一个1、2、3……的标签),再在同一个分类里随机选取。
 
进一步你会发现,这其实跟推荐系统的算法也是相似的。只不过推荐算法的输入,换成了各种各样的用户行为数据,以及算法复杂了很多。
 
简而言之,结合这几个例子,我们有哪些进行「迁移」的方法呢?
 
第一,类比。
 
可以去思考,这个问题跟哪些旧的问题、我们已知的问题相似,可以进行模仿和类推。
 
第二,黑箱。
 
不妨把这个问题视为一个黑箱,去思考:它的输入是什么,输出是什么。
 
第三,抽象。
 
不妨去掉具体情境,试着把它泛化、抽象化,提炼出它的结构和骨架,思考,它本质上是一个什么样的问题?
 
06
  模型:
真正的高手
都懂得构建自己的方法论
 
 
当你进入「迁移」的阶段之后,下一步,就是不断去练习。不断去寻找和发现新的情境,练习拆解和迁移。
 
在这个过程中,你也许会慢慢发现:
 
许多新问题之间,其实是存在一些共性的。它们虽然不同,但都可以用同一套知识模式去迁移解决。
 
这时,你就创造出了一个「模型」
 
这也是很多人缺乏的能力。
 
他们或许知道怎么迁移,也不缺乏练习量,但缺的是,从解决问题的经验中,进行高层次的总结归纳、抽象出「模型」的能力。
 
许多我们所说的「专家」和「聪明的人」,其实比我们厉害的,也正是这一点:他们的优势并不在于知识量的储备——那些都是静态的。他们的长处,是拥有大量的「模型」积累。
 
你会发现面对一个新问题,他们总是能够很快把它进行拆解,并调用相关的知识来解决——这就是模型起到的作用。
 
比如,我在第5点举的例子「救画还是救猫」中,用到的措辞是「这类问题」—— 这其实就是一种「模型」。
 
再比如,我以前经常提到「动力-阻力」模型。这个模型有哪一本书提到过吗?其实没有。它完全是我原创的。
 
但是,通过这个模型,我就可以把许多相关的知识浓缩起来,去处理一系列跟决策、行为、习惯、政策……等等相关的问题,更好地思考它们和解决它们。
 
我常常说,要努力去创造自己的方法论。模型就是自己的方法论。
 
你所有的知识,都是这个世界上已有的、已知的,唯有这些通过你的经验和实践,所得来的浓缩的「模型」,才是真正专属于你自己的财富。
 
你会发现,模型跟主题非常像。它们的区别是什么呢?
 
主题是对内的,是你围绕知识网络中某个节点,所展开的一系列「解释」;而模型是对外的,它是将主题迁移到一系列情境上面的结果。
 
简而言之,模型的本质就是主题+情境;主题聚焦于「为什么」,而模型聚焦于「怎么做」。
 
当你能够打通前五层,并且从模型的角度看待新问题、解决新问题的时候,你就已经进入「专业」的领域了。
 
07
  更新:
只有保持开放的心态
才能保持生命力
 
 
最后一层,是更新。
 
学无止境。
 
一个框架搭建起来,一个知识网络构建起来,它始终是「过去」。但人类的知识是在不断发展的。你必须时刻去更新它,去更新旧的节点,更新节点间的联系,才能让你的知识网络保持生命力。
 
如何更新呢?
 
这里,就是碎片信息的作用了。我会在生活中,去看各种各样的网站、博客、杂志,看一些不长的、专注于某个点的文章,并用最新的结论和观点,去覆盖和修正我的旧观点。
 
同样在生活中,如果我的旧观点受到挑战和质疑,我也会去想办法「寻找共识」,找到自己观点的不足和残缺点(正),把对方的观点整合起来(反),以达到一个更高层次的「合」。
 
这就是一个不断更新知识库、不断升级大脑操作系统的过程。
 
但很多人在这一层,也特别容易产生一个问题:封闭心态。
 
许多人会把不同的观点,当成是对自己的攻击,从而下意识地启动防卫机制,来维护自己的正确、稳定。
 
但是我们需要知道:只有开放的心态,能够让我们保持生命力。
 
当你的内心变得封闭,当你关上了接纳和共识的大门时,你才是真正地变「老」了。
 

08
不追求绝对正确
只追求比过去的自己更好
最后,简单提几个大家常见的问题。
 
1)有些人可能会觉得「我好像没有框架」。实际上,框架是一定存在的。你之所以觉得「没有框架」,只不过是因为它没有被你意识到而已。
 
但这样一来,就很容易造成什么结果呢?框架不完整,不准确,支离破碎。从而导致,你对新知识的接收和储存,也是破碎的。
 
所以,把自己的框架「显式化」,也是一种非常重要的能力。
 
2)这套理论适用于绝大多数的学习。只不过对不同领域的学习而言,每一层次的比重会有所不同。
 
比如,偏理论型的知识领域(比如哲学、历史、艺术),框架-概念-网络-主题的占比可能会重一些;而偏实践、技能型的知识领域(比如编程),框架-概念、迁移-模型的比重就会大一些。
 
3)大多数人的问题是什么呢?被动学习。
 
什么意思呢?打开一本书,从头看到尾,忙着去思考「作者讲了什么」「书的结构是什么」,全盘照收;听一门课,忙着把课程结构、脉络梳理出来,然后去记忆和背诵……
 
这样有用吗?也许有,但不大。你只是在复制别人的思想而已。学再多,你也只是在复述,很难真正能够「运用」。
 
不要觉得跟着别人走就是捷径。学习没有捷径。
 
4)很多人在前几层的时候会有困惑:可是,我怎么知道我搭的框架、理解的概念是否正确?万一错了呢?
 
其实不必过分担心。一方面,框架的搭建、概念的理解并非源于臆测——你是要查阅资料来攻克它们的。这一点可以保证不会出现方向性的偏差。
 
另一方面,这是一个稳健的系统。框架和概念共同组合,彼此作用,如果偏差过大,那么这个框架一定是有内在矛盾的,也很容易被我们所发现。
 
最后,无需追求100%的正确,这既不必要也不可能。关键是,要保持开放的心态,在后面的学习中,时刻去检查和更新自己的知识。这就可以了。
 
我们要追求的,永远不是「绝对正确」,而是「比过去的自己更好」。
 
最后,再回顾一下这张图。
超详细!如何自学一个领域?这篇文章讲透了
 
2021年已经过去一半了。希望能为你接下来的半年,注入一些动力。一起加油。
 

作者简介:Lachel,认知思维专家,多个跨界品牌创立者,虎嗅、36氪特约作者,致力于让更多人学会深度思考。公众号:L先生说(lxianshengmiao)。本文配图来源自《律政俏佳人》。

END

转自:https://mp.weixin.qq.com/s/6j-MGJOpS1XNk6UHAdIdPg

Shodan:互联网上最可怕的搜索引擎

Shodan 在百度百科里被给出了这么一句话介绍:Shodan 是互联网上最可怕的搜索引擎。

为什么呢?与谷歌、百度等搜索引擎爬取网页信息不同,Shodan 爬取的是互联网上所有设备的 IP 地址及其端口号。

而随着智能家电的普及,家家户户都有许多电器连接到互联网,这些设备存在被入侵的可能性,这是十分危险的。

说了这么多,给大家体验下 shodan,让你们有更切身的理解。打开 shodan.io,在搜索框输入 Hikvision-Webs :

Shodan:互联网上最可怕的搜索引擎

你会搜素到这个品牌的摄像头设备遍及全球的IP及其暴露的端口号:

Shodan:互联网上最可怕的搜索引擎

可以看到,这台机器暴露了 17、80、111、995、3128、5000、6000、20547 端口,黑客可以根据这些端口进行针对性的攻击。

不过也不需要过于担心,如果你的服务不存在漏洞,一般是无法攻入的。但有些端口号会暴露摄像头的 web 管理端,如下:

Shodan:互联网上最可怕的搜索引擎

那么黑客可能可以用暴力破解的方式,强行进入摄像头后台管理端,获取到实时的录像。

谨记这会侵犯别人的隐私权,是违法的行为,我们是遵纪守法的好公民所以知道它的原理和危害就足够。我们的目的是运用技术保护好个人隐私,如非必要不将摄像头接入互联网,一定要接入的话,不能使用容易被破解的弱口令。

Shodan Web 端非常好用,但如果我们有从 Python 搜索的需求怎么办?

没关系,Shodan 官方也提供了 Python SDK 包,下面就来讲讲这个 SDK 包的使用。

1.准备

开始之前,你要确保 Python 和 pip 已经成功安装在电脑上。

(可选1) 如果你用 Python 的目的是数据分析,可以直接安装 Anaconda,它内置了 Python 和 pip .

(可选2) 此外,推荐大家用 VSCode 编辑器,它有许多的优点

请选择以下任一种方式输入命令安装依赖
1. Windows 环境 打开 Cmd (开始-运行- CMD)。
2. MacOS 环境 打开 Terminal (command + 空格输入 Terminal)。
3. 如果你用的是 VSCode 编辑器 或 Pycharm,可以直接使用界面下方的 Terminal.

pip install shodan
2.注册账号获取API

使用 Shodan 必须注册账号,注册网址:https://account.shodan.io/register

Shodan:互联网上最可怕的搜索引擎

输入完相关信息,点击 CREATE 会跳转到个人账户页:

Shodan:互联网上最可怕的搜索引擎

此时 API Key 会显示你的API秘钥,请记录这个秘钥,后续会使用到这个秘钥去请求接口。

3.Shodan 基本调用

Shodan 本质上就是一个搜索引擎,你只需要输入搜索的关键词:

# 公众号:Python 实用宝典
# 2021-05-04
from shodan import Shodan

api = Shodan('你的API KEY')

def search_shodan(keyword):
    # 调用搜索接口
    result = api.search(keyword)

    # 显示所有IP
    for service in result['matches']:
            print(service['ip_str'])

search_shodan("Hikvision-Webs")

结果如下:

Shodan:互联网上最可怕的搜索引擎

可惜的是,普通 API 只能像这样搜索关键字,无法使用过滤条件如: Hikvision-Webs country:"US" 搜索美国境内的所有 Hikvision 网站管理端。

如果你想要使用过滤条件,Shodan 需要你升级API权限:

Shodan:互联网上最可怕的搜索引擎

挺贵的,不过还好是一次性支付,永久使用。

4. Shodan 高级使用

Shodan 的用处当然不仅仅是在黑客攻防中,它还能用于统计。如果你想要了解哪些国家的使用这款摄像头的数量最多,可以使用 Facets 特性。

# 公众号:Python 实用宝典
# 2021-05-04
from shodan import Shodan

api = Shodan('你的API KEY')
def try_facets(query):
    FACETS = [
        'org',
        'domain',
        'port',
        'asn',
        ('country', 3),
    ]

    FACET_TITLES = {
        'org': 'Top 5 Organizations',
        'domain': 'Top 5 Domains',
        'port': 'Top 5 Ports',
        'asn': 'Top 5 Autonomous Systems',
        'country': 'Top 3 Countries',
    }

    try:
        # 使用 count() 方法可以不需要升级API,且比 search 方法更快。
        result = api.count(query, facets=FACETS)

        print('Shodan Summary Information')
        print('Query: %s' % query)
        print('Total Results: %sn' % result['total'])

        # 显示每个要素的摘要
        for facet in result['facets']:
            print(FACET_TITLES[facet])

            for term in result['facets'][facet]:
                print('%s: %s' % (term['value'], term['count']))

    except Exception as e:
        print('Error: %s' % e)

try_facets("Hikvision-Webs")

得到结果如下:

Shodan:互联网上最可怕的搜索引擎

从 Top 3 Countries 中可以看到,这款摄像头使用数量排名前三的国家分别是:美国、日本和德国。

没想到吧,Shodan 居然还能用于产品分析。同样地原理,如果你把关键词改为 apache ,你可以知道目前哪些国家使用apache服务器数量最多,最普遍被使用的版本号是什么。

简而言之,Shodan 是一个非常强大的搜索引擎,它在好人手里,能被发挥出巨大的潜能。如果 Shodan 落入坏人之手的话,那真是一个可怕的东西。

为了避免受到不必要的攻击,请大家及时检查所有联网设备的管理端的密码,如果有使用默认密码及弱口令,立即进行密码的更改,以保证服务的安全。

– EOF –

转自:https://mp.weixin.qq.com/s/wQjXtZCj-uY3L63husLDTg

一位打工人、家长、内卷者眼中的“七普”

七普之后,真正的问题,是结构性问题。

一位打工人、家长、内卷者眼中的“七普”

如图所示,0—14岁人口的比重上升1.35个百分点;15—59岁人口的比重下降6.79个百分点;60岁及以上人口的比重上升5.44个百分点;65岁及以上人口的比重上升4.63个百分点。

 

概括来讲就是,孩子老人增加了,青年劳动力减少了,少子化程度超过老龄化,社会的养老压力骤至眼前。

 

回首过去,人口普查数据的结果将对我们如何评价相关的政策以及在这个过程中相关部门具体执行产生巨大的影响。以后怎么做,需要智慧。至少目前的数据来看,大家不愿意生孩子了。

也怪不得相关部门对七普的舆情管控如此上心。

 

一位打工人、家长、内卷者眼中的“七普”

想起我的一位朋友王某,作为来自农村80后。父母都是地地道道的农民,抱着养儿防老的心态,在生完大哥后,他父母又顶着计划生育政策偷偷生下了他,并东拼西凑借了一大笔钱交了计生罚款,本已拮据的生活在此后的好几年里更加雪上加霜。

 

父母想让小王早点完成九年义务教育出来打工赚钱养家——就像当时绝大多数农民和农名工子弟那样。好在小王争气,一路考上县城里最好的高中,并在不断的自我鞭策和学校衡水中学式的教育监督下,考上一所二线城市的一本大学,并在大学里谈了个本地女朋友小丽。

 

毕业后小王进了互联网大厂在当地的事业部,薪资不菲,就是996时常不着家,小丽在当地的一个事业单位工作,体面稳定,俩人顺理成章地谈婚论嫁,两人却因为彩礼的问题差点吵到分手。

 

小王没法只好回家跟父母商量,本以为自己读了大学找了个好工作摆脱了原生家庭,在父母面前曾一度有些趾高气昂,但父母却是佝偻着背,二话不说走进房里,把多年的积蓄交到他手上,小王眼睛有些湿润,半是感恩半是羞愧。

 

谢天谢地,女方父母真的只是看一下他诚意,只是希望小俩口在本地买一套房,除了彩礼还给他外,还会额外给他俩一笔钱用来凑首付,看着一年比一年涨得猛的房价,小王和小丽一咬牙一跺脚,把六个钱包都掏了一遍后,在当地一个不错的地段买了套房,公摊后面积虽然又小了不少,但终于有个家了也是欢喜的很。

 

漫长而又繁重的房贷压力,小俩口每月工资还完房贷和日常开销后便所剩无几了,想到将来还要生孩子以及教育投入,小王头都大了,以前还偶尔有旅游、电影、花束浪漫的小俩口彻底被柴米油盐淹没,因琐事吵架成为家常便饭。

 

在双方二老的催促下,俩人也开始造人计划并且生下了一个男孩,小丽还好,事业单位,产假管够,每月工资照发,但她进入私企的大学室友小美就没这么幸运了,怀孕后不久就被公司以绩效不达标优化。

 

在小王的奋斗下,薪资待遇有所上升,生活压力逐渐小了一些。更重要的是,自家房子才几年时间都快翻倍了,小王不禁窃喜。

 

但另一个室友在深圳却郁郁不得志,多年领着1万出头/月的工资。深圳2019年的平均月薪是10646元,而2020年,平均房价87957元/平。也就是说,一个普通的深圳打工人需要不吃不喝55年才能买得起一套80平的两居室,上一次跟他聊天还说想回老家,平时也经常转发“逃离北上广深”这样的微信爆文。

 

小王看着认真上网课的儿子,在夫妻俩无微不至的关照下,儿子没有喝过三鹿的奶粉、没有经历红黄蓝的幼儿园、没有打长春长生生物的疫苗…避开了一切他能避开的雷,如果说踩中了什么雷,那至少现在还没爆。小王眉目舒展,想着孩子将来会感谢自己对他成长过程中的呵护。

 

儿子是跨学区就读的,为了更好的教育资源,他和妻子疏通人脉打点关系,费了不少钱财力气,总算是把孩子送进了一个不错的学区,不过孩子班上同学内卷得太厉害了,各种动辄5位数价格的辅导班、游学班、兴趣班层出不穷,老师还要求父母批改学生家庭作业,并讲解错题,小王提出了质疑,当即就被班主任痛批这样的家长对小孩不负责任,群里一大堆家长支持班主任并点赞。

 

不久前,小王的父亲突发心肌梗塞,生命垂危。跟领导口头沟通请假后,小王失魂落魄回到家,却终究没见到父亲最后一面,听母亲讲,父亲患了癌症,无力负担治疗需要的巨额医药费,不想因为自己的病把小王现在美满的家庭拖入深渊…父亲死前还一直念叨小王,小王哭的像个孩子,脑子里不断闪过和父亲的点点滴滴,“可是你不在我身旁,托清风送去安康”。

 

料理完父亲的后事,小王不得不旷工几天。回到公司,发现工位上东西已被收好,桌上放着公司的辞退信,小王自知与这位领导有隙,再加上公司要清退一批“超龄”员工,借题发挥把自己排挤出公司而已,无奈诉诸劳动仲裁,拿到了一笔微薄的补偿。

 

工作没了,但房贷还得还,儿子上学各项支出也没法停,一波三折下小王托朋友介绍了一个国企工作,职级和薪资都明显比上一份工作低,但胜在稳定,他明白自己已经35岁了,在这个几乎每个招聘要求都会写上一条“低于35岁”的招聘市场,他只能接受。

 

日子慢慢地过,转眼间小王的儿子也上高中了,在老婆的“鸡娃”教育下,成绩也还可以。但2020年公司效益不佳,对边缘岗位进行裁员,想到孩子未来上学、结婚、买房要花的钱,小王一夜白头,变成了老王。

 

打拼了半生,到头来才发现自己那么努力,竟然是为了活成一个普通人。

 

有一阵他频繁从报纸上看到“我国老龄化形势严峻,人口出生率持续低迷”“ 高婚育成本使年轻人实现家庭变得更加困难”“单身经济站上风口,民政部数据显示,2018年我国单身成年人口高达2.4亿人。其中,超过7700万名成年人处于独居状态,预计到2021年这个数字将上升到9200万人…”“年轻人不想结婚生孩子了,天天宅在家里看动漫A片刷抖音追星”“养老金压力太大,要推动养老金入市投资,要延迟退休年龄和领取养老金年龄到65岁…”

 

跟他聊起这些问题时,老王总说,房价、教育、养老是最好的避孕药。年轻人结不结婚是自己的问题,多为自己想想,少整点所谓的大局观,如果你把买房和结婚两件事从人生的选项中剔除,人生无限宽广。

 

一位打工人、家长、内卷者眼中的“七普”

 

相关新闻:

 

  1. 民政部数据显示,2018年我国单身成年人口高达2.4亿人。其中,超过7700万名成年人处于独居状态,预计到2021年这个数字将上升到9200万人。
  2. 晚婚晚育、不婚问题加重中国养老负担,严重拖累国家财政、制约经济活力。中国将逐渐成为世界上养老负担最重的国家之一, 2019年有16个省份养老金入不敷出;黑龙江、青海、辽宁、吉林和内蒙古仍低于中央调剂制度规定的可支付月数警戒线。其中,黑龙江养老保险基金从2013年开始持续“入不敷出”,2016年累计结余转负,2019年缺口达433.7亿元。
  3. 作为严重老龄化国家,在应对人口快速老龄化,增强养老金制度的长期可持续性上,日本尝试了提高税收、延长工作年限、提高养老金领取年龄、控制给付、转向缴费确定型计划、保障养老基金投资收益等各类政策选项。改革阻力越大,越需要高层决心和相对中立的部门牵头。
  4. 农村老年人的自杀问题日益严重,预计未来10-20年内,中国农村老年人自杀潮将加剧。其中一部分原因非常地悲情又温暖,既然不能再为子女做贡献了,活着还有什么意思?尤其在农民之间存在激烈竞争的情况下。农民家庭之间竞争的压力最终由老年父母承担起来。(《农民自杀研究》,刘燕舞,武汉大学社会学系副教授,2014年)
  5. 放眼全国乡村,伴随着工业化城镇化进程的加快,农二代、农三代相继离土出村不回村,乡村留守老人的境况堪忧。2014年经济学人的一份调查指出,中国65—69岁的城市老年男性中,自杀率为每10万人中9.9人,而在70—74岁的农村男性中,每10万人口中有41.7人自杀。

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