日常学习之:vue + django + docker + heroku 对后端项目 / 前后端整体项目进行部署

news2024/11/19 3:46:58

文章目录

  • 使用 docker 在 heroku 上单独部署 vue 前端
  • 使用 docker 在 heroku 上单独部署 django 后端
    • 创建 heroku 项目
    • 构建 Dockerfile
    • 设置 settings.py
      • database
      • 静态文件管理
      • 安全设置
      • applicaiton & 中间件配置
    • 设置 requirements.txt
    • heroku container 部署应用
  • 前后端分别部署的优势和问题分别是什么
    • 好处
      • 解耦合
      • 灵活性
      • 安全性
      • 技术栈独立
    • 坏处
  • 使用 docker 在 heroku 上整体部署 vue + django
    • step1: 将 vue 的文件整个挪到 django 项目根目录底下
    • step2: 构建 dockerfile
    • step3: settings.py
    • step4: 更新 django url.py 并在 views.py 中呈现 Vue 应用
    • step5: heroku container 部署整体项目
    • step6: debug -- 让 django 能找到 vue 的静态资源
      • 调整 Vue 构建配置
      • 在 Django 中处理静态文件引用

使用 docker 在 heroku 上单独部署 vue 前端

  • 在 这篇文章 中我已经介绍了如何通过 docker 单独部署一个 vue 的前端项目
  • 在这个章节,我想按照下面的结构来给大家介绍:
    • 如何使用 docker 在 heroku 上单独部署 django 后端
    • 前后端分别部署的问题是什么
    • 如何将 vue + django 合并到一起通过 docker 构建一个完整的项目

使用 docker 在 heroku 上单独部署 django 后端

  • 我之前在讲如何使用 heroku 的 repository 部署 django 项目的 时较为详细地讲了如何创建 Procfileruntime.txt 以及里面写什么内容,
  • 但是我们使用 docker 来部署 django 项目,是使用 heroku container,因此不需要设定 Procfileruntime.txt 等文件,我们会将所有需要使用的指令都放在 Dockerfile 里面

创建 heroku 项目

  • 如果您还没有创建应用,可以使用以下命令创建:
    heroku create <应用名称>
    
  • 也可以用 heroku 的图形化界面创建

构建 Dockerfile

# 使用兼容 Django 项目的 Python 镜像
FROM --platform=linux/amd64 python:3.9

# 设置工作目录为 /app
WORKDIR /app

# 复制项目文件到容器中
COPY . /app

# 更新安装包
RUN apt-get update

# 安装项目依赖 (这里是我自己的 Linux 依赖,如果你不需要安装这种依赖,那就只需要 RUN pip install -r requirements.txt)
RUN apt-get install -y portaudio19-dev
RUN pip install -r requirements.txt 

# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# 运行 Django 服务,注意下面两个 # 修饰的部分是错误的写法
#CMD ["python", "manage.py", "runserver", "0.0.0.0:9000"]
#CMD ["python", "manage.py", "runserver", "0.0.0.0:$PORT"]
# CMD python manage.py runserver 0.0.0.0:$PORT
# CMD gunicorn <your project>.wsgi:application --bind 0.0.0.0:$PORT
CMD daphne -p $PORT -b 0.0.0.0 <your project>.asgi:application
  • 需要注意的是:
    在这里插入图片描述

  • 第一种错在不应该指定 9000 这个端口

    • 因为 heroku 在执行的时候会自动分配端口并生成一个 httpurl
    • 外面的服务需要访问你部署的系统时直接访问这个 url 就可以访问服务,而不需要访问 9000 端口
  • 第二种错在不应该使用 CMD [..., ..., ...] 这种形式:

    • CMD指令可以有两种不同的格式:shell 格式和 exec格式。这两种格式在处理环境变量时有所不同
    • 使用shell格式(如CMD python manage.py runserver 0.0.0.0:$PORT)时,命令会在shell中执行,这意味着可以进行环境变量展开。因此 $PORT 会被正确解析为 Heroku分配的端口值
    • 使用exec格式(如CMD ["python", "manage.py", "runserver", "0.0.0.0:$PORT"])时,命令不会在shell中执行,而是直接作为进程启动。这意味着不会进行环境变量展开,因此 $PORT 不会被解析为其实际值,而是被当作字符串$PORT 处理。
  • 第三种没有错,但是使用 daphne 或者 gunicorn 来启动服务器的方式在性能上更优秀。

  • 第四种,因为我的项目里面用了 websocket,而 gunicorn 不能处理这种情况,因此不行

  • 第五种是最好的,但是一定要注意,要指定 -b 0.0.0.0 如果不指定默认在 127.0.0.1,这样是不对的。同时,这里简单阐述一下为什么不直接用 python manage.py runserver 而用 daphne 这种专业的服务器,是因为:

    • Daphne 是一个 ASGI (Asynchronous Server Gateway Interface) 服务器,这意味着它能够处理异步请求,包括 WebSocket。这对于需要实时功能(如聊天应用、实时通知等)的应用程序来说非常重要。
      Django的 runserver 命令是一个 WSGI (Web Server Gateway Interface) 服务器,它 只能处理同步请求。虽然 Django 从3.0版本开始支持异步视图和中间件但runserver 并不是为处理高并发或实时通信设计的
    • Daphne 旨在作为生产级的服务器运行,提供更高的性能和可靠性。它能够更好地处理多个并发连接。 Django的 runserver 主要是为开发过程中的本地测试设计的。它没有针对性能和并发进行优化,不适合用于生产环境。
    • Daphne 和其他专用的ASGI/WSGI服务器如 Gunicorn、Uvicorn 等,通常包括用于生产环境的安全特性和最佳实践。 使用 Django的runserver 在生产环境中可能带来安全风险,因为它不是为暴露在公网上的环境设计的。
    • Daphne 支持 HTTP/2(虽然需要额外的配置),这可以提供更好的性能,特别是在处理大量静态内容或使用了大量API请求的应用程序中。Django 的 runserver 不支持 HTTP/2。
    • Daphne 可以更容易地与其他组件(如 Nginx、负载均衡器等)集成,提供更好的扩展性和部署灵活性。 直接使用 runserver 在复杂的生产环境中可能会受到限制。
  • 此外,我们指定了 FROM --platform=linux/amd64 python:3.9 是因为我用的是 macbook m1芯片,所以默认构建的 platform 和 docker 的 linux 是有冲突的,因此我需要在构建的时候指定 platform

  • docker 的默认根目录就是 /app,我们用 dockerfile 定义的一切,无非就是在 docker 的隔离环境中重建一个我们 local 的环境。因此 heroku 也可以直接依据 dockerfile 构建一个一模一样运行环境。

  • 安装项目依赖那里之所以 RUN apt-get install -y portaudio19-dev 是因为我的项目在 install requirements.txt 的时候报错,缺少一个头文件,而这个头文件依赖于我的这个 library,因此我需要 pip install 之前把这些依赖项先装了,按照自己的情况来

设置 settings.py

database

  • 如果你要再 heroku 上使用 database(比如 postgres)等,就要提前在 settings 里面配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

静态文件管理

STATIC_URL = '/static/'
# 这么写表明当用户使用 python manage.py collectstatic 时,所有的静态资源都会放到 staticfiles 文件夹里面
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# 这行其实没啥用,但相当于说,如果我有其他的 static 文件,我会放到 static 文件夹里面,而不会去占用 django 项目自己的静态文件夹 'staticfiles'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
  • 在Heroku上,静态文件的处理与本地环境不同。需要设置STATIC_ROOT和其他相关设置以确保静态文件能被正确收集和服务。

安全设置

  • 例如ALLOWED_HOSTS,以包括您的Heroku应用程序的域名:
ALLOWED_HOSTS = ['your-app-name.herokuapp.com']

这个我一般设置为:

ALLOWED_HOSTS = ['*']

applicaiton & 中间件配置

INSTALLED_APPS = [
    "daphne",   # asgi 应用,如果不设置,默认为 wsgi 应用
    "channels", # 它使服务器和客户端之间的双向通信成为可能,从而可以构建具有即时消息、通知和实时更新等功能的应用程序。
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "<your project name>",  # 只要你构建 django 项目,这个就要加进来
    "corsheaders"  # 解决跨域问题的
]

CORS_ALLOW_ALL_ORIGINS = True     # 跨域问题

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # cors problem
    'django.middleware.security.SecurityMiddleware',
    "whitenoise.middleware.WhiteNoiseMiddleware",  # 它可以帮助处理静态文件的服务和缓存。它允许你将静态文件(如 CSS、JavaScript 和图像文件)直接提供给最终用户,而无需通过额外的服务器或 CDN。
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

设置 requirements.txt

  • 上面配置的 application 的那些东西(daphne, channels 等),不要忘记在 requirements.txt 文件中进行定义,方便 dockerfile 执行的时候自动安装这些依赖,这里提供一个 requirements.txt 的样本:

    asgiref==3.4.1
    Django==4.0.1
    sqlparse==0.4.2
    tzdata==2023.3
    gunicorn==20.1.0
    django-heroku==0.3.1
    openai==0.28.1
    django-cors-headers
    django-redis
    daphne
    channels_redis
    whitenoise
    dj-database-url
    opencv-python-headless
    channels
    pysbd
    pyaudio
    agora_token_builder
    google-api-core==2.11.0
    google-auth==2.25.2
    google-cloud-core==2.4.1
    google-cloud-speech==2.19.0
    google-cloud-storage==2.14.0
    google-cloud-translate==3.13.0
    google-crc32c==1.5.0
    google-resumable-media==2.7.0
    googleapis-common-protos==1.59.0
    langchain==0.0.350
    langchain-community==0.0.3
    langchain-core==0.1.1
    nltk==3.7
    

heroku container 部署应用

heroku container:push web -a <heroku application name>
heroku container:release web -a <heroku application name>

前后端分别部署的优势和问题分别是什么

  • 现在我们已经讲完了 vue 和 django 分别通过 docker + heroku 的方式部署前端项目和后端项目的流程。那这里有个问题是,前后端分别部署这样的好处和坏处分别是什么呢?

好处

解耦合

前后端分离使得前端和后端可以独立开发和部署,这有助于提高团队的工作效率,同时降低了代码耦合性。
可以单独更新前端或后端,而不影响系统的其他部分。

灵活性

前后端分别部署允许您为每部分选择最适合的托管和缩放策略。例如,您可能会根据流量模式对前端和后端进行不同的缩放。

安全性

通过将前端和后端分开,您可以在网络架构上实现更细粒度的安全控制。例如,可以限制对后端服务的访问,只允许来自特定前端的请求。

技术栈独立

您可以自由选择或更改前端或后端的技术栈,而不需要对整个应用架构进行大规模的更改。
性能优化:

分别优化前端和后端的性能。例如,可以在内容交付网络 (CDN) 上托管静态前端资源,而后端则专注于API响应。

坏处

  • heroku 单独部署两个项目分别收费不划算
  • 跨域问题:前后端分别部署可能需要处理跨源资源共享 (CORS) 问题,这需要在后端正确配置以允许来自前端的请求。

使用 docker 在 heroku 上整体部署 vue + django

step1: 将 vue 的文件整个挪到 django 项目根目录底下

  • 注意,这时候 vue 不再需要 server.js 这个文件了,后面会详细说为什么。

  • vue 项目中的 Dockerfile 也可以删除,因为我们也不单独基于 vue 来构建项目了

  • 移动后的文件目录如下,当然你也可以不这么放,但是你要能够保证按照后面的步骤能够准确对应到你放前端代码的位置,因为后面的操作比较细节,或者你可以等你后面的步骤熟练了再自己做调整。

    .
    ├── Dockerfile
    ├── db.sqlite3
    ├── google_credential.json
    ├── manage.py
    ├── readme.md
    ├── requirements.txt
    ├── staticfiles
    │   ├── admin
    │   └── staticfiles.json
    ├── validation_backend
    │   ├── __init__.py
    │   ├── __pycache__
    │   ├── admin.py
    │   ├── asgi.py
    │   ├── consumers.py
    │   ├── migrations
    │   ├── models.py
    │   ├── routing.py
    │   ├── settings.py
    │   ├── tools.py
    │   ├── urls.py
    │   ├── views.py
    │   └── wsgi.py
    └── validation_front
        ├── README.md
        ├── babel.config.js
        ├── img.png
        ├── jsconfig.json
        ├── node_modules
        ├── package-lock.json
        ├── package.json
        ├── public
        ├── src
        ├── todo.md
        ├── vue.config.js
    

step2: 构建 dockerfile

# 第一阶段:构建 Vue.js 应用
FROM --platform=linux/amd64 node:14 as vue-build-stage

# 设置 Vue.js 项目的工作目录,这样设置是为了 docker 里面的目录和 local 真实的目录路径保持一致
WORKDIR /app/validation_front

# 拷贝 Vue.js 项目的 package.json 和 package-lock.json
COPY validation_front/package*.json ./

# 安装 Vue.js 项目依赖
RUN npm install

# 拷贝 Vue.js 项目文件
COPY validation_front/ .

# 构建 Vue.js 应用
RUN npm run build

# 第二阶段:构建 Django 应用
# 使用兼容 Django 项目的 Python 镜像
FROM --platform=linux/amd64 python:3.9

RUN apt-get update
# 安装项目依赖
RUN apt-get install -y portaudio19-dev

# 设置工作目录为 /app
WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt


# 复制剩余的 Django 项目文件到容器中,这样做是为了将环境安装部分放在上一个docker 的层,避免每次 push docker 都重新安装 package
COPY . .

# 判断 app 里面是不是有 static 和 templates,没有就创建
RUN test -d /app/templates || mkdir /app/templates
RUN test -d /app/static || mkdir /app/static

# 从 Vue.js 构建阶段拷贝静态文件到 Django 的静态文件目录
COPY --from=vue-build-stage /app/validation_front/dist /app/static/

# 将 Vue 的 index.html 移动到 Django 的模板目录
COPY --from=vue-build-stage /app/validation_front/dist/index.html /app/templates/



# 在 docker 内运行的端口(暴露端口)
EXPOSE 9000

# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# 运行 Django 服务
# CMD python manage.py runserver 0.0.0.0:$PORT
CMD daphne -p $PORT -b 0.0.0.0 validation_backend.asgi:application
  • 我认为上面步骤中最重要的就是要通过 build 将 vue 的项目打包,打包好的内容 vue 会自动放到 validation_front/dist 文件夹里面,大约是这个样子(我这个图是本地 build 了一下给大家展示,真正在 docker 里面的和这个是一样的,只不过不可见):
    在这里插入图片描述

  • 然后我们需要在 docker 里面把 dist 这个文件夹里面所有的内容拷贝到 django 项目的根目录下面的 static 文件夹里面去(dockerfile 中已经定义了这样的操作)。将 vue 中 dist 的内容 copy 到 django static 路径的原因是:如果前后端放在一起部署。那么 vue 项目就不再需要一个单独的 server.js 而是把 django 项目直接当成 backend,因此,当有 request 进来的时候,django 需要结合 vue 已经写好的那些页面(静态资源)来给 user 返回内容让浏览器解析。

  • 因此我们 需要让 django 和 vue 的东西适配起来,也就是让 django 能够定位到 vue 的静态资源。这个我们后面会着重讲

  • 此外,如果你关注上面的 dockerfile 你就会发现

上文中有两处:

  • 第一阶段中:COPY validation_front/package*.json ./ 之后又进行了 COPY validation_front/ .
  • 第二阶段中:COPY requirements.txt . 之后又进行了 COPY . .
    上述两个操作中的第二步看上去都似乎包含了第一步的操作,那么这样做的道理是什么呢?
  • 这是因为:
    • 在 Dockerfile 中,这种 seemingly redundant 的 COPY 操作实际上是一种优化技术,称为 Docker 层的缓存利用。每个 RUN, COPY,ADD 指令在 Docker 构建过程中都会创建一个新层。Docker 使用这些层来缓存构建步骤,这样在后续构建中,如果没有检测到任何变化,它就可以重用现有的层。这大大加速了构建过程。

    • 分步骤 COPY 的目的:

      • COPY validation_front/package*.json ./COPY requirements.txt . 这些命令是为了首先复制 package.jsonpackage-lock.json(对于 Vue.js 应用),以及 requirements.txt(对于 Django 应用)。 这样做的好处是,只要这些文件未发生变化,Docker 就可以使用现有的缓存层来重新安装依赖项,而无需从头开始。这可以节省大量时间,因为依赖项安装通常是构建过程中最耗时的部分之一。

step3: settings.py

  • 因为我们需要用 django 来找到 vue 的静态资源(css, js, index.html)之后整合到一起发到前端,我们需要一个 templates 文件夹来存放 index.html,所以在 settings.py 中设置好
    # 模板设置
    TEMPLATES = [
        {
            # ...
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            # ...
        },
    ]
    

step4: 更新 django url.py 并在 views.py 中呈现 Vue 应用

  • 在 Django 的 urls.py 中添加一个路由来指向这个视图。

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('', views.index),
        # 其他路由...
    ]
    
  • 在 views.py 中增加如下内容:

    from django.shortcuts import render
    
    def index(request):
        return render(request, 'index.html')
    
  • 上述增添的项目表示,当有人访问服务器地址的时候,会得到基于 vue 来构建的静态页面 index.html,而 django 所做的处理将会嵌入在静态页面 index.html 中,这也就是为什么你访问部署后的项目能够看到前端页面。

  • 在 dockerfile 中我们也指定了 dist/index.html 会被复制到 django 的 static/index.html,而 render(request, 'index.html') 也正是通过访问预先定义 static 文件夹来找这个 index.html

step5: heroku container 部署整体项目

heroku container:push web -a <heroku application name>
heroku container:release web -a <heroku application name>

step6: debug – 让 django 能找到 vue 的静态资源

  • 按说完成上述的操作,前后端的相互协作应该已经没问题了,但是当我部署完成并打开 heroku 的 app 傻眼了,经过我的测试,后端正常运行了,但是前端的页面没有显示
    在这里插入图片描述

  • 这个问题我闹了好久,最后发现是 django 的 静态路径vue 默认的导出设置不匹配导致的

  • 这里我们再强调一下 settings.py 中的这部分内容

    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
    STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
    
  • 首先 django 项目的默认静态资源路径定义为 base_dir/staticfiles ,也就是,当你执行 python manage.py collectstatic 命令的时候, django 项目本身的哪些 css, js, index.html (注意,这不是 vue 的静态资源)会自动加载到 base_dir/staticfiles 里面,但由于我们用 vue 构造的前端,所以我们自然是需要 vue 自己 build 出来的静态资源而不是 django 自己的静态资源,因此我们需要区分这两部分静态资源。而我们通过 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] 定义了存放其他静态资源(这里可以是 vue 的静态资源)的文件夹

  • 我通过找问题,发现问题出在 vue 生成的 index.html

    <!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible"
    content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link
    rel="icon" href="/favicon.ico"><title>validation_front</title><script defer="defer"
     src="/js/chunk-vendors.0804f4a0.js"></script><script defer="defer" 
     src="/js/app.893a5f38.js"></script><link href="/css/chunk-vendors.10dd4e95.css" rel="stylesheet"><link href="/css/app.a285b80a.css" rel="stylesheet"></head>
     <body><noscript><strong>We're sorry but validation_front doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
     <div id="app"></div></body></html>
    
  • 可以看到这里面加载资源的 src 都是直接 /js/... 或者 /css/...

  • 如果我们在 docker 中部署好了之后,也就是说他会直接从 docker 的根路径 /app/... 去找是否有 jscss 文件夹,但是很显然他找不到,因为现在这些文件夹都在 /app/static 里面

  • 在 Django 项目中,静态文件通常通过 STATIC_URL 设置的路径来提供。默认情况下,STATIC_URL 被设置为 /static/。这意味着如果 Vue 应用构建生成的静态文件路径是 /css/somefile.css,实际上 Django 会期望它们位于 /static/css/somefile.css

  • 那么问题就来了,如何让这个矛盾解决呢?其实有几种方案

调整 Vue 构建配置

  • 修改 Vue 项目的构建配置,使其生成的静态资源路径与 Django 的 STATIC_URL 一致。这通常在 Vue 项目的 vue.config.js 文件中配置。例如,您可以添加一个公共路径前缀 /static/

    module.exports = {
        publicPath: process.env.NODE_ENV === 'production'
            ? '/static/'
            : '/'
    };
    
  • 这样,构建后的静态资源路径将与 Django 预期的路径一致。

  • 我最终的 vue.config.js 文件是:

    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
      transpileDependencies: true,
      publicPath: process.env.NODE_ENV === 'production' ? '/static/' : '/'
    })
    
    
  • 在这个配置中:

    • publicPath 被设置为 /static/ 当应用处于生产模式(process.env.NODE_ENV === 'production')
      对于开发模式,publicPath 保持为根路径 /,以便于本地开发时资源可以被正确加载。
      这样,当构建生产版本的 Vue 应用时(通常通过运行 npm run build),所有静态资源(CSS、JavaScript 等)将会在它们的 URL 前加上 /static/ 前缀。然后,当这些文件被部署到与 Django 集成的环境中时,这些路径将与 Django 预期的静态文件路径一致。

那怎么判断是生产模式还是本地模式呢?

  • 在大多数 JavaScript 和 Node.js 环境中,包括 Vue.js 项目,您可以通过检查 process.env.NODE_ENV 环境变量的值来判断当前是生产模式(production)还是开发模式(development)。这个环境变量通常在不同的构建命令或环境中被设置。
    • 开发模式:通常在运行本地开发服务器时(例如,当您使用 npm run servevue-cli-service serve),NODE_ENV 被设置为 "development"。这是默认的模式,用于本地开发和调试。
    • 生产模式:当您构建应用以准备部署到生产环境时(例如,使用 npm run buildvue-cli-service build),NODE_ENV 被设置为 "production"。在生产模式下,Vue 会启用各种优化,包括压缩、最小化和更有效的代码分割

在 Django 中处理静态文件引用

  • 使用 Django 的模板语言动态生成静态文件路径。可以在 index.html 中使用 Django 的 {% static %} 模板标签来正确引用静态文件。不过,这可能需要手动编辑 Vue 构建出的 index.html 文件, 很显然我们使用 dockerfile 来流程化构建,因此这种手动改的方式并不适用

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解读BEVFormer,新一代自动驾驶视觉工作的基石

文章出处 BEVFormer这篇文章很有划时代的意义&#xff0c;改变了许多视觉领域工作的pipeline[2203.17270] BEVFormer: Learning Birds-Eye-View Representation from Multi-Camera Images via Spatiotemporal Transformers (arxiv.org)https://arxiv.org/abs/2203.17270 BEV …

深入理解C语言(3):自定义类型详解

文章主题&#xff1a;结构体类型详解&#x1f30f;所属专栏&#xff1a;深入理解C语言&#x1f4d4;作者简介&#xff1a;更新有关深入理解C语言知识的博主一枚&#xff0c;记录分享自己对C语言的深入解读。&#x1f606;个人主页&#xff1a;[₽]的个人主页&#x1f3c4;&…

使用毫米波雷达传感器的功能安全兼容系统设计指南1(TI文档)

摘要 功能安全标准规定了在系统中实施安全的要求&#xff0c;并有助于概括该系统要达到的安全目标。包括功能安全的系统设计不仅要降低操作不当的风险&#xff0c;还要检测故障并将其影响降到最低。随着汽车和工业系统的自主性越来越强&#xff0c;严格的功能安全要求被强制执行…

docker中安装seata,以nacos为配置中心

docker中安装seata&#xff0c;以nacos为配置中心 一、环境二、拉取seata镜像1、查看seata有哪些镜像2、查看原来有没有seata镜像3、拉取最新版本4、拉取指定版本 三、配置seata1、创建seata相关的数据库2、创建seata配置文件目录3、启动seata容器4、复制seata容器下的配置文件…

leetcode刷题(剑指offer) 509.斐波那契数

509.斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n…

读书笔记:九句耐人寻味的话

“情商一定是让别人和自己都舒服。如果让别人舒服&#xff0c;自己却很痛苦&#xff0c;那不叫情商&#xff0c;叫智障。” Emotional intelligence must be about making both others and oneself comfortable. If it makes others comfortable but oneself miserable, thats …

盛最多水的容器[中等]

一、题目 给定一个长度为n的整数数组height。有n条垂线&#xff0c;第i条线的两个端点是(i, 0)和(i, height[i])。找出其中的两条线&#xff0c;使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。也就是求x轴与y轴的面积。 说明&#xff1a;你不能倾…

Threejs 展示——obj 格式模型导入

文章目录 需求分析1. HTML版本2. Vue 版本 需求 导入obj 格式的模型数据 分析 .obj&#xff1a;Wavefront OBJ 格式&#xff0c;是一种广泛使用的三维模型文件格式。预览 .obj格式文件的软件可点此下载需要准备两种格式的数据&#xff0c;如下所示 1. HTML版本 html <!…

电脑和手机连接酒店的wifi,网络不通导致charles无法抓手机的包

查看苹果手机&#xff0c;连wifi后的ip地址 电脑去ping 手机的ip地址&#xff0c;发现ping不通 解决方案&#xff1a; 应该是酒店wifi的问题&#xff0c;让朋友开个手机热点&#xff0c;电脑和我的手机都连这个热点&#xff0c;就可以抓包了

13.Golang中面向对象的多态及基本要素

目录 概述实践多态实现代码结果 基本要素 结束 概述 Golang中类的表示与封装继承 用这种方式并不能实现多态 需要结合 interface 来实现。 实践 多态实现 代码 package mainimport "fmt"type AnimalIF interface {// 这两个方法&#xff0c;实现类&#xff0c;必…

python笔记10

1、继承 继承是面向对象编程中的一个重要概念&#xff0c;它允许一个类&#xff08;子类&#xff09;继承另一个类&#xff08;父类&#xff09;的属性和方法。通过继承&#xff0c;子类可以重用父类的代码&#xff0c;并且有机会添加新的属性和方法&#xff0c;或者重写父类的…

【C++】一题掌握空指针

今天看见一道面试题&#xff0c;比较有意思&#xff0c;这一分享出来&#xff1a; 1.下面程序能编译通过吗&#xff1f; 2.下面程序会崩溃吗&#xff1f;在哪里崩溃 class A {public:void PrintA(){cout<<_a<<endl;}void Show(){cout<<"Show()"&…

.ui文件相关

目录 ui类生成过程&#xff1a; 提问&#xff1a; 等以后自己熟练了用代码写这些样式内容&#xff0c;尽量用代码写&#xff0c;原因很简单&#xff1a; 用代码写的可以直接修改代码&#xff0c;但是在设计界面修改的东西&#xff0c;电脑没有QC这玩意&#xff0c;还真不好改…

ChatGPT4 比 ChatGPT3.5 强在了那里?

刚开始的时候我还在纠结&#xff0c;一个月20 刀的ChatGPT4 &#xff0c;到底值不值这个价钱&#xff1f;使用过后发现&#xff0c;诶嘛真香。因为 GPT4 比 GPT3.5 多了太多功能&#xff0c;特别是识图能力&#xff0c;用好的话效率翻倍。 1. 看图写代码 ChatGPT4 相比 ChatG…

【极数系列】Flink集成DataSource读取集合数据(07)

文章目录 01 引言02 简介概述03 基于集合读取数据3.1 集合创建数据流3.2 迭代器创建数据流3.3 给定对象创建数据流3.4 迭代并行器创建数据流3.5 基于时间间隔创建数据流3.6 自定义数据流 04 源码实战demo4.1 pom.xml依赖4.2 创建集合数据流作业4.3 运行结果日志 01 引言 源码地…

用ASM HEMT模型提取GaN器件的参数

标题&#xff1a;Physics-Based Multi-Bias RF Large-Signal GaNHEMT Modeling and Parameter Extraction Flow (JEDS 17年) 模型描述 该模型的核心是对表面势&#xff08;ψ&#xff09;及其随施加的栅极电压&#xff08;Vg&#xff09;和漏极电压&#xff08;Vd&#xff09…

【数据结构1-3】集合

有时候&#xff0c;我们并不关心数据之间的前后关系&#xff0c;也不关心数据的层次关系。一些确定元素只是单纯的聚集在一起&#xff0c;这样的元素聚集体被称为集合。 当希望知道某个数据是否存在一个集合中&#xff0c;或者两个元素是否在同一个集合中时&#xff0c;就需要使…

JVM系列——对象管理

JVM对象分布 对象头 第一类是用于存储对象自身的运行时数据&#xff0c;如哈希码&#xff08;HashCode&#xff09;、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等 另外一部分是类型指针&#xff0c;即对象指向它的类型元数据的指针&#xff0c;Java 虚…

敲黑板啦!CSGO游戏搬砖项目操作注意事项

CSGO游戏搬砖项目怎么赚钱的&#xff0c;利润在哪&#xff1f; 1.两个平台之间币种不一样&#xff0c;就存在一个汇率差&#xff0c;两平台装备价格也不一样&#xff0c;汇率差-价格差利润。 CSGO游戏搬砖项目具体有哪些操作步骤&#xff1f; 1、准备一台电脑&#xff0c;配置…

Git学习,基础,安装,配置,笔记总结

Git安装与常用命令 本教程里的git命令例子都是在Git Bash中演示的,会用到一些基本的linux命令,在此为大家提前列举: ls/ll 查看当前目录 cat 查看文件内容 touch 创建文件 vi vi编辑器(使用vi编辑器是为了方便展示效果,学员可以记事本、editPlus、notPad++等其它编 辑…