Django 基础入门教程(第四篇):Form组件、Auth认证、Cookie/Session与中间件

作者:冉成未来日期:2026/3/20

在前三篇中,我们完成了 Django 的环境搭建、模型设计、视图模板、Admin 后台以及 ORM 高级查询。本篇将带你深入 Django 的用户交互与安全机制:Form 组件、Auth 认证系统、Cookie/Session 和中间件。学完本篇,你将能够处理复杂的表单验证、实现用户注册登录、管理用户会话,并理解 Django 的请求/响应处理流程。


第一部分:Django Form 组件

1.1 为什么需要 Form 组件?

在 Web 开发中,处理表单是常见且复杂的任务。你需要:

  • 渲染 HTML 表单字段
  • 验证用户输入(格式、长度、唯一性等)
  • 保留用户上次输入的内容
  • 显示友好的错误提示

Django 的 Form 组件正是为了解决这些问题而设计的。它提供了:

  1. 自动生成 HTML 标签:减少模板中的重复代码
  2. 数据校验:内置多种验证规则
  3. 保留上次输入:出错时用户无需重新填写
  4. 错误提示:自动关联到对应字段

1.2 定义第一个 Form 类

在应用目录下创建 forms.py,定义一个简单的联系人表单:

1# blog/forms.py
2from django import forms
3
4class ContactForm(forms.Form):
5    name = forms.CharField(
6        label='您的姓名',
7        max_length=50,
8        required=True,
9        error_messages={'required': '请输入姓名'}
10    )
11    email = forms.EmailField(
12        label='电子邮箱',
13        required=True,
14        error_messages={'required': '请输入邮箱', 'invalid': '请输入有效邮箱'}
15    )
16    message = forms.CharField(
17        label='留言内容',
18        widget=forms.Textarea(attrs={'rows': 4, 'class': 'form-control'}),
19        max_length=500
20    )
21

每个字段对应 HTML 表单的一个 <input> 元素。widget 参数可以控制渲染成哪种 HTML 控件以及添加 CSS 类。

1.3 在视图中使用表单

表单的典型处理流程是:GET 请求显示空表单,POST 请求验证并处理数据。

1# blog/views.py
2from django.shortcuts import render, redirect
3from .forms import ContactForm
4
5def contact(request):
6    if request.method == 'POST':
7        # 使用 POST 数据实例化表单(绑定表单)
8        form = ContactForm(request.POST)
9        
10        # 验证数据
11        if form.is_valid():
12            # 获取清洗后的数据
13            name = form.cleaned_data['name']
14            email = form.cleaned_data['email']
15            message = form.cleaned_data['message']
16            
17            # 处理数据(如发送邮件、保存到数据库)
18            # send_mail(...)  Contact.objects.create(...)
19            
20            return redirect('contact_success')  # 重定向到成功页面
21    else:
22        # GET 请求:创建空表单(未绑定)
23        form = ContactForm()
24    
25    return render(request, 'blog/contact.html', {'form': form})
26

关键点:

  • form.is_valid() 执行所有字段的验证规则
  • form.cleaned_data 是验证通过后的“干净”数据字典
  • 未绑定的表单(无数据)和绑定的表单(有数据)使用同一个模板

1.4 在模板中渲染表单

1{# blog/templates/blog/contact.html #}
2{% extends "base.html" %}
3
4{% block content %}
5<h2>联系我们</h2>
6<form method="post">
7    {% csrf_token %}
8    
9    {# 渲染所有字段的默认样式 #}
10    {{ form.as_p }}
11    
12    {# 或者手动渲染每个字段,以便更灵活控制 #}
13    {% comment %}
14    <div>
15        {{ form.name.label_tag }}
16        {{ form.name }}
17        {{ form.name.errors }}
18    </div>
19    {% endcomment %}
20    
21    <button type="submit" class="btn btn-primary">提交</button>
22</form>
23{% endblock %}
24

Django 提供了多种渲染方式:as_p()(段落)、as_table()(表格)、as_ul()(列表)。错误信息会自动显示在对应字段旁边。

1.5 ModelForm:从模型生成表单

如果表单与模型字段基本一致,使用 ModelForm 可以大大减少代码:

1# blog/forms.py
2from .models import Article
3
4class ArticleForm(forms.ModelForm):
5    class Meta:
6        model = Article
7        fields = ['title', 'content', 'category', 'tags']  #  '__all__'
8        widgets = {
9            'content': forms.Textarea(attrs={'rows': 5}),
10        }
11        labels = {
12            'title': '文章标题',
13            'content': '正文',
14        }
15

在视图中,可以直接调用 form.save() 保存到数据库:

1def create_article(request):
2    if request.method == 'POST':
3        form = ArticleForm(request.POST)
4        if form.is_valid():
5            form.save()  # 自动创建并保存 Article 实例
6            return redirect('article_list')
7    else:
8        form = ArticleForm()
9    return render(request, 'blog/article_form.html', {'form': form})
10

1.6 表单验证进阶

Django 支持多层次的验证:

1. 字段级验证:定义 clean_字段名() 方法

1class ContactForm(forms.Form):
2    # ...
3    
4    def clean_name(self):
5        name = self.cleaned_data.get('name')
6        if 'admin' in name.lower():
7            raise forms.ValidationError('姓名不能包含 "admin"')
8        return name
9

2. 表单级验证:定义 clean() 方法,用于跨字段验证

1def clean(self):
2    cleaned_data = super().clean()
3    name = cleaned_data.get('name')
4    email = cleaned_data.get('email')
5    
6    # 示例:禁止某些用户名和邮箱组合
7    if name and email and 'test' in name and 'test.com' in email:
8        raise forms.ValidationError('测试用户不能使用测试邮箱')
9    
10    return cleaned_data
11

第二部分:Django Auth 认证系统

Django 内置了一个功能完善的认证系统,位于 django.contrib.auth。它处理用户账户、组、权限和会话。

2.1 User 模型基础

Django 默认的 User 模型包含以下核心字段:

  • username:用户名(必填)
  • password:密码(哈希存储)
  • email:邮箱
  • first_name / last_name:姓名
  • is_active:是否激活
  • is_staff:是否可登录 Admin
  • is_superuser:是否超级用户
  • date_joined:注册日期

2.2 创建用户

方式一:命令行创建超级用户

1python manage.py createsuperuser
2

方式二:编程方式创建普通用户

1from django.contrib.auth.models import User
2
3# 创建用户(密码会自动哈希)
4user = User.objects.create_user(
5    username='john',
6    email='john@example.com',
7    password='johnpassword'
8)
9user.last_name = 'Lennon'
10user.save()
11
12# 创建超级用户
13superuser = User.objects.create_superuser(
14    username='admin',
15    email='admin@example.com',
16    password='adminpass'
17)
18

重要:永远不要直接设置 password 属性,必须使用 set_password()create_user()

2.3 用户认证与登录

Django 提供了 authenticate()login() 函数来处理用户认证。

1# blog/views.py
2from django.contrib.auth import authenticate, login, logout
3from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
4from django.shortcuts import render, redirect
5
6def user_login(request):
7    if request.method == 'POST':
8        form = AuthenticationForm(request, data=request.POST)
9        if form.is_valid():
10            username = form.cleaned_data.get('username')
11            password = form.cleaned_data.get('password')
12            user = authenticate(request, username=username, password=password)
13            if user is not None:
14                login(request, user)
15                return redirect('article_list')
16    else:
17        form = AuthenticationForm()
18    return render(request, 'blog/login.html', {'form': form})
19
20def user_logout(request):
21    logout(request)
22    return redirect('article_list')
23

authenticate() 验证凭据,成功则返回 User 对象;login() 将用户 ID 存入 session。

2.4 注册新用户

可以使用 Django 内置的 UserCreationForm

1from django.contrib.auth.forms import UserCreationForm
2
3def register(request):
4    if request.method == 'POST':
5        form = UserCreationForm(request.POST)
6        if form.is_valid():
7            user = form.save()  # 创建用户
8            login(request, user)  # 自动登录
9            return redirect('article_list')
10    else:
11        form = UserCreationForm()
12    return render(request, 'blog/register.html', {'form': form})
13

模板 register.html 与普通表单类似。

2.5 权限系统

Django 为每个模型自动创建四个权限:添加、修改、删除、查看。

检查权限

1# 在视图或模板中
2if request.user.has_perm('blog.add_article'):
3    # 用户有添加文章的权限
4    pass
5
6# 在模板中
7{% if perms.blog.change_article %}
8    <a href="{% url 'edit_article' article.id %}">编辑</a>
9{% endif %}
10

自定义权限:在模型的 Meta 类中定义

1class Article(models.Model):
2    # ...
3    class Meta:
4        permissions = [
5            ("can_publish_article", "可以发布文章"),
6            ("can_review_article", "可以审核文章"),
7        ]
8

2.6 在视图中限制访问

Django 提供了多种装饰器和混入类来限制访问:

1from django.contrib.auth.decorators import login_required
2from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
3from django.views.generic import CreateView
4
5# 函数视图
6@login_required
7def my_view(request):
8    return render(request, 'blog/profile.html')
9
10# 类视图
11class ArticleCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
12    model = Article
13    form_class = ArticleForm
14    permission_required = 'blog.add_article'
15    login_url = '/login/'  # 未登录时重定向的URL
16

第三部分:Cookie 与 Session

3.1 Cookie 基础

Cookie 是存储在客户端浏览器的小段文本,用于跟踪用户状态。Django 通过 HttpResponse 对象设置和读取 cookie。

设置 Cookie

1def set_cookie(request):
2    response = HttpResponse("Cookie 已设置")
3    response.set_cookie('username', 'john', max_age=3600)  # 有效期1小时
4    return response
5

读取 Cookie

1def get_cookie(request):
2    username = request.COOKIES.get('username', '匿名用户')
3    return HttpResponse(f"当前用户:{username}")
4

删除 Cookie

1def delete_cookie(request):
2    response = HttpResponse("Cookie 已删除")
3    response.delete_cookie('username')
4    return response
5

3.2 Session 基础

Session 将数据存储在服务器端,客户端只保存 session ID(通过 cookie)。Django 默认使用数据库存储 session。

启用 Session:默认项目已启用,需要确保:

  • INSTALLED_APPS 包含 django.contrib.sessions
  • MIDDLEWARE 包含 SessionMiddleware

使用 Session

1# 设置 session
2def set_session(request):
3    request.session['user_id'] = 123
4    request.session['preferences'] = {'theme': 'dark', 'language': 'zh'}
5    return HttpResponse("Session 已设置")
6
7# 读取 session
8def get_session(request):
9    user_id = request.session.get('user_id', '未登录')
10    return HttpResponse(f"用户ID:{user_id}")
11
12# 删除 session
13def delete_session(request):
14    request.session.flush()  # 清空 session 数据并删除 cookie
15    return HttpResponse("Session 已清空")
16

3.3 Session 常用方法

request.session 是一个类似字典的对象,提供了丰富的方法:

1# 基础操作
2request.session['key'] = value          # 设置值
3value = request.session.get('key')      # 获取值
4del request.session['key']               # 删除键
5'key' in request.session                 # 检查存在
6
7# 高级操作
8request.session.set_expiry(300)          # 设置5分钟后过期
9request.session.set_expiry(0)             # 浏览器关闭时过期
10request.session.clear_expired()           # 清理过期session
11
12# 测试 cookie 支持
13request.session.set_test_cookie()         # 设置测试 cookie
14if request.session.test_cookie_worked():  # 检查测试 cookie
15    request.session.delete_test_cookie()   # 删除测试 cookie
16

3.4 配置 Session 存储

Django 支持多种 session 后端:

数据库 session(默认)

1SESSION_ENGINE = 'django.contrib.sessions.backends.db'
2

缓存 session(需要配置缓存):

1SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
2SESSION_CACHE_ALIAS = 'default'
3

文件 session

1SESSION_ENGINE = 'django.contrib.sessions.backends.file'
2SESSION_FILE_PATH = '/path/to/sessions/dir'  # 可选
3

cookie-based session(数据加密后存在 cookie):

1SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
2

3.5 实战:购物车示例

1def add_to_cart(request, product_id):
2    # 获取当前购物车(session 中)
3    cart = request.session.get('cart', [])
4    
5    # 添加商品
6    cart.append({
7        'product_id': product_id,
8        'quantity': 1,
9        'added_at': str(timezone.now())
10    })
11    
12    # 保存回 session
13    request.session['cart'] = cart
14    request.session.modified = True  # 确保 Django 知道 session 已修改
15    
16    return redirect('view_cart')
17
18def view_cart(request):
19    cart = request.session.get('cart', [])
20    return render(request, 'shop/cart.html', {'cart': cart})
21

第四部分:Django 中间件

4.1 什么是中间件?

中间件是 Django 请求/响应处理过程中的钩子框架。它是一个轻量级的、底层的“插件”系统,用于全局修改 Django 的输入或输出。

每个中间件组件负责执行特定功能,例如:

  • SessionMiddleware:管理用户 session
  • AuthenticationMiddleware:将用户与请求关联
  • CsrfViewMiddleware:防止 CSRF 攻击

4.2 中间件的执行顺序

中间件的执行像一个洋葱:

  • 请求阶段:按 MIDDLEWARE 列表的顺序从上到下执行
  • 响应阶段:按相反的顺序从下到上执行
1  请求进入  中间件1 (process_request) 
2           中间件2 (process_request)
3           视图函数
4           中间件2 (process_response)
5           中间件1 (process_response)
6   响应返回
7

4.3 自定义中间件

Django 支持函数式和类式两种中间件写法。

函数式中间件

1# blog/middleware.py
2def simple_middleware(get_response):
3    # 初始化代码(服务器启动时执行一次)
4    
5    def middleware(request):
6        # 请求处理前(视图之前)
7        print(f"请求路径: {request.path}")
8        
9        # 获取响应
10        response = get_response(request)
11        
12        # 响应处理后(返回客户端之前)
13        print(f"响应状态码: {response.status_code}")
14        
15        return response
16    
17    return middleware
18

类式中间件

1class StatsMiddleware:
2    def __init__(self, get_response):
3        self.get_response = get_response
4        # 初始化代码
5    
6    def __call__(self, request):
7        # 请求前
8        start_time = time.time()
9        
10        response = self.get_response(request)
11        
12        # 响应后
13        duration = time.time() - start_time
14        print(f"请求 {request.path} 耗时: {duration:.2f}秒")
15        
16        return response
17

4.4 中间件的钩子方法

类式中间件可以定义多个钩子方法:

1class AdvancedMiddleware:
2    def __init__(self, get_response):
3        self.get_response = get_response
4    
5    def __call__(self, request):
6        # 请求处理
7        response = self.get_response(request)
8        return response
9    
10    def process_view(self, request, view_func, view_args, view_kwargs):
11        """视图调用前执行"""
12        print(f"即将调用视图: {view_func.__name__}")
13        # 可以返回 None 继续处理,或返回 HttpResponse 短路
14    
15    def process_exception(self, request, exception):
16        """视图抛出异常时执行"""
17        print(f"捕获异常: {exception}")
18        # 可以返回 HttpResponse 替代错误页面
19    
20    def process_template_response(self, request, response):
21        """模板响应渲染前执行"""
22        print("准备渲染模板")
23        return response
24

4.5 激活中间件

将中间件类或函数的完整 Python 路径添加到 settings.pyMIDDLEWARE 列表中:

1# settings.py
2MIDDLEWARE = [
3    'django.middleware.security.SecurityMiddleware',
4    'django.contrib.sessions.middleware.SessionMiddleware',
5    'django.middleware.common.CommonMiddleware',
6    'django.middleware.csrf.CsrfViewMiddleware',
7    'django.contrib.auth.middleware.AuthenticationMiddleware',
8    'django.contrib.messages.middleware.MessageMiddleware',
9    'django.middleware.clickjacking.XFrameOptionsMiddleware',
10    'blog.middleware.StatsMiddleware',  # 自定义中间件
11]
12

顺序很重要!例如,AuthenticationMiddleware 依赖于 SessionMiddleware,因为用户信息存储在 session 中。

4.6 实战:IP 访问限制中间件

1# blog/middleware.py
2from django.http import HttpResponseForbidden
3from django.core.cache import cache
4
5class RateLimitMiddleware:
6    """
7    简单的 IP 限流中间件:同一 IP 每分钟最多访问 60 
8    """
9    def __init__(self, get_response):
10        self.get_response = get_response
11    
12    def __call__(self, request):
13        # 获取客户端 IP
14        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
15        if x_forwarded_for:
16            ip = x_forwarded_for.split(',')[0]
17        else:
18            ip = request.META.get('REMOTE_ADDR')
19        
20        # 缓存键
21        cache_key = f'rate_limit_{ip}'
22        
23        # 获取当前访问次数
24        count = cache.get(cache_key, 0)
25        
26        if count >= 60:
27            return HttpResponseForbidden('访问过于频繁,请稍后再试')
28        
29        # 增加计数
30        cache.set(cache_key, count + 1, timeout=60)
31        
32        # 继续处理请求
33        response = self.get_response(request)
34        return response
35

5. 综合实战:用户认证与表单结合

让我们将所学知识整合起来,实现一个完整的用户资料编辑功能。

5.1 用户资料表单

1# blog/forms.py
2from django import forms
3from django.contrib.auth.models import User
4
5class UserProfileForm(forms.ModelForm):
6    """用户资料表单"""
7    class Meta:
8        model = User
9        fields = ['first_name', 'last_name', 'email']
10        widgets = {
11            'first_name': forms.TextInput(attrs={'class': 'form-control'}),
12            'last_name': forms.TextInput(attrs={'class': 'form-control'}),
13            'email': forms.EmailInput(attrs={'class': 'form-control'}),
14        }
15

5.2 资料编辑视图

1# blog/views.py
2from django.contrib.auth.decorators import login_required
3from django.contrib import messages
4from .forms import UserProfileForm
5
6@login_required
7def profile_edit(request):
8    if request.method == 'POST':
9        form = UserProfileForm(request.POST, instance=request.user)
10        if form.is_valid():
11            form.save()
12            messages.success(request, '资料更新成功!')
13            return redirect('profile_edit')
14    else:
15        form = UserProfileForm(instance=request.user)
16    
17    # 记录用户最后访问时间到 session
18    request.session['last_visit'] = str(timezone.now())
19    
20    return render(request, 'blog/profile_edit.html', {
21        'form': form,
22        'last_visit': request.session.get('last_visit')
23    })
24

5.3 中间件记录用户活动

1# blog/middleware.py
2import logging
3logger = logging.getLogger(__name__)
4
5class UserActivityMiddleware:
6    def __init__(self, get_response):
7        self.get_response = get_response
8    
9    def __call__(self, request):
10        # 仅记录已登录用户的活动
11        if request.user.is_authenticated:
12            logger.info(f"用户 {request.user.username} 访问 {request.path}")
13            
14            #  session 中记录最后活动时间
15            request.session['last_activity'] = str(timezone.now())
16        
17        response = self.get_response(request)
18        return response
19

5.4 模板中使用消息和用户信息

1{# blog/templates/blog/profile_edit.html #}
2{% extends "base.html" %}
3
4{% block content %}
5<h2>编辑资料</h2>
6
7{% if messages %}
8    {% for message in messages %}
9        <div class="alert alert-{{ message.tags }}">{{ message }}</div>
10    {% endfor %}
11{% endif %}
12
13{% if last_visit %}
14    <p class="text-muted">上次访问时间: {{ last_visit }}</p>
15{% endif %}
16
17<form method="post">
18    {% csrf_token %}
19    {{ form.as_p }}
20    <button type="submit" class="btn btn-primary">保存修改</button>
21</form>
22{% endblock %}
23

6. 小结与练习

本篇总结

我们深入学习了 Django 的四个核心主题:

  1. Form 组件:表单定义、验证、渲染,以及 ModelForm 的使用
  2. Auth 认证系统:用户模型、认证登录、权限管理、访问控制
  3. Cookie 与 Session:状态保持机制、session 存储配置、实战应用
  4. 中间件:执行流程、自定义中间件、钩子方法

练习

  1. 注册登录功能:实现完整的用户注册、登录、注销功能,并使用 login_required 保护文章发布页面。
  2. 表单验证:为文章创建表单添加自定义验证,禁止标题中包含特定敏感词。
  3. 访问统计:编写中间件统计每个用户的访问次数,并在用户资料页显示。
  4. 购物车功能:使用 session 实现一个简单的购物车,支持添加、删除商品。

下一篇,我们将学习 Django 的 FBV 与 CBV、Nginx+uwsgi 生产部署配置,完成整个系列的最后篇章。敬请期待!


Django 基础入门教程(第四篇):Form组件、Auth认证、Cookie/Session与中间件》 是转载文章,点击查看原文


相关推荐


AI时代的数据对比:DBA还需要盯着屏幕看差异吗?
NineData2026/3/12

当 AI 已经能写 SQL、辅助诊断、生成代码时,很多企业的数据对比却还停留在相对原始的阶段:任务跑完,DBA 需要面对动辄上百张表的差异报告,逐行核对的工作量极大。 这种场景在迁移、同步、数据备份演练里并不少见,到了国产化迁移场景下更是被进一步放大。数据库从 Oracle 迁到达梦、从 MySQL 迁到人大金仓,变化的不只是运行环境,更是数据库内核、数据类型、字符集规则和兼容语义。DBA 担心的往往不是任务失败,而是任务看起来已经完成,业务流量切换之后才发现数据并不一致。 AI 时代的数据对


ubuntu应用深度守护
字节逆旅2026/3/4

二、 定位分析:抽丝剥茧 1. 系统日志中的“启动死循环” 输入sudo grep "linux-myApp" /var/log/syslog调取 syslog 发现,系统曾多次尝试自动拉起应用,但均告失败。 报错核心:Exec binary ... does not exist: No such file or directory。 结论:系统预设的自动启动路径与实际安装路径不匹配,导致应用在服务器重启后无法“回家”。 2. 定位原因 上面的日志内容意味着我的应用可能已经被卸载、被移动了位


【C++】整数类型(Integer Types)避雷指南与正确使用姿势
PAK向日葵2026/2/24

背景 C++继承自C语言。作为一门以零开销抽象为主要特征的底层语言,不同于Python或JavaScript等高抽象层次的语言,C++拥有一套较为完整、但又包含有一定历史包袱的内建整数类型。 在实际开发中,如果对C++内建整数类型的机制不熟悉,或者不遵循一定的使用规范,则非常容易引入难以排查和调试的Bug。因此学习了解C++中内建整数类型的特性,以及一套行之有效的使用规范,是非常有必要的。 内建整数类型的坑 or 历史包袱 C++ 标准没有规定具体位数 虽然在实际实践中,我们知道在x64平台,对


百度 APP 正式接入 OpenClaw,所有人限时免费!
苍何2026/2/15

这是苍何的第 495 篇原创! 大家好,我是苍何。 最近被 OpenClaw 刷屏了吧? 3 周时间 GitHub Star 干到 19 万,比当年 DeepSeek 还猛。 我也发了好几篇文章了,然后还开源了个知识库,你别说,还挺多人用的。 基本上接入 QQ、微信、飞书、discord 等都写的比较全了。 但是说实话,OpenClaw 的部署使用过程并不算丝滑。 买服务器、配环境、装依赖,光是部署就需要折腾大半天。 好不容易跑起来了,还得通过 Telegram 来发指令。 就,怎么说呢,能用


主流模型对比-02
一诺滚雪球2026/2/6

前言 GPT-4、Claude、Llama、Qwen、DeepSeek... 面对层出不穷的大语言模型,你是否也曾感到迷茫? 选贵的 GPT-4,还是用免费的开源模型? 中文场景应该用什么模型? 本地部署和云端 API 各有什么优劣? 性价比最高的选择是什么? 选对模型,不仅能节省成本,还能获得更好的效果。今天我们来聊聊如何做出明智的选择。 1. 什么是模型选型 1.1 闭源模型 vs 开源模型 特点闭源模型开


langchain学习笔记(二):工具的调用
Shawn_Shawn2026/1/29

Tool Calling 定义简单tool 创建工具最简单的方法是使用 @tool 装饰器。 @tool(description="Returns the current time in yyyy-MM-dd HH:mm:ss format.") def get_current_time(*args, **kwargs) -> str: """ 获取当前系统时间。 格式为:yyyy-MM-dd HH:mm:ss """ now = datetime.dat


2025.12.17华为软开
ゞ 正在缓冲99%…2026/1/19

细胞增殖 import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); long n = scanner.nextLong();//n个观测值


hive问题
心止水j2026/1/11

一、基础概念 问题:简述 Hive 的定义及核心作用?答案:Hive 是基于 Hadoop 的数据仓库工具,支持类 SQL(HQL)查询分析;核心作用是让非开发人员通过 SQL 分析 Hadoop 上的海量数据。 问题:Hive 的元数据默认存储在哪里?生产环境中为什么要替换为 MySQL?答案:默认存 Derby;生产换 MySQL 因 Derby 仅单用户、不支持并发,MySQL 支持多用户并发、数据持久化且易维护。 问题:Hive 支持哪些执行引擎?它们的区别是什么?答案


GDAL 实现自定义数据坐标系
GIS之路2026/1/3

^ 关注我,带你一起学GIS ^ 前言 ❝ 在GIS开发中,经常需要进行数据的转换处理,特别是Shapefile数据的投影转换更是重中之重,如何高效、准确的将源数据坐标系转换到目标坐标系是我们需要研究解决的问题。 在之前的文章中讲了如何使用GDAL或者ogr2ogr工具将txt以及csv文本数据转换为Shp格式,本篇教程在之前一系列文章的基础上讲解如何使用GDAL实现自定义数据坐标系。 GDAL 简介 GDAL 下载安装 GDAL 开发起步 GDAL 实现 GIS 数据读取转换(全) 如


刷新后点赞全变 0?别急着怪 Redis,这八成是 Long 被 JavaScript 偷偷“改号”了(一次线上复盘)
WanderInk2025/12/25

做社区功能的人,多半都经历过这种抓狂时刻:你在帖子上点了个赞,按钮立刻高亮,数字也加一,用户体验看起来很丝滑;可你一刷新页面,点赞数像被人清空了一样,全部回到 0。你打开 Redis 客户端看,计数 key 明明存在,值也不是 0。于是你开始怀疑缓存一致性,怀疑是不是读了另一台 Redis,怀疑线上 jar 没更新,甚至怀疑自己是不是在梦里写代码。 我得说,这类问题最阴的地方就在于它特别像缓存问题,实际上却往往跟缓存一点关系都没有。真正的凶手是数据类型边界,准确地说,是 Java 的 long

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客