add kownledge ahout mechine learning
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
# AWS
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2022050510233200000000000005` · 排序:6 · 文章数:7
|
||||
|
||||
## 目录
|
||||
|
||||
1. [S3](#s3)
|
||||
2. [EC2](#ec2)
|
||||
3. [Route 53](#route-53)
|
||||
4. [VPC](#vpc)
|
||||
5. [AWS Storage Gateway](#aws-storage-gateway)
|
||||
6. [Amazon Kinesis](#amazon-kinesis)
|
||||
7. [AWS STS](#aws-sts)
|
||||
|
||||
---
|
||||
|
||||
## 1. S3
|
||||
|
||||
<sub>bid: `2022050510233300000000000006`</sub>
|
||||
|
||||
### simple storage service
|
||||
---
|
||||
[Price文档](https://aws.amazon.com/cn/s3/pricing/)
|
||||
S3的收费内容,包括:
|
||||
存储,请求(http请求数量),数据传输(宽带费用),复制(跨区域和不跨区域),管理(额外的高级管理功能)
|
||||
|
||||
|
||||
### Enable Requester Pays
|
||||
---
|
||||
[官方文档](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/RequesterPaysBuckets.html)
|
||||
作为SAP考试中的一题,重要考察的是:存储桶的拥有者和访问者分开付费。两个不同的付费账户,访问者需要身份验证。
|
||||
关键词:**Enable Requester Pays**,**AWS credentials**
|
||||
|
||||
### Replicating objects
|
||||
---
|
||||
[官方文档](https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication.html#crr-scenario)
|
||||
**Cross-Region Replication** 跨区域复制 **CRR**
|
||||
|
||||
**Same-Region Replication** 同区域复制 **SRR**
|
||||
|
||||
---
|
||||
|
||||
## 2. EC2
|
||||
|
||||
<sub>bid: `2022050510458100000000000007`</sub>
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 3. Route 53
|
||||
|
||||
<sub>bid: `2022050510575300000000000008`</sub>
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 4. VPC
|
||||
|
||||
<sub>bid: `2022050511086300000000000009`</sub>
|
||||
|
||||
### Amazon Virtual Private Cloud
|
||||
---
|
||||
私有云
|
||||
[官方文档](https://docs.aws.amazon.com/zh_cn/vpc/?id=docs_gateway)
|
||||
|
||||
PVC的CIDR是 16位,
|
||||
PVC的子网的CIDR是24位,
|
||||
同一个区域的两个VPC,最好的解决方式是peering connection,并在路由表中添加路由
|
||||
|
||||
### VPC peering
|
||||
---
|
||||
  VPC 对等连接是两个 VPC 之间的网络连接,通过此连接,您可以使用私有 IPv4 地址或 IPv6 地址在两个 VPC 之间路由流量。这两个 VPC 中的实例可以彼此通信,就像它们在同一网络中一样。您可以在自己的 VPC 之间创建 VPC 对等连接,或者在自己的 VPC 与其他AWS账户中的 VPC 之间创建连接。VPC 可位于不同区域内(也称为区域间 VPC 对等连接)
|
||||
  AWS使用 VPC 的现有基础设施来创建 VPC 对等连接;该连接既不是网关也不是 VPN 连接,并且不依赖某一单独的物理硬件。没有单点通信故障也没有带宽瓶颈。
|
||||
  创建 VPC 对等连接,无需付费。通过对等连接进行数据传输需要付费。
|
||||
  要将私有 IPv4 流量从实例发送到对等 VPC 中的实例,必须向与实例所在子网关联的路由表添加路由。此路由指向 VPC 对等连接中对等 VPC 的 CIDR 块(或 CIDR 块的一部分),并指定 VPC 对等连接作为目标。
|
||||
### AWS Transit Gateway
|
||||
---
|
||||
[中转网关工作原理](https://docs.aws.amazon.com/zh_cn/vpc/latest/tgw/how-transit-gateways-work.html)
|
||||
中转网关是网络中转中心,您可用它来互连 Virtual Private Cloud (VPC) 和本地网络.
|
||||
中转网关独立存在,有中转网关路由表,可以挂载VPC,AWS Direct Connect,对等连接的另一个Transit Gateway,VPN链接,和第三方设备
|
||||
中转网关既可以共享,也可以通过CloudWatch和CloudTrail进行监控。
|
||||
### AWS PrivateLink
|
||||
---
|
||||
  AWS PrivateLink 是一项具有高可用性的可扩展技术,支持您将您的 VPC 私密地连接到支持的 AWS 服务、由其他 AWS 账户托管的服务(VPC 终端节点服务)以及支持的 AWS Marketplace 合作伙伴服务。您无需使用互联网网关、NAT 设备、公有 IP 地址、AWS Direct Connect 连接或 AWS Site-to-Site VPN 连接,就能与该服务通信。因此,您可以控制可从 VPC 访问的特定 API 终端节点、站点和服务。
|
||||
|
||||
  请区分终端节点和终端节点服务。
|
||||
|
||||
  私有链接通过终端节点来实现,终端节点包括:
|
||||
接口终端节点:
|
||||
网关终端节点:
|
||||
网关负载均衡器终端节点:
|
||||
|
||||
---
|
||||
|
||||
## 5. AWS Storage Gateway
|
||||
|
||||
<sub>bid: `2022050513596500000000000010`</sub>
|
||||
|
||||
**提供几乎不受限制的云存储的本地应用程序访问权限**
|
||||
[官方文档](https://aws.amazon.com/cn/storagegateway/?nc1=h_ls)
|
||||
|
||||
---
|
||||
|
||||
## 6. Amazon Kinesis
|
||||
|
||||
<sub>bid: `2022050514188900000000000011`</sub>
|
||||
|
||||
对标于flume,Kafka,和flink的分布式云计算模式。
|
||||
[官方文档](https://aws.amazon.com/cn/kinesis/)
|
||||
**Amazon Kinesis Data Streams** 其实和flume很像
|
||||
  日志采集传输,sink
|
||||
**Amazon Kinesis Data Firehose** 其实和kafka很像
|
||||
  消息队列,存储
|
||||
**Amazon Kinesis Data Analytics** 其实和flink很像
|
||||
  流式计算
|
||||
|
||||
---
|
||||
|
||||
## 7. AWS STS
|
||||
|
||||
<sub>bid: `2022050911184000000000000004`</sub>
|
||||
|
||||
|
||||
AWS Security Token Service (STS)
|
||||
|
||||
---
|
||||
@@ -0,0 +1,154 @@
|
||||
# Azure
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2022052309468900000000000004` · 排序:8 · 文章数:8
|
||||
|
||||
## 目录
|
||||
|
||||
1. [Iot Hub Endpoint](#iot-hub-endpoint)
|
||||
2. [Iot Hub Message routing](#iot-hub-message-routing)
|
||||
3. [Azure IoT Hub Device Provisioning Service (DPS)](#azure-iot-hub-device-provisioning-service-dps)
|
||||
4. [Batch Shipyard](#batch-shipyard)
|
||||
5. [Azure system](#azure-system)
|
||||
6. [pricing](#pricing)
|
||||
7. [Azure IoT Edge](#azure-iot-edge)
|
||||
8. [pvc](#pvc)
|
||||
|
||||
---
|
||||
|
||||
## 1. Iot Hub Endpoint
|
||||
|
||||
<sub>bid: `2022052309469000000000000009`</sub>
|
||||
|
||||
### endpoints
|
||||
---
|
||||
[IoT Hub endpoints](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-endpoints)
|
||||
|
||||
## IoT Hub names
|
||||
You can find the hostname of the IoT hub that hosts your endpoints in the portal on your hub's Overview page.
|
||||
By default, the DNS name of an IoT hub looks like: {your iot hub name}.azure-devices.net.
|
||||
|
||||
## List of built-in IoT Hub endpoints
|
||||
1. Device identity management
|
||||
2. Device twin management
|
||||
3. Jobs management
|
||||
4. Device endpoints
|
||||
5. Service endpoints
|
||||
6. Resource provider.
|
||||
|
||||
## Custom endpoints
|
||||
1. Azure Storage containers
|
||||
2. Event Hubs
|
||||
3. Service Bus Queues
|
||||
4. Service Bus Topics
|
||||
|
||||
|
||||
## Endpoint Health
|
||||
|
||||
## Field gateways
|
||||
In an IoT solution, a field gateway sits between your devices and your IoT Hub endpoints.
|
||||
It is typically located close to your devices.
|
||||
You can use Azure IoT Edge to implement a field gateway.
|
||||
IoT Edge offers functionality such as multiplexing communications from multiple devices onto the same IoT Hub connection.
|
||||
|
||||
---
|
||||
|
||||
## 2. Iot Hub Message routing
|
||||
|
||||
<sub>bid: `2022052310025600000000000010`</sub>
|
||||
|
||||
Message routing
|
||||
---
|
||||
[Message routing](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-d2c)
|
||||
|
||||
---
|
||||
|
||||
## 3. Azure IoT Hub Device Provisioning Service (DPS)
|
||||
|
||||
<sub>bid: `2022052310265300000000000011`</sub>
|
||||
|
||||
### Azure IoT Hub Device Provisioning Service (DPS)
|
||||
---
|
||||
[DPS](https://docs.microsoft.com/en-us/azure/iot-dps/?WT.mc_id=Portal-Microsoft_Azure_IotHub)
|
||||
|
||||
## what is
|
||||
Microsoft Azure provides a rich set of integrated public cloud services for all your IoT solution needs.
|
||||
The IoT Hub Device Provisioning Service (DPS) is a helper service for IoT Hub that enables zero-touch, just-in-time provisioning to the right IoT hub without requiring human intervention.
|
||||
DPS enables the provisioning of millions of devices in a secure and scalable manner.
|
||||
|
||||
##
|
||||
|
||||
---
|
||||
|
||||
## 4. Batch Shipyard
|
||||
|
||||
<sub>bid: `2022052313361500000000000012`</sub>
|
||||
|
||||
## Batch Shipyard
|
||||
---
|
||||
[doc](https://batch-shipyard.readthedocs.io/en/latest/00-introduction/)
|
||||
|
||||
---
|
||||
|
||||
## 5. Azure system
|
||||
|
||||
<sub>bid: `2022052313512900000000000013`</sub>
|
||||
|
||||
1.active directory
|
||||
2.subscriptions
|
||||
3.Resource groups
|
||||
4.
|
||||
|
||||
azure 基本上是个网格体系
|
||||
|
||||
---
|
||||
|
||||
## 6. pricing
|
||||
|
||||
<sub>bid: `2022052314413800000000000015`</sub>
|
||||
|
||||
## Pricing Options
|
||||
---
|
||||
[doc](https://azure.microsoft.com/ja-jp/pricing/details/iot-hub/#purchase-options)
|
||||
|
||||
---
|
||||
|
||||
## 7. Azure IoT Edge
|
||||
|
||||
<sub>bid: `2022052410596000000000000017`</sub>
|
||||
|
||||
## Modules
|
||||
---
|
||||
[doc](https://docs.microsoft.com/en-us/azure/iot-edge/iot-edge-modules?view=iotedge-2020-11)
|
||||
|
||||
IoT Edge modules are Docker containers deployed to IoT Edge devices.
|
||||
They can communicate with other modules or send data to the IoT Edge runtime.
|
||||
Azure IoT Edge lets you deploy and manage business logic on the edge in the form of modules.
|
||||
Azure IoT Edge modules are the smallest unit of computation managed by IoT Edge, and can contain Azure services (such as Azure Stream Analytics) or your own solution-specific code.
|
||||
To understand how modules are developed, deployed, and maintained, consider the four conceptual elements of a module:
|
||||
|
||||
## Routes
|
||||
---
|
||||
[doc](https://docs.microsoft.com/ja-jp/azure/iot-edge/module-composition?view=iotedge-2020-11#declare-routes)
|
||||
|
||||
|
||||
## IoT Edge deployments
|
||||
---
|
||||
[doc](https://docs.microsoft.com/ja-jp/azure/iot-edge/module-deployment-monitoring?view=iotedge-2020-11)
|
||||
|
||||
IoT Edge deployments configure sets of IoT Edge devices to run IoT Edge modules.
|
||||
Each deployment continuously ensures that all matching devices are running the specified set of modules, even when new devices are created or are modified to match the target condition.
|
||||
|
||||
Two modules are required in every deployment manifest: $edgeAgent, and $edgeHub.
|
||||
|
||||
These modules are part of the IoT Edge runtime that manages the IoT Edge device and the modules running on it.
|
||||
|
||||
---
|
||||
|
||||
## 8. pvc
|
||||
|
||||
<sub>bid: `2022110910113500000000000002`</sub>
|
||||
|
||||
|
||||
|
||||
---
|
||||
@@ -0,0 +1,199 @@
|
||||
# Golang
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2023022315480800000000000001` · 排序:12 · 文章数:4
|
||||
|
||||
## 目录
|
||||
|
||||
1. [3. grpc xds](#3-grpc-xds)
|
||||
2. [2. grpc health check](#2-grpc-health-check)
|
||||
3. [1. grpc protoc](#1-grpc-protoc)
|
||||
4. [4. Go](#4-go)
|
||||
|
||||
---
|
||||
|
||||
## 1. 3. grpc xds
|
||||
|
||||
<sub>bid: `2023022315480900000000000020`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 2. 2. grpc health check
|
||||
|
||||
<sub>bid: `2023022315484500000000000019`</sub>
|
||||
|
||||
##
|
||||
|
||||
---
|
||||
|
||||
## 3. 1. grpc protoc
|
||||
|
||||
<sub>bid: `2023022315507600000000000021`</sub>
|
||||
|
||||
## base consepts
|
||||
|
||||
- protobuf
|
||||
|
||||
我们可以查看官方文档 [protobuf guides](https://protobuf.dev/programming-guides/proto3/)
|
||||
|
||||
简单来说就是一种以 .proto 结尾文件,遵循protocol buffer language 语法,其中包含一个或者多个message和service。
|
||||
|
||||
**notice_service.proto**
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package notice.service.v1;
|
||||
|
||||
option go_package ="violin-notice/pkg/service/notice.service.v1";
|
||||
|
||||
message NoticeMessage {
|
||||
|
||||
};
|
||||
|
||||
message NoticeResponse {};
|
||||
|
||||
service NoticeService {
|
||||
rpc SendNotice(NoticeMessage) returns (NoticeResponse) {}
|
||||
}
|
||||
|
||||
- protoc
|
||||
[protoc guides](https://github.com/bufbuild/protoc-gen-validate)
|
||||
|
||||
作为可执行程序,其作用是将上面的我们定义的.proto文件转换成对应语言的grpc 可用的文件,我们通过对这些文件进行扩展来实现我们想要的场景。
|
||||
|
||||
protoc --go_out=./gen --go_opt=paths=source_relative --go-grpc_out=./gen --go-grpc_opt=paths=source_relative notice_service.proto
|
||||
|
||||
执行上面命令会生成go语言的两个文件
|
||||
|
||||
notice_service_grpc.pb.go
|
||||
notice_service.pb.go
|
||||
|
||||
我们只需要自己写一个notice_service.go 来扩展上述两个文件即可。
|
||||
|
||||
**package notice_service_v1**
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gopkg.in/gomail.v2"
|
||||
"log"
|
||||
"violin-home.cn/common/logs"
|
||||
)
|
||||
|
||||
type NoticeService struct {
|
||||
UnimplementedNoticeServiceServer
|
||||
}
|
||||
|
||||
func New() *NoticeService {
|
||||
return &NoticeService{}
|
||||
}
|
||||
|
||||
|
||||
func (*NoticeService) SendNotice(
|
||||
ctx context.Context, msg *NoticeMessage) (*NoticeResponse, error) {
|
||||
|
||||
// to write logic
|
||||
return &NoticeResponse{}, nil
|
||||
}
|
||||
|
||||
|
||||
## 如何使用grpc
|
||||
|
||||
grpc 存在client和server
|
||||
|
||||
---
|
||||
|
||||
## 4. 4. Go
|
||||
|
||||
<sub>bid: `2023030213489100000000000022`</sub>
|
||||
|
||||
## 1. 概述
|
||||
一些简单的概念介绍可以通过下面网站学习到。
|
||||
[golang 菜鸟教程](https://www.runoob.com/go/go-tutorial.html)
|
||||
|
||||
## 2. package
|
||||
|
||||
golang的包管理模式是树形的,并且有以下规约:
|
||||
**1**
|
||||
树形结构的根节点是main,即项目根目录。
|
||||
**2**
|
||||
文件中的包定义 一定是和该文件所处的文件夹相同
|
||||
**3**
|
||||
文件中定义的函数,如果是像作为第三方包引用,函数的首字母必须大写
|
||||
|
||||
# violin-controller 工程为例 https://github.com/simple321vip/violin-controller
|
||||
ls
|
||||
main.go controller.go controller_test.go 都是 根目录下的文件,所以他们的package 都是 main
|
||||
请注意 包 的名字只能是该文件夹的名字,并不包括父级路径
|
||||
|
||||
**4 引包**
|
||||
引包 包括第三方包 和 项目自定义包
|
||||
在mod模式下,第三方包存在 \$GOPATH/pkg/mod
|
||||
而自定义包 引入的时候直接从采用 项目相对路径的方式引入
|
||||
|
||||
## 3. 变量与指针
|
||||
|
||||
变量分为 值变量和指针变量
|
||||
|
||||
## 4. 函数
|
||||
|
||||
**1. main()** 函数
|
||||
|
||||
程序入口函数
|
||||
|
||||
**2. init()** 函数
|
||||
|
||||
每一个源文件都可以包含一个init函数,init意为初始化,也表明init函数会在main函数执行之前执行。
|
||||
|
||||
**3. go func()** 函数
|
||||
|
||||
并发编程 即异步
|
||||
|
||||
**4. func() {}()** 匿名函数
|
||||
|
||||
匿名函数可以通过变量指向匿名函数,可以匿名函数直接执行
|
||||
|
||||
// 声明一个函数变量
|
||||
f := func() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// 调用函数
|
||||
f()
|
||||
|
||||
// 也可以直接执行匿名函数
|
||||
func() int {
|
||||
return 1
|
||||
}()
|
||||
|
||||
**5. func sample() func() int {}** 通过匿名函数实现闭包
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func getSequence() func() int {
|
||||
i:=0
|
||||
return func() int {
|
||||
i+=1
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
func main(){
|
||||
/* nextNumber 为一个函数,函数 i 为 0 */
|
||||
nextNumber := getSequence()
|
||||
|
||||
/* 调用 nextNumber 函数,i 变量自增 1 并返回 */
|
||||
fmt.Println(nextNumber())
|
||||
fmt.Println(nextNumber())
|
||||
fmt.Println(nextNumber())
|
||||
|
||||
/* 创建新的函数 nextNumber1,并查看结果 */
|
||||
nextNumber1 := getSequence()
|
||||
fmt.Println(nextNumber1())
|
||||
fmt.Println(nextNumber1())
|
||||
}
|
||||
|
||||
---
|
||||
@@ -0,0 +1,659 @@
|
||||
# Java and Spring
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`00000000000002` · 排序:1 · 文章数:14
|
||||
|
||||
## 目录
|
||||
|
||||
1. [Springboot AbstractApplicationContext](#springboot-abstractapplicationcontext)
|
||||
2. [Map Set List](#map-set-list)
|
||||
3. [Java8 AQS](#java8-aqs)
|
||||
4. [Java8 Stream](#java8-stream)
|
||||
5. [Spring superinterface](#spring-superinterface)
|
||||
6. [Springboot DefaultSingletonBeanRegistry](#springboot-defaultsingletonbeanregistry)
|
||||
7. [Springboot SpringApplication](#springboot-springapplication)
|
||||
8. [Springboot AbstractBeanFactory](#springboot-abstractbeanfactory)
|
||||
9. [Springboot AbstractAutowireCapableBeanFactory](#springboot-abstractautowirecapablebeanfactory)
|
||||
10. [Springboot AbstractBeanDefinition](#springboot-abstractbeandefinition)
|
||||
11. [Springboot ConfigurationClassPostProcessor](#springboot-configurationclasspostprocessor)
|
||||
12. [Spring ASM](#spring-asm)
|
||||
13. [PostProcessorRegistrationDelegate](#postprocessorregistrationdelegate)
|
||||
14. [Spring Aop](#spring-aop)
|
||||
|
||||
---
|
||||
|
||||
## 1. Springboot AbstractApplicationContext
|
||||
|
||||
<sub>bid: `00000000000003`</sub>
|
||||
|
||||
## AbstractApplicationContext
|
||||
|
||||
AbstractApplicationContext 是 SpringBoot的 核心应用上下文父类。
|
||||
|
||||
## x.1 properties
|
||||
|
||||
### beanFactoryPostProcessors
|
||||
|
||||
### environment
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### refresh
|
||||
|
||||
refresh 是 Springboot启动中核心方法。
|
||||
|
||||
- prepareRefresh
|
||||
- obtainFreshBeanFactory
|
||||
- prepareBeanFactory
|
||||
- postProcessBeanFactory
|
||||
- invokeBeanFactoryPostProcessors
|
||||
- registerBeanPostProcessors
|
||||
- onRefresh
|
||||
- finishBeanFactoryInitialization
|
||||
- finishRefresh
|
||||
|
||||
---
|
||||
|
||||
## 2. Map Set List
|
||||
|
||||
<sub>bid: `2022051816085000000000000006`</sub>
|
||||
|
||||
### 1. Summary
|
||||
|
||||
我们在开发过程在,最常见的三种数据存储结构就是 Map Set 和List了
|
||||
|
||||
这三种结构最明显的特征就是Map 是键值,Set是对象存储唯一,List是有序数组
|
||||
|
||||
|
||||
### Map<K, V>
|
||||
|
||||
键值存储,主键不允许重复
|
||||
|
||||
添加元素 使用put方法,如果key重复,则value被覆盖
|
||||
|
||||
### Set<E>
|
||||
|
||||
对象存储,对象不允许重复
|
||||
|
||||
/**
|
||||
* if this set did not already contain the specified element will return {@code true}
|
||||
* f this set already contains the element, the call leaves the set
|
||||
* unchanged and returns {@code false}
|
||||
*/
|
||||
public boolean add(E e)
|
||||
|
||||
### List<E>
|
||||
|
||||
list是由数组构成的,这就意味着,list是有顺序的,因为数组在内存中是一段连续的内存。
|
||||
|
||||
---
|
||||
|
||||
## 3. Java8 AQS
|
||||
|
||||
<sub>bid: `2022052314143400000000000014`</sub>
|
||||
|
||||
## AQ
|
||||
|
||||
---
|
||||
|
||||
## 4. Java8 Stream
|
||||
|
||||
<sub>bid: `2022060810550500000000000022`</sub>
|
||||
|
||||
## S
|
||||
|
||||
---
|
||||
|
||||
## 5. Spring superinterface
|
||||
|
||||
<sub>bid: `2022120915183100000000000001`</sub>
|
||||
|
||||
## summary
|
||||
|
||||
|
||||
## 1. Aware(感知)
|
||||
|
||||
Spring Ioc 是解耦行为,我们的业务代码其实是没有感知或者意识到spring框架的存在。如果我们需要使用spring Ioc中的资源时候,我们就需要有意识的去获取这个资源,而Aware 就是这样的存在。
|
||||
|
||||
@Service
|
||||
public class AppContextAware implements ApplicationContextAware {
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext=applicationContext;
|
||||
}
|
||||
|
||||
public void hello(){
|
||||
//user为容器中存在的bean
|
||||
User user = applicationContext.getBean("user", User.class);
|
||||
System.out.println(user);
|
||||
|
||||
//获取容器的环境、User.name为设置好的属性
|
||||
Environment environment = applicationContext.getEnvironment();
|
||||
String property = environment.getProperty("User.name");
|
||||
System.out.println(" 属性:"+property);
|
||||
}
|
||||
}
|
||||
|
||||
一些常用的Aware interface
|
||||
BeanNameAware
|
||||
ApplicationContextAware
|
||||
ResourceLoaderAware
|
||||
EnvironmentAware
|
||||
|
||||
|
||||
|
||||
## 2. BeanFactory
|
||||
|
||||
BeanFactory 提供了获取bean和判断bean的方法,包括
|
||||
|
||||
getBean(String beanName)
|
||||
getBean(String beanName, Class<T> requiredType)
|
||||
getBean(Class<T> requiredType)
|
||||
containsBean(String name)
|
||||
isSingleton(String name)
|
||||
isPrototype(String name)
|
||||
sTypeMatch(String name)
|
||||
getType(String name)
|
||||
String[] getAliases(String name);
|
||||
|
||||
## 3. BeanPostProcessor
|
||||
|
||||
## 4. BeanFactoryPostProcessor
|
||||
|
||||
## 5. ApplicationContext
|
||||
|
||||
## 6. InitializingBean
|
||||
|
||||
---
|
||||
|
||||
## 6. Springboot DefaultSingletonBeanRegistry
|
||||
|
||||
<sub>bid: `2022121513519200000000000002`</sub>
|
||||
|
||||
## DefaultSingletonBeanRegistry
|
||||
|
||||
DefaultSingletonBeanRegistry 是Springboot bean 自动装配的核心实现类。
|
||||
顾名思义,是默认的单例bean 注册器。
|
||||
|
||||
## x.1 properties
|
||||
|
||||
### dependentBeanMap
|
||||
|
||||
存放(依赖对象key -> 被依赖Set)的 ConcurrentHashMap
|
||||
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
|
||||
|
||||
### dependenciesForBeanMap
|
||||
|
||||
存放(被依赖对象key -> 依赖Set)的 ConcurrentHashMap
|
||||
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
|
||||
###
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### registerDependentBean
|
||||
|
||||
我们知道Spring DI 依赖注入,此方法就是依赖注入的核心组成。注意,这段逻辑是加锁的,即存在并行处理逻辑。
|
||||
Springboot 在 AbstractApplicationContext 进行 refresh 操作时候,在最后一步会实例化bean,参照AbstractApplicationContext.finishBeanFactoryInitialization 方法,此方法的流程我们会在xxx讲解。源码如下
|
||||
|
||||
|
||||
/**
|
||||
* Register a dependent bean for the given bean。
|
||||
*/
|
||||
public void registerDependentBean(String beanName, String dependentBeanName) {
|
||||
String canonicalName = canonicalName(beanName);
|
||||
synchronized (this.dependentBeanMap) {
|
||||
Set<String> dependentBeans =
|
||||
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
|
||||
if (!dependentBeans.add(dependentBeanName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (this.dependenciesForBeanMap) {
|
||||
Set<String> dependenciesForBean =
|
||||
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
|
||||
dependenciesForBean.add(canonicalName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DI 在此处的实现逻辑可以通过下面例子来通俗说明:
|
||||
① A对象 依赖 B对象
|
||||
② A对象 依赖 C对象
|
||||
③ D对象 依赖 B对象
|
||||
所以 必须要提前先把 B 对象和 C对象进行实例化后,才能 创建A对象和 D对象。
|
||||
我们从RootBeanDefinition中获取 dependsOn的数组,遍历调用registerDependentBean方法
|
||||
参数beanName是依赖对象,即 B 或者 C,参数dependentBeanName是被依赖对象A
|
||||
1. 传入参数是 (B,A) 时,为 B 创建一个 LinkedHashSet,并在该Set中存放A, 并把 B -> Set的映射关系放入dependentBeanMap中。
|
||||
紧接着 为 A 创建一个 LinkedHashSet, 并在该Set中存放B,并把 A -> Set的映射关系放入dependenciesForBeanMap中。
|
||||
2. 传入参数是 (C, A) 时,为 C 创建一个 LinkedHashSet,并在该Set中存放A, 并把 C -> Set的映射关系放入dependentBeanMap中。
|
||||
因为 dependenciesForBeanMap 已经存在了 A -> Set这个映射,我们只需将 C 也存入这个Set就可以。
|
||||
3. 传入参数是 (B, D) 时,因为 dependentBeanMap 已经存在了 B -> Set这个映射,我们只需将 D 也存入这个Set就可以。
|
||||
紧接着 为 D 创建一个 LinkedHashSet, 并在该Set中存放B,并把 D -> Set的映射关系放入dependenciesForBeanMap中。
|
||||
|
||||
`注意` 依赖和被依赖总是成对出现的,dependentBeans.add(dependentBeanName) 返回 false,视为添加失败,即视为已经存在,根据 依赖和被依赖总是成对出现的,所以后面dependenciesForBean.add(canonicalName) 这部分就没必要执行了,因为执行了也没有意义,所以直接 return了。毕竟dependenciesForBean中已经存在了canonicalName。
|
||||
|
||||
---
|
||||
|
||||
## 7. Springboot SpringApplication
|
||||
|
||||
<sub>bid: `2022121513597200000000000003`</sub>
|
||||
|
||||
## SpringApplication
|
||||
|
||||
## x.1 properties
|
||||
|
||||
### sources
|
||||
|
||||
### environment
|
||||
|
||||
### webApplicationType
|
||||
|
||||
###
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### run
|
||||
|
||||
1. 创建 DefaultBootstrapContext
|
||||
2. 获取 SpringApplicationRunListeners
|
||||
3. 转换 ApplicationArguments 将commandLine args
|
||||
4. 装备环境 ConfigurableEnvironment
|
||||
5. 配置忽略bean情报 configureIgnoreBeanInfo
|
||||
6. 创建 ApplicationContext
|
||||
7. 准备 ApplicationContext prepareContext
|
||||
设置上下文环境,加载source
|
||||
8. 刷新 ApplicationContext
|
||||
9. 刷新后处理
|
||||
|
||||
---
|
||||
|
||||
## 8. Springboot AbstractBeanFactory
|
||||
|
||||
<sub>bid: `2022121515315000000000000004`</sub>
|
||||
|
||||
## AbstractBeanFactory
|
||||
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### doGetBean
|
||||
AbstractBeanFactory 的核心方法 doGetBean,doGetBean方法是由getBean调用的,如果有dependsOn存在,就会将注册依赖, 然调用getBean(dep),从而形成了递归操作。
|
||||
当不存dependsOn的时候mbd.isSingleton 时候,就会调用 getSingleton方法,子类会回调createBean(beanName, mbd, args)方法,去创建bean。
|
||||
|
||||
源码
|
||||
|
||||
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType) {
|
||||
String beanName = transformedBeanName(name);
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
checkMergedBeanDefinition(mbd, beanName, args);
|
||||
|
||||
// Guarantee initialization of beans that the current bean depends on.
|
||||
String[] dependsOn = mbd.getDependsOn();
|
||||
if (dependsOn != null) {
|
||||
for (String dep : dependsOn) {
|
||||
if (isDependent(beanName, dep)) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
|
||||
}
|
||||
registerDependentBean(dep, beanName);
|
||||
try {
|
||||
getBean(dep);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create bean instance.
|
||||
if (mbd.isSingleton()) {
|
||||
sharedInstance = getSingleton(beanName, () -> {
|
||||
try {
|
||||
return createBean(beanName, mbd, args);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
// Explicitly remove instance from singleton cache: It might have been put there
|
||||
// eagerly by the creation process, to allow for circular reference resolution.
|
||||
// Also remove any beans that received a temporary reference to the bean.
|
||||
destroySingleton(beanName);
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## 9. Springboot AbstractAutowireCapableBeanFactory
|
||||
|
||||
<sub>bid: `2022121523309700000000000005`</sub>
|
||||
|
||||
## AbstractAutowireCapableBeanFactory
|
||||
|
||||
父类是AbstractBeanFactory,实现了AutowireCapableBeanFactory 的方法,其中最主要的还是createBean方法。
|
||||
源码
|
||||
|
||||
/**
|
||||
* Central method of this class: creates a bean instance,
|
||||
* populates the bean instance, applies post-processors, etc.
|
||||
* @see #doCreateBean
|
||||
*/
|
||||
@Override
|
||||
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
|
||||
throws BeanCreationException {
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
RootBeanDefinition mbdToUse = mbd;
|
||||
|
||||
// Make sure bean class is actually resolved at this point, and
|
||||
// clone the bean definition in case of a dynamically resolved Class
|
||||
// which cannot be stored in the shared merged bean definition.
|
||||
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
|
||||
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
|
||||
mbdToUse = new RootBeanDefinition(mbd);
|
||||
mbdToUse.setBeanClass(resolvedClass);
|
||||
}
|
||||
|
||||
// Prepare method overrides.
|
||||
try {
|
||||
mbdToUse.prepareMethodOverrides();
|
||||
}
|
||||
catch (BeanDefinitionValidationException ex) {
|
||||
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
|
||||
beanName, "Validation of method overrides failed", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
|
||||
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
|
||||
if (bean != null) {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
|
||||
"BeanPostProcessor before instantiation of bean failed", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Finished creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
return beanInstance;
|
||||
}
|
||||
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
|
||||
// A previously detected exception with proper bean creation context already,
|
||||
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
|
||||
throw ex;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(
|
||||
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## 10. Springboot AbstractBeanDefinition
|
||||
|
||||
<sub>bid: `2022121523361800000000000006`</sub>
|
||||
|
||||
## AbstractBeanDefinition
|
||||
|
||||
AbstractBeanDefinition 定义了 一个bean的各种描述。
|
||||
|
||||
## x.1
|
||||
|
||||
### String[] dependsOn
|
||||
|
||||
### Resource resource
|
||||
|
||||
###
|
||||
|
||||
---
|
||||
|
||||
## 11. Springboot ConfigurationClassPostProcessor
|
||||
|
||||
<sub>bid: `2022121612282000000000000009`</sub>
|
||||
|
||||
## ConfigurationClassPostProcessor
|
||||
|
||||
这一节主要讲的是ConfigurationClassPostProcessor和他的一些生态。
|
||||
他的生态有
|
||||
- ConfigurationClassParser 真正的处理者。
|
||||
- ComponentScanAnnotationParser 扫描classpath,把beanName加入到registry的beanDefinitionMap中。
|
||||
- doProcessConfigurationClass 是该 postProcessor最核心的处理方法
|
||||
|
||||
/**
|
||||
* Apply processing and build a complete {@link ConfigurationClass} by reading the
|
||||
* annotations, members and methods from the source class. This method can be called
|
||||
* multiple times as relevant sources are discovered.
|
||||
* @param configClass the configuration class being build
|
||||
* @param sourceClass a source class
|
||||
* @return the superclass, or {@code null} if none found or previously processed
|
||||
*/
|
||||
@Nullable
|
||||
protected final SourceClass doProcessConfigurationClass(
|
||||
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
|
||||
throws IOException {
|
||||
|
||||
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
|
||||
// Recursively process any member (nested) classes first
|
||||
processMemberClasses(configClass, sourceClass, filter);
|
||||
}
|
||||
// Process any @PropertySource annotations
|
||||
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
|
||||
sourceClass.getMetadata(), PropertySources.class,
|
||||
org.springframework.context.annotation.PropertySource.class)) {
|
||||
if (this.environment instanceof ConfigurableEnvironment) {
|
||||
processPropertySource(propertySource);
|
||||
}
|
||||
else {
|
||||
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
|
||||
"]. Reason: Environment must implement ConfigurableEnvironment");
|
||||
}
|
||||
}
|
||||
// Process any @ComponentScan annotations
|
||||
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
|
||||
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
|
||||
if (!componentScans.isEmpty() &&
|
||||
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
|
||||
for (AnnotationAttributes componentScan : componentScans) {
|
||||
// The config class is annotated with @ComponentScan -> perform the scan immediately
|
||||
Set<BeanDefinitionHolder> scannedBeanDefinitions =
|
||||
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
|
||||
// Check the set of scanned definitions for any further config classes and parse recursively if needed
|
||||
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
|
||||
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
|
||||
if (bdCand == null) {
|
||||
bdCand = holder.getBeanDefinition();
|
||||
}
|
||||
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
|
||||
parse(bdCand.getBeanClassName(), holder.getBeanName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process any @Import annotations
|
||||
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
|
||||
|
||||
// Process any @ImportResource annotations
|
||||
AnnotationAttributes importResource =
|
||||
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
|
||||
if (importResource != null) {
|
||||
String[] resources = importResource.getStringArray("locations");
|
||||
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
|
||||
for (String resource : resources) {
|
||||
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
|
||||
configClass.addImportedResource(resolvedResource, readerClass);
|
||||
}
|
||||
}
|
||||
|
||||
// Process individual @Bean methods
|
||||
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
|
||||
for (MethodMetadata methodMetadata : beanMethods) {
|
||||
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
|
||||
}
|
||||
|
||||
// Process default methods on interfaces
|
||||
processInterfaces(configClass, sourceClass);
|
||||
|
||||
// Process superclass, if any
|
||||
if (sourceClass.getMetadata().hasSuperClass()) {
|
||||
String superclass = sourceClass.getMetadata().getSuperClassName();
|
||||
if (superclass != null && !superclass.startsWith("java") &&
|
||||
!this.knownSuperclasses.containsKey(superclass)) {
|
||||
this.knownSuperclasses.put(superclass, configClass);
|
||||
// Superclass found, return its annotation metadata and recurse
|
||||
return sourceClass.getSuperClass();
|
||||
}
|
||||
}
|
||||
|
||||
// No superclass -> processing is complete
|
||||
return null;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## 12. Spring ASM
|
||||
|
||||
<sub>bid: `2022121615335100000000000010`</sub>
|
||||
|
||||
## asm
|
||||
|
||||
在spring中其实很少听到asm这个关键字,asm -> Assembly,跟多是指汇编语言。
|
||||
|
||||
spring也是用到asm,而且asm包是spring-core的组成部分。spring asm 大体上跟 原生的asm 都是差不多了。
|
||||
|
||||
(参照链接)[ https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/asm/package-summary.htm ]
|
||||
|
||||
|
||||
package org.springframework.asm
|
||||
Spring's repackaging of ASM 9.x (with Spring-specific patches; for internal use only).
|
||||
This repackaging technique avoids any potential conflicts with dependencies on ASM at the application level or from third-party libraries and frameworks.
|
||||
|
||||
As this repackaging happens at the class file level, sources and javadocs are not available here.
|
||||
|
||||
从package-info可以看出,repackaging,avoids any potential conflicts
|
||||
|
||||
---
|
||||
|
||||
## 13. PostProcessorRegistrationDelegate
|
||||
|
||||
<sub>bid: `2022121915527600000000000011`</sub>
|
||||
|
||||
## PostProcessorRegistrationDelegate
|
||||
|
||||
作为 Delegate 提供了 静态方法 invokeBeanFactoryPostProcessors。
|
||||
|
||||
主要是将beanFactory和beanFactoryPostProcessors做matching,
|
||||
然后对beanFactoryPostProcessors做遍历调用postProcessBeanFactory(beanFactory)
|
||||
|
||||
## ConfigurationClassPostProcessor
|
||||
|
||||
postProcessBeanFactory(beanFactory)
|
||||
|
||||
processConfigBeanDefinitions(beanFactory)
|
||||
|
||||
核心的 处理方法,
|
||||
|
||||
---
|
||||
|
||||
## 14. Spring Aop
|
||||
|
||||
<sub>bid: `2022122715594900000000000012`</sub>
|
||||
|
||||
## Aop
|
||||
Aspect Oriented Programming的缩写,意为:面向切面编程。
|
||||
Spring aop 作为spring的一个模块,在springboot中是在bean的实例化中使用的。
|
||||
|
||||
AbstractAutowireCapableBeanFactory#initializeBean
|
||||
|
||||
|
||||
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
invokeAwareMethods(beanName, bean);
|
||||
return null;
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
# 实现了Aware接口<BeanNameAware><BeanClassLoaderAware><BeanFactoryAware>会invoke对应的set方法。
|
||||
invokeAwareMethods(beanName, bean);
|
||||
}
|
||||
|
||||
Object wrappedBean = bean;
|
||||
if (mbd == null || !mbd.isSynthetic()) {
|
||||
# beanPostProcesser的before方法。
|
||||
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
|
||||
}
|
||||
|
||||
try {
|
||||
# 实现了InitializingBean接口的会invoke afterPropertiesSet方法。
|
||||
invokeInitMethods(beanName, wrappedBean, mbd);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(
|
||||
(mbd != null ? mbd.getResourceDescription() : null),
|
||||
beanName, "Invocation of init method failed", ex);
|
||||
}
|
||||
if (mbd == null || !mbd.isSynthetic()) {
|
||||
# beanPostProcesser的after方法。
|
||||
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
|
||||
}
|
||||
|
||||
return wrappedBean;
|
||||
}
|
||||
|
||||
AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
|
||||
// Ignore AOP infrastructure such as scoped proxies.
|
||||
return bean;
|
||||
}
|
||||
|
||||
if (bean instanceof Advised) {
|
||||
Advised advised = (Advised) bean;
|
||||
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
|
||||
// Add our local Advisor to the existing proxy's Advisor chain...
|
||||
if (this.beforeExistingAdvisors) {
|
||||
advised.addAdvisor(0, this.advisor);
|
||||
}
|
||||
else {
|
||||
advised.addAdvisor(this.advisor);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEligible(bean, beanName)) {
|
||||
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
|
||||
if (!proxyFactory.isProxyTargetClass()) {
|
||||
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
|
||||
}
|
||||
proxyFactory.addAdvisor(this.advisor);
|
||||
customizeProxyFactory(proxyFactory);
|
||||
|
||||
// Use original ClassLoader if bean class not locally loaded in overriding class loader
|
||||
ClassLoader classLoader = getProxyClassLoader();
|
||||
if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {
|
||||
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
|
||||
}
|
||||
# ProxyFactory 其实就是创建动态代理或者Cglib的 InvocationHandler调用Proxy.newProxyInstance返回代理对象
|
||||
return proxyFactory.getProxy(classLoader);
|
||||
}
|
||||
|
||||
// No proxy needed.
|
||||
return bean;
|
||||
}
|
||||
|
||||
---
|
||||
@@ -0,0 +1,745 @@
|
||||
# Kubernetes 最佳实践
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2022050319356100000000000001` · 排序:4 · 文章数:8
|
||||
|
||||
## 目录
|
||||
|
||||
1. [Mongo Replica 集群搭建](#mongo-replica-集群搭建)
|
||||
2. [kubernetes nfs](#kubernetes-nfs)
|
||||
3. [Mongo Replica 集群搭建-1](#mongo-replica-集群搭建-1)
|
||||
4. [kubernetes](#kubernetes)
|
||||
5. [kubeadm](#kubeadm)
|
||||
6. [kubernetes containerd](#kubernetes-containerd)
|
||||
7. [新增加work节点](#新增加work节点)
|
||||
8. [kubelet](#kubelet)
|
||||
|
||||
---
|
||||
|
||||
## 1. Mongo Replica 集群搭建
|
||||
|
||||
<sub>bid: `2023033021115000000000000029`</sub>
|
||||
|
||||
## Replica Set 集群搭建
|
||||
本篇文章记录了基于mongodb-kubernetes-operator【Replica Set】模式集群搭建。
|
||||
[1]()
|
||||
[2](https://github.com/mongodb/mongodb-kubernetes-operator)
|
||||
[3](https://github.com/mongodb/mongodb-kubernetes-operator/blob/master/docs/install-upgrade.md#install-the-operator-using-kubectl)
|
||||
|
||||
### 1. 事前准备
|
||||
|
||||
> kubernetes 版本: 1.23.9
|
||||
> mongodb 版本:6.0.2
|
||||
> nfs: 提前搭建好了kubernetes的nfs系统(具体搭建可以参照)。
|
||||
|
||||
### 2. github项目mongodb-kubernetes-operator
|
||||
|
||||
[项目地址](https://github.com/mongodb/mongodb-kubernetes-operator)
|
||||
|
||||
我们使用mongodb 官网推荐的 mongodb-kubernetes-operator 来进行集群安装。
|
||||
[document](https://github.com/mongodb/mongodb-kubernetes-operator/blob/master/docs/install-upgrade.md#install-the-operator-using-kubectl)
|
||||
|
||||
我们事先把 mongodb-kubernetes-operator 项目中我们要使用的yaml文件复制到我们的工作目录 mongo, 需要的文件夹如下:
|
||||
|
||||
+ mongo
|
||||
+ config/crd/bases/
|
||||
+ config/rbac/
|
||||
+ config/manager/
|
||||
+ config/samples/mongodb.com_v1_mongodbcommunity_cr.yaml
|
||||
+ deploy/clusterwide/
|
||||
|
||||
$ pwd
|
||||
/usr/local/kubernetes/mongo
|
||||
$ ls
|
||||
config deploy
|
||||
|
||||
### 3. 按照document依次进行安装
|
||||
#### 3.1 创建 mongodb 使用的namespace
|
||||
|
||||
kubectl create ns kube-mongo
|
||||
|
||||
#### 3.2 创建集群rbac 权限
|
||||
|
||||
# 修改 deploy/clusterwide/cluster_role_binding.yaml 中namespace 为 3.1 中我我们创建的 [kube-mongo]
|
||||
kubectl apply -f deploy/clusterwide
|
||||
kubectl apply -k config/rbac --namespace kube-mongo
|
||||
|
||||
#### 3.3 创建 crd
|
||||
|
||||
kubectl apply -f config/crd/bases/mongodbcommunity.mongodb.com_mongodbcommunity.yaml
|
||||
|
||||
#### 3.4 安装operator
|
||||
|
||||
kubectl create -f config/manager/manager.yaml --namespace kube-mongo
|
||||
|
||||
#### 3.5 安装mongodb
|
||||
修改 config/samples/mongodb.com_v1_mongodbcommunity_cr.yaml文件
|
||||
- 修改 MongoDBCommunity 资源
|
||||
我们修改 metadata.name=violin-mongodb
|
||||
我们修改 spec.version= "6.0.2"
|
||||
我们修改 spec.users.name[0].passwordSecretRef.name= kube-mongo-pw
|
||||
- 修改 Secret 资源
|
||||
我们修改 metadata.name= kube-mongo-pw
|
||||
我们修改 stringData.password= "任意随意写了吧"
|
||||
|
||||
然后进行安装
|
||||
|
||||
kubectl apply -f config/samples/mongodb.com_v1_mongodbcommunity_cr.yaml --namespace kube-mongo
|
||||
|
||||
#### 3.6 重新创建pvc
|
||||
由于我使用的是自定义的storageclass,pvc 处于 pending状态,我们删除掉pvc
|
||||
|
||||
kubectl delete pvc data-volume-violin-mongodb-0 -n kube-mongo
|
||||
kubectl delete pvc logs-volume-violin-mongodb-0 -n kube-mongo
|
||||
|
||||
我们创建新的pvc定义文件:
|
||||
|
||||
# pvc.yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: data-volume-violin-mongodb-0
|
||||
namespace: kube-mongo
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: managed-nfs-storage
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: data-volume-violin-mongodb-1
|
||||
namespace: kube-mongo
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: managed-nfs-storage
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: data-volume-violin-mongodb-2
|
||||
namespace: kube-mongo
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: managed-nfs-storage
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: logs-volume-violin-mongodb-0
|
||||
namespace: kube-mongo
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
storageClassName: managed-nfs-storage
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: logs-volume-violin-mongodb-1
|
||||
namespace: kube-mongo
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
storageClassName: managed-nfs-storage
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: logs-volume-violin-mongodb-2
|
||||
namespace: kube-mongo
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
storageClassName: managed-nfs-storage
|
||||
|
||||
我们 创建 pvc
|
||||
|
||||
kubectl apply -f pvc.yaml
|
||||
# 查看pvc 是否已
|
||||
kubectl get pvc -n kube-mongo
|
||||
kube-mongo data-volume-violin-mongodb-0 Bound pvc-1ac1a5fd-389c-496d-a47c-7df11d5f5a34 10Gi RWO managed-nfs-storage 41m
|
||||
kube-mongo data-volume-violin-mongodb-1 Bound pvc-39008253-8702-4cc5-876a-0561850929bb 10Gi RWO managed-nfs-storage 61m
|
||||
kube-mongo data-volume-violin-mongodb-2 Bound pvc-a7e867d3-b499-486a-9b39-a42ac5a00b43 10Gi RWO managed-nfs-storage 61m
|
||||
kube-mongo logs-volume-violin-mongodb-0 Bound pvc-209ed46c-d558-4a09-8a2f-edfddbed610c 1Gi RWO managed-nfs-storage 41m
|
||||
kube-mongo logs-volume-violin-mongodb-1 Bound pvc-664b307f-ab95-4af3-8851-17a3ecd2b57c 1Gi RWO managed-nfs-storage 61m
|
||||
kube-mongo logs-volume-violin-mongodb-2 Bound pvc-a8f3a8d2-337d-4470-9ef4-5dbe18a4100a 1Gi RWO managed-nfs-storage 61m
|
||||
|
||||
### 4. 关于删除资源的问题。
|
||||
我们创建operator 或者 statefuset 出错的时候,可以重新删除他们。
|
||||
|
||||
#### 4.1 删除 operator
|
||||
|
||||
kubectl delete deployments.apps mongodb-kubernetes-operator -n kube-mongo
|
||||
|
||||
#### 4.1 删除 statefulset
|
||||
|
||||
kubectl delete statefulsets.apps violin-mongodb -n kube-mongo
|
||||
|
||||
### 5. 关于 mongosh的使用
|
||||
|
||||
kubectl get secret <connection-string-secret-name> -n <my-namespace> -o json | jq -r '.data | with_entries(.value |= @base64d)'
|
||||
|
||||
kubectl get secret violin-mongodb-admin-my-user -n kube-mongo -o json | jq -r '.data | with_entries(.value |= @base64d)'
|
||||
|
||||
---
|
||||
|
||||
## 2. kubernetes nfs
|
||||
|
||||
<sub>bid: `2023040608509800000000000030`</sub>
|
||||
|
||||
## 1 概述
|
||||
---
|
||||
  本篇文章记录了violin-home网站NFS系统搭建过程。
|
||||
采用腾讯云的3台公网云轻量服务器(ubuntu系统)
|
||||
> NFS服务需要开启 mountd,nfs,nlockmgr,portmapper,rquotad这5个服务.
|
||||
|
||||
  其中
|
||||
|
||||
# 查看服务使用端口
|
||||
# nfs : 2049
|
||||
# portmapper: 111
|
||||
# mountd, nlockmgr, rquotad 是随机的
|
||||
|
||||
# 所以事先要做好端口规划, 在轻量云服务器上开放对应的端口.
|
||||
```bash
|
||||
rpcinfo -p
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 2 nfs 服务器搭建
|
||||
---
|
||||
|
||||
# install server
|
||||
apt-get install nfs-kernel-server
|
||||
|
||||
# enable and start server
|
||||
systemctl enable nfs-server
|
||||
systemctl start nfs-server
|
||||
|
||||
# confirm nfs-server status
|
||||
|
||||
# create storage
|
||||
mkdir -p /data/nfs-volume && chmod -R 777 /data/nfs-volume
|
||||
|
||||
# edit config file
|
||||
cat > /etc/exports << EOF
|
||||
/data/nfs-volume 49.233.4.79(rw,sync,no_root_squash) 43.138.55.43(rw,sync,no_root_squash) 43.138.73.106(rw,sync,no_root_squash)
|
||||
EOF
|
||||
|
||||
# view nfs port usage
|
||||
rpcinfo -p
|
||||
|
||||
# set port infomation for mountd、rquotad ser
|
||||
# edit nfs-common status
|
||||
vi /etc/default/nfs-common
|
||||
STATDOPTS="--port 31000"
|
||||
|
||||
# edit nfs-kernel-server status
|
||||
vi /etc/default/nfs-kernel-server
|
||||
RPCMOUNTDOPTS="--manage-gids -p 31001"
|
||||
|
||||
# edit nlockmgr ,就算进行了这一步操作,也可能不生效。
|
||||
vi /etc/modprobe.d/options.conf
|
||||
options lockd nlm_udpport=31002 nlm_tcpport=31002
|
||||
|
||||
# to add locked
|
||||
vi /etc/modules
|
||||
|
||||
# /etc/modules: kernel modules to load at boot time.
|
||||
#
|
||||
# This file contains the names of kernel modules that should be loaded
|
||||
# at boot time, one per line. Lines beginning with "#" are ignored.
|
||||
lockd
|
||||
|
||||
vi /etc/sysctl.conf
|
||||
fs.nfs.nlm_udpport=31002
|
||||
fs.nfs.nlm_tcpport=31002
|
||||
|
||||
# enable sysctl.conf
|
||||
/sbin/sysctl -p
|
||||
|
||||
# reload server and service
|
||||
systemctl reload nfs-server
|
||||
systemctl restart rpcbind.service
|
||||
systemctl restart nfs.service
|
||||
|
||||
# view nfs port usage again
|
||||
rpcinfo -p
|
||||
|
||||
# to confirm client ip
|
||||
showmount -e 49.233.4.79
|
||||
# Export list for 49.233.4.79:
|
||||
# /data/nfs-volume 43.138.73.106,43.138.55.43,49.233.4.79
|
||||
|
||||
## 3 nfs 客户端搭建
|
||||
---
|
||||
  下面操作需要在每台node上操作,包括master节点。
|
||||
|
||||
# install client
|
||||
apt-get install nfs-common
|
||||
|
||||
# create mount path for client(we use different path to server)
|
||||
mkdir /opt/nfs-volume
|
||||
|
||||
# mount
|
||||
mount -t nfs 49.233.4.79:/data/nfs-volume /opt/nfs-volume
|
||||
df -h | tail -1
|
||||
|
||||
# config auto mount for client
|
||||
cat >> /etc/fstab << EOF
|
||||
49.233.4.79:/data/nfs-volume /opt/nfs-volume defaults,_netdev 0 0
|
||||
EOF
|
||||
|
||||
## 4
|
||||
|
||||
---
|
||||
|
||||
## 3. Mongo Replica 集群搭建-1
|
||||
|
||||
<sub>bid: `2023040623407900000000000031`</sub>
|
||||
|
||||
## Replica Set 集群搭建
|
||||
本篇文章记录了基于 helm bitnami/mongodb chat的【Replica Set】模式集群搭建。
|
||||
|
||||
[参照文档](https://github.com/bitnami/charts/tree/main/bitnami/mongodb)
|
||||
|
||||
### 1. 事前准备
|
||||
|
||||
> kubernetes 版本: 1.23.9
|
||||
> mongodb 版本:6.0.2
|
||||
> nfs: 提前搭建好了kubernetes的nfs系统(具体搭建可以参照)。
|
||||
> storageclass: 提前准备好了基于nfs的storageclass。
|
||||
> helm: 已经安装了helm
|
||||
|
||||
### 2. 添加bitnami repo
|
||||
|
||||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||||
|
||||
### 3. 查询 mongodb 相关资源
|
||||
|
||||
helm repo update
|
||||
helm search repo mongodb
|
||||
|
||||
NAME CHART VERSION APP VERSION DESCRIPTION
|
||||
bitnami/mongodb 13.9.4 6.0.5 MongoDB(R) is a relational open source NoSQL da...
|
||||
bitnami/mongodb-sharded 6.3.3 6.0.5 MongoDB(R) is an open source NoSQL database tha...
|
||||
|
||||
### 4. 创建helm 配置文件
|
||||
|
||||
## values.yaml
|
||||
global:
|
||||
namespaceOverride: kube-mongo
|
||||
storageClass: "managed-nfs-storage"
|
||||
nameOverride: violin-mongo
|
||||
image:
|
||||
pullPolicy: IfNotPresent
|
||||
architecture: "replicaset"
|
||||
replicaCount: 3
|
||||
#auth:
|
||||
# rootUser: "root"
|
||||
# rootPassword: "123654"
|
||||
# usernames:
|
||||
# - "guan"
|
||||
# passwords:
|
||||
# - "83201048"
|
||||
# databases:
|
||||
# - "violin"
|
||||
resources:
|
||||
requests:
|
||||
cpu: "0.2"
|
||||
memory: 200M
|
||||
limits:
|
||||
cpu: "0.3"
|
||||
memory: 300M
|
||||
containerPorts:
|
||||
mongodb: 27017
|
||||
externalAccess:
|
||||
enabled: true
|
||||
service:
|
||||
externalTrafficPolicy: "Cluster"
|
||||
type: "ClusterIP"
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 5Gi
|
||||
|
||||
### 5. 安装 mongodb
|
||||
|
||||
helm install mongodb bitnami/mongodb -f values.yaml
|
||||
|
||||
NAME: mongodb
|
||||
LAST DEPLOYED: Fri Apr 7 11:49:07 2023
|
||||
NAMESPACE: default
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
NOTES:
|
||||
CHART NAME: mongodb
|
||||
CHART VERSION: 13.9.4
|
||||
APP VERSION: 6.0.5
|
||||
|
||||
** Please be patient while the chart is being deployed **
|
||||
|
||||
MongoDB® can be accessed on the following DNS name(s) and ports from within your cluster:
|
||||
|
||||
mongodb-violin-mongo-0.mongodb-violin-mongo-headless.kube-mongo.svc.cluster.local:27017
|
||||
mongodb-violin-mongo-1.mongodb-violin-mongo-headless.kube-mongo.svc.cluster.local:27017
|
||||
mongodb-violin-mongo-2.mongodb-violin-mongo-headless.kube-mongo.svc.cluster.local:27017
|
||||
|
||||
To get the root password run:
|
||||
|
||||
export MONGODB_ROOT_PASSWORD=$(kubectl get secret --namespace kube-mongo mongodb-violin-mongo -o jsonpath="{.data.mongodb-root-password}" | base64 -d)
|
||||
|
||||
To get the password for "guan" run:
|
||||
|
||||
export MONGODB_PASSWORD=$(kubectl get secret --namespace kube-mongo mongodb-violin-mongo -o jsonpath="{.data.mongodb-passwords}" | base64 -d | awk -F',' '{print $1}')
|
||||
|
||||
To connect to your database, create a MongoDB® client container:
|
||||
|
||||
kubectl run --namespace kube-mongo mongodb-violin-mongo-client --rm --tty -i --restart='Never' --env="MONGODB_ROOT_PASSWORD=$MONGODB_ROOT_PASSWORD" --image docker.io/bitnami/mongodb:6.0.5-debian-11-r4 --command -- bash
|
||||
|
||||
Then, run the following command:
|
||||
mongosh admin --host "mongodb-violin-mongo-0.mongodb-violin-mongo-headless.kube-mongo.svc.cluster.local:27017,mongodb-violin-mongo-1.mongodb-violin-mongo-headless.kube-mongo.svc.cluster.local:27017,mongodb-violin-mongo-2.mongodb-violin-mongo-headless.kube-mongo.svc.cluster.local:27017" --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD
|
||||
|
||||
To connect to your database nodes from outside, you need to add both primary and secondary nodes hostnames/IPs to your Mongo client. To obtain them, follow the instructions below:
|
||||
|
||||
|
||||
### 6. connect
|
||||
|
||||
db.createUser({user: "root", pwd: "123654", roles: ["root"]})
|
||||
|
||||
---
|
||||
|
||||
## 4. kubernetes
|
||||
|
||||
<sub>bid: `2023040717276500000000000032`</sub>
|
||||
|
||||
## kubernetes 1.25.2 base Containerd
|
||||
|
||||
### 1. deploy schedule
|
||||
NAME | IP | ROLES | VERSION | OS
|
||||
k8s-master | 192.168.8.30 | master | 1.25.2 | ubuntu 22.04
|
||||
k8s-node1 | 192.168.8.31 | worker | 1.25.2 | ubuntu 22.04
|
||||
k8s-node2 | 192.168.8.32 | worker | 1.25.2 | ubuntu 22.04
|
||||
|
||||
### 2. preparation
|
||||
|
||||
#### 2.1 安装系统工具
|
||||
```bash
|
||||
apt-get update && apt-get install -y apt-transport-https
|
||||
```
|
||||
#### 2.2 安装 GPG 证书
|
||||
```bash
|
||||
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
|
||||
```
|
||||
#### 2.3 写入软件源
|
||||
```bash
|
||||
cat << EOF >/etc/apt/sources.list.d/kubernetes.list
|
||||
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
|
||||
EOF
|
||||
```
|
||||
#### 2.4 vi hostname
|
||||
```bash
|
||||
vi /etc/hostname
|
||||
vi /etc/hosts
|
||||
reboot
|
||||
```
|
||||
#### 2.5 selinux
|
||||
```bash
|
||||
sudo setenforce 0
|
||||
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
|
||||
```
|
||||
#### 2.6 禁用交换分区
|
||||
```bash
|
||||
swapoff -a
|
||||
sed -ri 's/.*swap.*/#&/' /etc/fstab
|
||||
```
|
||||
#### 2.7 iptables
|
||||
```bash
|
||||
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
vi /etc/sysctl.conf
|
||||
net.ipv4.ip_forward = 1
|
||||
|
||||
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
|
||||
net.bridge.bridge-nf-call-ip6tables = 1
|
||||
net.bridge.bridge-nf-call-iptables = 1
|
||||
EOF
|
||||
|
||||
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
|
||||
br_netfilter
|
||||
EOF
|
||||
|
||||
sudo sysctl --system
|
||||
```
|
||||
#### 2.8
|
||||
|
||||
### 3 install kubectl kubelet kebeadm
|
||||
#### 3.1 install
|
||||
```bash
|
||||
apt-get install -y kubelet=1.25.2-00 kubeadm=1.25.2-00 kubectl=1.25.2-00
|
||||
```
|
||||
### 4 Containerd
|
||||
#### 4.1 install Containerd
|
||||
```bash
|
||||
apt-get install containerd.io
|
||||
```
|
||||
#### 4.2 generate config file
|
||||
```bash
|
||||
containerd config default | sudo tee /etc/containerd/config.toml
|
||||
```
|
||||
#### 4.3 edit config.toml
|
||||
```bash
|
||||
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
|
||||
SystemdCgroup = true
|
||||
```
|
||||
#### 4.4 restart
|
||||
```bash
|
||||
systemctl restart containerd && systemctl enable containerd
|
||||
crictl version
|
||||
```
|
||||
#### 4.5 edit crictl.yaml
|
||||
```bash
|
||||
runtime-endpoint: unix:///run/containerd/containerd.sock
|
||||
image-endpoint: unix:///run/containerd/containerd.sock
|
||||
timeout: 10
|
||||
debug: false
|
||||
```
|
||||
#### 4.6 confirm crictl
|
||||
```bash
|
||||
crictl images
|
||||
```
|
||||
### 5 kubeadm
|
||||
|
||||
#### 5.1 kubeadm init
|
||||
```bash
|
||||
kubeadm init --kubernetes-version=1.25.2 \
|
||||
--apiserver-advertise-address=192.168.8.30 \
|
||||
--apiserver-bind-port=6443 \
|
||||
--image-repository=registry.aliyuncs.com/google_containers \
|
||||
--service-cidr=10.96.0.0/12 \
|
||||
--cri-socket unix:///var/run/containerd/containerd.sock \
|
||||
--ignore-preflight-errors=Swap \
|
||||
--control-plane-endpoint=k8s-master \
|
||||
--upload-certs
|
||||
```
|
||||
```
|
||||
Your Kubernetes control-plane has initialized successfully!
|
||||
|
||||
To start using your cluster, you need to run the following as a regular user:
|
||||
|
||||
mkdir -p $HOME/.kube
|
||||
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
||||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||
|
||||
Alternatively, if you are the root user, you can run:
|
||||
|
||||
export KUBECONFIG=/etc/kubernetes/admin.conf
|
||||
|
||||
You should now deploy a pod network to the cluster.
|
||||
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
|
||||
https://kubernetes.io/docs/concepts/cluster-administration/addons/
|
||||
|
||||
You can now join any number of the control-plane node running the following command on each as root:
|
||||
|
||||
kubeadm join k8s-master:6443 --token 81jkv9.2n555fci6m6i9afx \
|
||||
--discovery-token-ca-cert-hash sha256:9ffe6e7ed7cf4ad6eb0e0dbb5b6f3bae1cac6989c3870653c83fe424715b4008 \
|
||||
--control-plane --certificate-key c16ea4431de14998ccb28282b5e6215ab03c9ba94287903c6a8482add718034a
|
||||
|
||||
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
|
||||
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
|
||||
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
|
||||
|
||||
Then you can join any number of worker nodes by running the following on each as root:
|
||||
|
||||
kubeadm join k8s-master:6443 --token 81jkv9.2n555fci6m6i9afx \
|
||||
--discovery-token-ca-cert-hash sha256:9ffe6e7ed7cf4ad6eb0e0dbb5b6f3bae1cac6989c3870653c83fe424715b4008
|
||||
```
|
||||
#### 5.2 kubeconfig
|
||||
```bash
|
||||
mkdir -p $HOME/.kube
|
||||
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
||||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||
export KUBECONFIG=/etc/kubernetes/admin.conf
|
||||
```
|
||||
#### 5.3 kubectl
|
||||
```bash
|
||||
kubectl get noe
|
||||
```
|
||||
```
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
k8s-master NotReady control-plane 135m v1.25.2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. kubeadm
|
||||
|
||||
<sub>bid: `2023041008541300000000000036`</sub>
|
||||
|
||||
## 1. xxx
|
||||
|
||||
22.04.1-Ubuntu
|
||||
|
||||
```bash
|
||||
cat << EOF >/etc/apt/sources.list.d/kubernetes.list
|
||||
deb https://mirrors.aliyun.com/kubernetes/apt/kubernetes-xenial main
|
||||
EOF
|
||||
```
|
||||
```bash
|
||||
apt-get update
|
||||
apt-get install -y kubelet=1.25.2-00 kubeadm=1.25.2-00 kubectl=1.25.2-00
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo setenforce 0
|
||||
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
|
||||
```
|
||||
|
||||
临时关闭swap分区,当前会话生效,重启失效
|
||||
永久关闭swap分区
|
||||
```bash
|
||||
swapoff -a
|
||||
sed -ri 's/.*swap.*/#&/' /etc/fstab
|
||||
```
|
||||
```bash
|
||||
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
|
||||
net.bridge.bridge-nf-call-ip6tables = 1
|
||||
net.bridge.bridge-nf-call-iptables = 1
|
||||
EOF
|
||||
|
||||
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
|
||||
br_netfilter
|
||||
EOF
|
||||
|
||||
sudo sysctl --system
|
||||
```
|
||||
|
||||
```bash
|
||||
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
vi /etc/sysctl.conf
|
||||
net.ipv4.ip_forward = 1
|
||||
```
|
||||
|
||||
```bash
|
||||
cat > /etc/sysconfig/network-scripts/ifcfg-eth0 <<EOF
|
||||
BOOTPROTO=static
|
||||
DEVICE=eth0
|
||||
IPADDR=172.16.0.11
|
||||
PREFIX=32
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
ONBOOT=yes
|
||||
EOF
|
||||
```
|
||||
vi /etc/hosts
|
||||
```bash
|
||||
echo "######## edit /etc/hosts ########"
|
||||
echo "" >> /etc/hosts
|
||||
echo 192.168.8.30 k8s-master >> /etc/hosts
|
||||
echo 192.168.8.31 k8s-node1 >> /etc/hosts
|
||||
echo 192.168.8.32 k8s-node2 >> /etc/hosts
|
||||
```
|
||||
|
||||
## about docker and cri-dockerd
|
||||
|
||||
```bash
|
||||
docker pull golang:1.20.2
|
||||
```
|
||||
download cri-dockerd
|
||||
```bash
|
||||
echo "######### https://github.com/Mirantis/cri-dockerd/releases/tag/v0.3.2 ########'
|
||||
tar -zxvf cri-dockerd-0.3.2.tar.gz
|
||||
```
|
||||
|
||||
|
||||
```bash
|
||||
echo "######## chuangjian guazai dian ########"
|
||||
mkdir /data
|
||||
cd /data
|
||||
mkdir go
|
||||
cd go
|
||||
echo "######## download cri-dockerd ########"
|
||||
echo "######## https://github.com/Mirantis/cri-dockerd/releases/tag/v0.3.2 ########'
|
||||
echo "######## jieya ########"
|
||||
tar -zxvf cri-dockerd-0.3.2.tar.gz
|
||||
|
||||
echo "######## yunxing golang container ########"
|
||||
docker run -it -v /data/go:/data/go golang:1.20.2 /bin/sh
|
||||
```
|
||||
enter container
|
||||
```bash
|
||||
cd /data/go/cri-dockerd-0.3.2
|
||||
mkdir bin
|
||||
go build -o bin/cri-dockerd
|
||||
```
|
||||
out container
|
||||
|
||||
```bash
|
||||
cd /data/go/cri-dockerd-0.3.2
|
||||
install -o root -g root -m 0755 bin/cri-dockerd /usr/local/bin/cri-dockerd
|
||||
cp -a packaging/systemd/* /etc/systemd/system
|
||||
sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
|
||||
systemctl daemon-reload
|
||||
systemctl enable cri-docker.service
|
||||
systemctl enable --now cri-docker.socket
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. kubernetes containerd
|
||||
|
||||
<sub>bid: `2023041415557100000000000037`</sub>
|
||||
|
||||
## containerd
|
||||
|
||||
|
||||
|
||||
|
||||
## ctr
|
||||
|
||||
## crictl
|
||||
|
||||
## nerdctl
|
||||
|
||||
##
|
||||
|
||||
---
|
||||
|
||||
## 7. 新增加work节点
|
||||
|
||||
<sub>bid: `2023061019139700000000000038`</sub>
|
||||
|
||||
##
|
||||
|
||||
---
|
||||
|
||||
## 8. kubelet
|
||||
|
||||
<sub>bid: `2024042923524000000000000040`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
@@ -0,0 +1,487 @@
|
||||
# machine learning
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2022102117088800000000000001` · 排序:10 · 文章数:16
|
||||
|
||||
## 目录
|
||||
|
||||
1. [第二章 模型评估与选择](#第二章-模型评估与选择)
|
||||
2. [第一章 绪论](#第一章-绪论)
|
||||
3. [第三章 线性模型](#第三章-线性模型)
|
||||
4. [第四章 决策树](#第四章-决策树)
|
||||
5. [第五章 神经网络](#第五章-神经网络)
|
||||
6. [第七章 贝叶斯分类器](#第七章-贝叶斯分类器)
|
||||
7. [第六章 支持向量机](#第六章-支持向量机)
|
||||
8. [第八章 集成学习](#第八章-集成学习)
|
||||
9. [第十章 降维与度量学习](#第十章-降维与度量学习)
|
||||
10. [第九章 聚类](#第九章-聚类)
|
||||
11. [第十三章 半监督学习](#第十三章-半监督学习)
|
||||
12. [第十一章 特征选择与稀疏学习](#第十一章-特征选择与稀疏学习)
|
||||
13. [第十二章 计算学习理论](#第十二章-计算学习理论)
|
||||
14. [第十四章 概率图模型](#第十四章-概率图模型)
|
||||
15. [第十五章 规则学习](#第十五章-规则学习)
|
||||
16. [第十六章 强化学习](#第十六章-强化学习)
|
||||
|
||||
---
|
||||
|
||||
## 1. 第二章 模型评估与选择
|
||||
|
||||
<sub>bid: `2022102117084500000000000004`</sub>
|
||||
|
||||
## 2.1 经验误差与过拟合
|
||||
> 错误的样本数a占总样本数m的比例称为 错误率【error rate】E = a / m
|
||||
> 精度【accuracy】 = 1 - 错误率
|
||||
|
||||
> 我们把实际预测输出与样本的真实输出之间的差异称为 误差【error】
|
||||
在训练集上 的误差 称为训练误差【training error】
|
||||
在新样本上的误差 称为 泛化误差 generalization error
|
||||
> 过拟合【overfitting】,学习器把样本学的太好了,以至于把样本自身的一些特点当作所有潜在样本的都具有的一般性质,这样会导致generalization 泛化性能下降。
|
||||
> 欠拟合【underfitting】
|
||||
## 2.2 评估方法
|
||||
### 留出法【hold-out】
|
||||
直接将数据集D 划分为两个互斥的子集,S和T,其中S占大于2/3 - 4/5 左右,并且,尽量保证训练/测试的的数据划分在分布上是一致性的,避免在数据划分过程中引入额外的不必要的偏差,而对最终结果产生影响。
|
||||
使用留出法通常采用果敢此随即划分,重复实验后去均值作为评估结果。
|
||||
### 交叉验证法【cross validation】
|
||||
将数据集划分为k个大小相似的互斥子集,每个子集D<sub>i</sub>都尽可能保持数据分布的一致性,即从D中通过分层采样得到。然后用k-1个子集做训练,余下的1个子集做测试集,这样就可以获得k组训练/测试集,然后对这k次结果做均值。
|
||||
这种评估结果的稳定性和保真性极大程度上取决于k的取值。我们把这种交叉验证法称为k折交叉验证【k-fold cross validation】,k最常用的值为10,即10折交叉验证法。与hold-out method 相似,我们也是需要多次划分来取均值作为最后的评估结果。
|
||||
### 自助法【bootstrap】
|
||||
hold-out and cross validation method 使用的训练集比样本集少,必然引入了因为样本规模不同而导致的估计偏差,自助法bootstrap 是一个比较好的解决方案
|
||||
给定一个m个样本的数据集D,我们对它采样产生数据集D' ,每次随机从D中抽取一个样本,将其拷贝到D',重复mci后,我们得到了一个m个样本的数据集D'。
|
||||
样本在m次采样中始终不被采集到的概率为(1 - 1/m)<sup>m</sup> 取极限,可得 0.368
|
||||
自助法在数据集较小时,很有用。
|
||||
## 2.3 性能度量【performance measure】
|
||||
预测任务中,给定样例集D,要评价学习器f的性能,就是要把学习器预测结果f(x)与真实标记【label】y进行比较
|
||||
回归任务最常用的性能度量是 均方误差【mean squared error】
|
||||
|
||||
> E(f;D) = 1/m ・
|
||||
|
||||
---
|
||||
|
||||
## 2. 第一章 绪论
|
||||
|
||||
<sub>bid: `2022102117089200000000000003`</sub>
|
||||
|
||||
## 1.1 引言
|
||||
---
|
||||
> 学习算法,机械学习所要研究的主要内容,是关于计算机从数据中产生【模型model】的算法,模型 泛指 从数据中学得的结果。
|
||||
|
||||
---
|
||||
## 1.2 基本术语
|
||||
> 数据集【data set】
|
||||
> 样本【sample】或者 实例【instance】
|
||||
> 属性【attribute】 或者 特征【feature】
|
||||
> 属性值【attribute value】
|
||||
> 属性空间【attribute space】
|
||||
> 样本空间【sample space】
|
||||
> 学习【learning】从数据中学得模型的过程 为 学习【learning】或 训练【training】
|
||||
> 训练数据【training data】训练过程中使用的数据 为 训练数据【training data】
|
||||
> 训练样本【training sample】,训练数据中的每一个样本 成为 训练样本 【training sample】
|
||||
> 训练集 【training set】训练样本 组成的集合 为 训练集 【training set】
|
||||
> 假设【hypothesis】学得模型对应了关于数据的魔种潜在规律,即 假设【hypothesis】
|
||||
> 真相【ground-truth】这种潜在规律自身,则称为 真相【ground-truth】,学习的过程就是为了找出或者逼近真相。
|
||||
> 标记【label】,样本结果的信息,即标记【label】
|
||||
> 样例【example】,拥有了标记的实例,即为 样例【example】
|
||||
|
||||
*D* = {*x<sub>1<sub></sub></sub>*, *x<sub>2</sub>*, ...,*x<sub>n<sub></sub></sub>*} 具有n个实例的数据集
|
||||
(*x*<sub><sub>i</sub></sub>, *y*<sub>i</sub>)表示第i个样例。
|
||||
|
||||
> - 如果我们的预测的是离散值,此类学习的任务成为 分类【classification】
|
||||
> - 如果我们的预测是连续值,此类的学习任务成为回归【regression】
|
||||
> - 对于只涉及的两个类别的二分类【binary classification】任务,通常一个成为正类【positive class】另一个类为反类【negative class】
|
||||
> - 涉及到多个类别时,则成为多分类【multi-class classification】任务
|
||||
|
||||
> - 根据train set 中是否含有 label,学习任务分为 监督学习【supervised】 和 无监督学习【unsupervised learning】
|
||||
分类和回归是 监督学习, 而聚类是后者的代表。
|
||||
|
||||
---
|
||||
## 1.3 假设空间
|
||||
归纳【induction】和演绎【deduction】是科学推理的两大手段。
|
||||
归纳是从特殊到一般的泛化【generalization】的过程,即从具体的事实归结出一般性规律。
|
||||
演绎是从一般到特殊的特化【specialization】的过程,从基础原理推演出具体情况。
|
||||
版本空间【version space】,存在着一个与训练集一致的假设集合,我们称之为版本空间
|
||||
|
||||
---
|
||||
## 1.4 归纳偏好
|
||||
无论学习算法A多聪明,学习算法B多笨拙,他们的期望性能是相同的,这就是NFL定理,即没有免费的午餐定理
|
||||
NFL定理最重要的寓意是,如果考虑所有的潜在的问题,所有的学习算法都一样好,而算法的优劣必须建在具体的学习问题上。
|
||||
---
|
||||
### 1.5
|
||||
|
||||
---
|
||||
|
||||
## 3. 第三章 线性模型
|
||||
|
||||
<sub>bid: `2022112915369100000000000001`</sub>
|
||||
|
||||
## 3.1 基本模型(linear model)
|
||||
---
|
||||
给定由 $d$ 个属性描述得实例 ${\pmb{x}}$ $ = (x_{1}; x_{2};...; x_{d})$,其中$x_i$ 是 ${\pmb{x}}$ 在第 $i$ 个属性山对的取值。
|
||||
线性模型试图学得一个通过属性的 **线性组合** 来进行 预测的函数,即
|
||||
$$
|
||||
f(x) = w_1x_1 + w_2x_2 + ... + w_3x_3 + b , \tag{3.1}
|
||||
$$
|
||||
|
||||
一般用向量表示,写成
|
||||
$$
|
||||
f(x) = \pmb{w}^{\pmb{T}}\pmb{x} + b, \tag{3.2}
|
||||
$$
|
||||
其中${\pmb{w}}$ $ = (w_{1}; w_{2};...; w_{d})$。${\pmb{w}}$和b学得之后,模型就得以确定。
|
||||
|
||||
`※注意`
|
||||
`行向量用 "," ,而列向量用 ";"`
|
||||
|
||||
## 3.2 线性回归(linear regression)
|
||||
给定数据集$D = \{ (x_1, y_1), (x_1, y_1), ... (x_m, y_m) \}$,其中 $\pmb{x}_i = (x_{i1}; x_{i2};...; x_{id})$,$y_i \in R$。
|
||||
线性回归 试图学习得一个线性模型,来尽可能准确的预测真实值输出标记label。
|
||||
$$
|
||||
f(x_i) = \pmb{w}^{\pmb{T}}\pmb{x_i} + b, \text{ 使得} f(x_i) \simeq y_i
|
||||
\tag{3.3}
|
||||
$$
|
||||
|
||||
如何确定 $w$ 和 $b$ 呢,通过2.3节的介绍过,均方误差(2.2)是回归任务中最常用的性能度量,因此我们试图让均方误差最小化。即,最小二乘法。
|
||||
即
|
||||
$$
|
||||
(w^*, b*) = arg\,min \sum_{i=1}^{m} (f(x_i) - y_i)^2
|
||||
$$
|
||||
$$
|
||||
= arg\,min \sum_{i=1}^{m} (y_i - wx_i -b)^2
|
||||
$$
|
||||
$$
|
||||
= arg\,min \sum_{i=1}^{m} [(y_i-b)^2 + w^2x_i^2 - 2wx_iy_i]
|
||||
$$
|
||||
$$
|
||||
= arg\,min \sum_{i=1}^{m} [(y_i-b)^2 + w^2x_i^2 - 2wx_iy_i]
|
||||
$$
|
||||
|
||||
均方误差有非常好的几何意义,他应对了常用的欧几里得几何定理。
|
||||
|
||||
而对于多元线性回归,我们把 $\pmb{w}$ 和 $b$ 吸收入向量形式 $\hat{ \pmb{w} } = (\pmb{w};b)$, 即 $\hat{ \pmb{w} } = (w_1;w_2;...;w_d;b)$,即 d + 1 列。
|
||||
对于数据集$D$,我们将它表示为一个 $m \times (d + 1)$ 大小矩阵 $ X $,用以方便进行 $ \pmb{w}^{\pmb{T}}\pmb{x} + b$ 相乘。
|
||||
$$
|
||||
\pmb{X}=\begin{pmatrix}
|
||||
x_{11} & x_{12} & \cdots & x_{1d} & 1\\
|
||||
x_{21} & x_{22} & \cdots & x_{2d} & 1\\
|
||||
\vdots & \vdots & \ddots & \vdots & 1\\
|
||||
x_{m1} & x_{m2} & \cdots & x_{md} & 1\\
|
||||
\end{pmatrix} = \begin{pmatrix}
|
||||
\pmb{x}_{1}^T & 1\\
|
||||
\pmb{x}_{2}^T & 1\\
|
||||
\vdots & 1\\
|
||||
\pmb{x}_{m}^T & 1\\
|
||||
\end{pmatrix}
|
||||
$$
|
||||
注意,这里的 $\pmb{x}_i$ 是列向量,转置后就是行向量了。
|
||||
这样
|
||||
$$
|
||||
\pmb{X}\hat{ \pmb{w} } = \begin{pmatrix}
|
||||
x_{11} & x_{12} & \cdots & x_{1d} & 1\\
|
||||
x_{21} & x_{22} & \cdots & x_{2d} & 1\\
|
||||
\vdots & \vdots & \ddots & \vdots & 1\\
|
||||
x_{m1} & x_{m2} & \cdots & x_{md} & 1\\
|
||||
\end{pmatrix}\begin{pmatrix}
|
||||
w_{1} \\
|
||||
w_{2} \\
|
||||
\vdots \\
|
||||
w_{d} \\
|
||||
b \\
|
||||
\end{pmatrix} = \begin{pmatrix}
|
||||
\pmb{x}_{1}^T & 1\\
|
||||
\pmb{x}_{2}^T & 1\\
|
||||
\vdots & 1\\
|
||||
\pmb{x}_{m}^T & 1\\
|
||||
\end{pmatrix}\begin{pmatrix}
|
||||
\pmb{w} \\
|
||||
b \\
|
||||
\end{pmatrix}
|
||||
$$
|
||||
|
||||
再把标记也写成向量形式 $y = (y_1;y_2;...;y_m)$, 有
|
||||
$$
|
||||
\hat{\pmb{w}}^* = arg \, min (\pmb{y} - \pmb{X} \hat{\pmb{w}})^T(\pmb{y} - \pmb{X} \hat{\pmb{w}}) \tag{3.9}
|
||||
$$
|
||||
令 $E_{\hat{w}} = (\pmb{y} - \pmb{X} \hat{\pmb{w}})^T(\pmb{y} - \pmb{X} \hat{\pmb{w}})$, 对 $\hat{ \pmb{w} }$ 求导得到
|
||||
$$
|
||||
\frac{\partial E_{\hat{w}}}{\partial \hat{\pmb{w}}} = 2 \, \pmb{X}^T(\pmb{X}\hat{\pmb{w}} -\pmb{y}) \tag{3.10}
|
||||
$$
|
||||
令上式为0,可得 $\hat{ \pmb{w} }$ 最优解的闭式解
|
||||
|
||||
`※闭式解也被称为解析解,是通过严格的公式所求得的解,即包含分式、三角函数、指数、对数甚至无限级数等基本函数的解的形式。通过给出解的具体函数形式,从解的表达式中就可以算出任何对应值。`
|
||||
|
||||
当 $\pmb{X}^T \pmb{X}$ 为满秩矩阵,可以直接令(3.10)为零即可得,
|
||||
$$
|
||||
\hat{\pmb{w}}^* = (\pmb{X}^T \pmb{X})^{-1}\pmb{X}\pmb{y}
|
||||
$$
|
||||
其中,$\pmb{X}^T \pmb{X})^{-1}$ 是矩阵 $\pmb{X}^T \pmb{X}$ 的逆矩阵。令$\hat{\pmb{x}}_i = (\pmb{x}_i; 1)$ 最终学得多元线性回归模型为
|
||||
$$
|
||||
f(\hat{\pmb{x}}_i) = {\hat{\pmb{x}}_i}^T(\pmb{X}^T \pmb{X})^{-1}\pmb{X}\pmb{y}
|
||||
$$
|
||||
|
||||
然后现实任务中,$\pmb{X}^T \pmb{X}$ 并不是满秩矩阵,例如在许多学习任务中我们会遇到大量的参数,其数量甚至超过样例数,导致 $\pmb{X}$ 列数多于行数,此时 $\pmb{X}^T \pmb{X}$ 显然不是满秩矩阵。
|
||||
此时可解出 $\hat{ \pmb{w} }$ , 他们都能是均方误差最小化,选择哪一个解作为输出将由学习算法的归纳偏好决定,常见的作法,就是**引入正则化项**(**regularization**)。
|
||||
|
||||
线性模型虽然简单,但是却有着丰富的变化,最简单就是将标记对数化,即将输出标记的对数作为线性模型逼近的目标
|
||||
$$
|
||||
\ln y = \pmb{w}^T \pmb{x} + b \tag{3.14}
|
||||
$$
|
||||
这就是 对数线性回归(log-linear regression),它实际上在试图让 $e^{\pmb{w}^T \pmb{x} + b}$逼近 $y$。(3.14) 在形式上仍是**线性回归**(linear regression), 但实质上是输入空间到输出空间的非线性的函数映射。
|
||||
|
||||
更一般的,考虑单调可微函数 $g(\cdot)$ ,令
|
||||
$$
|
||||
y = g^{-1}(\pmb{w}^T \pmb{x} + b) \tag{3.15}
|
||||
$$
|
||||
|
||||
这样就得到了 **广义线性模型** (**generalized linear model**) ,其中函数 $g(\cdot)$ 称为 **联系函数** (**link function**)。
|
||||
|
||||
## 3.3 对数几率回归
|
||||
|
||||
在第一章介绍过,我们知道预测的结果为离散的,我们称为分类(classification)任务,预测的结果是连续的,我们成为回归(regression)任务。
|
||||
上一节讨论了线性模型进行回归学习,但是若要做分类任务怎么办呢?答案蕴含在(3.15)的广义线性模型中:只需要找到一个单调可微函数将分类任务的真实标记 $y$ 与线性回归模型的预测值联系起来。
|
||||
|
||||
我们先考虑二分类任务(binary classification),其输出标记 $y \in \{ 0, 1 \}$,而线性回归模型产生的预测值是 $ z = \pmb{w}^T\pmb{x} + b$ 是实值,于是我们需要通过将 $z$ 转换为 0/1 的值。
|
||||
而最理想是 **单位阶跃函数**(unit-step function)
|
||||
$$
|
||||
f(n)=
|
||||
\begin{cases}
|
||||
0, & \text {$z < 0$} \\
|
||||
0.5, & \text {$z = 0$} \\
|
||||
1, & \text{$z > 0$}
|
||||
\end{cases} \tag{3.16}
|
||||
$$
|
||||
|
||||
单位阶跃函数不连续,不能作为 $g(\cdot)$ 的 反函数使用。于是我们希望,找到一个在一定程度近似于单位阶跃函数的代替函数,并希望他单调可微。**对数几率函数**(logistic function)正是这样的一个常用的替代函数。
|
||||
$$
|
||||
y = \frac{1}{1 + e^{-z}} \tag{3.17}
|
||||
$$
|
||||
将 $ z = \pmb{w}^T\pmb{x} + b$ 带入3.17中得到
|
||||
$$
|
||||
y = \frac{1}{1 + e^{-(\pmb{w}^T\pmb{x} + b)}} \tag{3.18}
|
||||
$$
|
||||
类似于3.14,对上式取对数,可变化为
|
||||
$$
|
||||
ln \frac{y}{1-y} = \pmb{w}^T\pmb{x} + b \tag{3.19}
|
||||
$$
|
||||
|
||||
若将 $y$ 视为样本 $x$ 为正例的可能性,那么 $1-y$则是反例可能性,两者的比值
|
||||
$$
|
||||
\frac{y}{1-y} \tag{3.20}
|
||||
$$
|
||||
称为 **几率**(odds),反映了 $x$ 为了正例的相对可能性,对几率取对数则得到 **对数几率**(log odds,或者logit)
|
||||
$$
|
||||
\ln\frac{y}{1-y} \tag{3.21}
|
||||
$$
|
||||
可以看出(3.18)实际上在用线性回归模型的预测结果去逼近真是标记的对数几率,因此,此模型称为 **对数几率模型** (logistic regression 或者 logit regression)
|
||||
|
||||
下面我们来看看如何确定式(3.18)中的 $\pmb{w}$ 和 $b$.若将y视为后验概率估计 $p(y=1|x)$,则式(3.19)可重写为
|
||||
$$
|
||||
ln \frac{p(y=1|x)}{p(y=0|x)} = \pmb{w}^T\pmb{x} + b \tag{3.22}
|
||||
$$
|
||||
显然有
|
||||
$$
|
||||
p(y=1|x) = \frac{e^{\pmb{w}^T\pmb{x} + b}}{1 + e^{\pmb{w}^T\pmb{x} + b}} \tag{3.23}
|
||||
$$
|
||||
$$
|
||||
p(y=0|x) = \frac{1}{1 + e^{\pmb{w}^T\pmb{x} + b}} \tag{3.24}
|
||||
$$
|
||||
于是,我们通过极大似然估计来估计$\pmb{w}$ 和 $b$.给定数据集$\{ (x_i, y_i) \}_{i=1}^m$,对数几率回归模型最大化"对数似然"
|
||||
|
||||
$$
|
||||
\ell(\pmb{w}, b) = \sum_{i=1}^{m} p(y_i| \pmb{x_i};\pmb{w},b) \tag{3.25}
|
||||
$$
|
||||
|
||||
|
||||
|
||||
|
||||
## 3.4 线性判断分析
|
||||
|
||||
## 3.5 多分类学习
|
||||
|
||||
## 3.6 类别不平衡问题
|
||||
|
||||
---
|
||||
|
||||
## 4. 第四章 决策树
|
||||
|
||||
<sub>bid: `2023011713085500000000000001`</sub>
|
||||
|
||||
## 4.1 basic flow
|
||||
|
||||
决策树 decision tree is a common machine learning method.
|
||||
|
||||
Generally, a decision tree contains a root node,several internal nodes and several leaf nodes。
|
||||
|
||||
a leaf node corresponds to decision result. the other nodes corresponds to a attribute test. The sample set contained in each node is divided into sub-nodes according to the result of attribute test. The root node contains the samples in the set.
|
||||
|
||||
|
||||
**Input** :
|
||||
|
||||
learning set, the count of sample set is m
|
||||
$$
|
||||
D = {(x_1, y_1), (x_2, y_2), ..., (x_m, y_m)}
|
||||
$$
|
||||
attribute set, the count of attribute set is d
|
||||
$$
|
||||
A = {a_1, a_2, ..., a_d}
|
||||
$$
|
||||
**Process**:
|
||||
function treeGenerate(D, A)
|
||||
1. generate node;
|
||||
2. if the kinds(y) in the node are same, we mark this node leaf node and return
|
||||
3. if A is empty or the value of D is same in A. we mark this node leaf node and return
|
||||
4. to choose the best divided attribute $a_*$
|
||||
5. for the value of $a_*$:
|
||||
6. to generate a node
|
||||
|
||||
|
||||
## 4.2 how to choose a divided method
|
||||
|
||||
### 4.2.1 information gain (信息增益)
|
||||
|
||||
信息熵 information entropy
|
||||
|
||||
$$
|
||||
Ent(D) = -\sum ^{|y|}_{k = 1} p_{k}log2p_{k}
|
||||
$$
|
||||
means that
|
||||
|
||||
信息增益 imformation gain
|
||||
|
||||
### 4.2.2 gain ratio(增益率)
|
||||
|
||||
信息增益 对可选数值数目较多的属性有所偏好,
|
||||
to reduce the possible adverse effect of this preference, the famous dicision tree algorithm **C4.5** does not use information gain directly, but use information gain ratio to select the optimal divided attributes.
|
||||
|
||||
represent it with:
|
||||
|
||||
$$
|
||||
Gain\_ratio(D, a) = \frac{Gain(D, a)}{IV(a)}
|
||||
$$
|
||||
|
||||
$$
|
||||
IV(a) = - \sum^{V}_{v = 1}\frac{D^v}{D}\log{2}\frac{D^v}{D}
|
||||
$$
|
||||
|
||||
需要注意的是增益率对可选择的属性值较少的具有偏好,所以C4.5并不是直接选择增益率最大的,而是先从划分属性中找到信息增益高出平均水平的,再从其中选择增益率最高的。
|
||||
|
||||
### 4.2.3 基尼指数
|
||||
|
||||
略
|
||||
## 4.3 减枝处理
|
||||
|
||||
剪枝是决策树学习算法对付过耦合的主要手段。
|
||||
|
||||
决策树的基本剪枝策略有预剪枝和后剪枝。
|
||||
|
||||
预剪枝是指在决策树生成过程中,对每个节点划分前进行估计,若当前节点的划分不能带来决策树泛化性能提升,则停止划分并将当前节点标记为叶节点;
|
||||
|
||||
后剪枝则是先从训练集生成一颗完整的决策树,然后自下而上地对非叶子节点考察,若将该节点对应的子树替换为叶子节点能带来决策树泛化性能提升,则将该子树替换成叶节点。
|
||||
|
||||
### 4.3.1 预剪枝
|
||||
|
||||
work flow:
|
||||
1. caculate
|
||||
|
||||
|
||||
### 4.3.2 后剪枝
|
||||
|
||||
|
||||
## 4.4 连续与缺失值
|
||||
|
||||
## 4.5 多变量决策树
|
||||
|
||||
---
|
||||
|
||||
## 5. 第五章 神经网络
|
||||
|
||||
<sub>bid: `2023011719438400000000000002`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 6. 第七章 贝叶斯分类器
|
||||
|
||||
<sub>bid: `2023011719441200000000000004`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 7. 第六章 支持向量机
|
||||
|
||||
<sub>bid: `2023011719441300000000000003`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 8. 第八章 集成学习
|
||||
|
||||
<sub>bid: `2023011719447400000000000005`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 9. 第十章 降维与度量学习
|
||||
|
||||
<sub>bid: `2023011719451200000000000007`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 10. 第九章 聚类
|
||||
|
||||
<sub>bid: `2023011719454000000000000006`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 11. 第十三章 半监督学习
|
||||
|
||||
<sub>bid: `2023011719460100000000000010`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 12. 第十一章 特征选择与稀疏学习
|
||||
|
||||
<sub>bid: `2023011719464700000000000008`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 13. 第十二章 计算学习理论
|
||||
|
||||
<sub>bid: `2023011719468000000000000009`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 14. 第十四章 概率图模型
|
||||
|
||||
<sub>bid: `2023011719469800000000000011`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 15. 第十五章 规则学习
|
||||
|
||||
<sub>bid: `2023011719472500000000000012`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
|
||||
## 16. 第十六章 强化学习
|
||||
|
||||
<sub>bid: `2023011719475600000000000013`</sub>
|
||||
|
||||
该写点什么么...
|
||||
|
||||
---
|
||||
@@ -0,0 +1,839 @@
|
||||
# probability and statistics
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2022102117130200000000000002` · 排序:11 · 文章数:6
|
||||
|
||||
## 目录
|
||||
|
||||
1. [1. 随机事件](#1-随机事件)
|
||||
2. [3. 随机变量的重要数字特征](#3-随机变量的重要数字特征)
|
||||
3. [2. 随机变量以及其分布率](#2-随机变量以及其分布率)
|
||||
4. [4. 参数估计](#4-参数估计)
|
||||
5. [5. 置信区间](#5-置信区间)
|
||||
6. [10. 线性回归分析和方差分析](#10-线性回归分析和方差分析)
|
||||
|
||||
---
|
||||
|
||||
## 1. 1. 随机事件
|
||||
|
||||
<sub>bid: `2022102117130400000000000005`</sub>
|
||||
|
||||
## Proba
|
||||
|
||||
[视频课程](https://www.bilibili.com/video/BV1D741147G5?p=9&spm_id_from=pageDriver)
|
||||
|
||||
### 1.2 随机试验
|
||||
### 1.3 样本空间
|
||||
### 1.4 随机事件
|
||||
### 1.5 事件关系和运算
|
||||
### 1.6 频率和概率
|
||||
### 1.7 古典概型
|
||||
### 1.8 超几何概型
|
||||
### 1.9 几何概型
|
||||
---
|
||||
## 1.10 条件概率
|
||||
|
||||
随机事件对应的sample space 为 S
|
||||
随机事件A 对应的样本空间是 C<sub>A</sub>
|
||||
随机事件B 对应的样本空间是 C<sub>B</sub>
|
||||
那么在已知随机事件A 已经发生的情况下,随机事件B的发生概率,记为 P(B|A)
|
||||
> $$
|
||||
P(B|A) = \frac{P(AB)}{P(A)}
|
||||
$$
|
||||
※注意、P(AB)与P(B|A)的意思是不同的,P(AB)是在样本空间S的下A和B同时发生的概率,P(B|A)是在已知A已经发生情况下的,B发生的概率,此时样本空间已经从S缩减至A。
|
||||
|
||||
### 条件概率 性质
|
||||
P(A) > 0 时,
|
||||
(1) $P(B|A) \geq{0}$
|
||||
(2) $P(S|A) = 1, P(\phi|A) = 0 $
|
||||
(3) $P(B \cup C | A) = P(B|A) + P(C|A) - P(BC|A) $
|
||||
(4) $P(B - C | A) = P(B|A) - P(BC|A) $
|
||||
(5) $P(\overline{B} | A) = 1 - P(B|A) $
|
||||
|
||||
---
|
||||
## 1.11 乘法公式
|
||||
$$
|
||||
P(B|A) = \frac{P(AB)}{P(A)}
|
||||
$$
|
||||
由条件概率公式可知
|
||||
$$
|
||||
P(AB) = P(A)P(B|A)
|
||||
$$
|
||||
$$
|
||||
P(ABC) = P(A)P(B|A)P(C|AB)
|
||||
$$
|
||||
|
||||
乘法公式 多个事件的积事件,前一个事件发生对后一个事件有影响的情况下
|
||||
将文字描述转化为 符号
|
||||
---
|
||||
## 1.12 全概率公式 与 贝叶斯公式
|
||||
|
||||
对于事件A,很复杂,无法单独求出概率,但是已知两两互不相容的事件B<sub>1</sub>,B<sub>2</sub>,B<sub>3</sub>,
|
||||
$S = B_1 + B_2 + B_3 $
|
||||
对于任意事件A,$ A\subset{S} $:
|
||||
$$
|
||||
由 P(A) = P(A)P(S) 即,P(A) = P(A)(P(B_1) + P(B_2) + P(B_3) )
|
||||
$$
|
||||
$$
|
||||
P(A) = P(A)P(B_1) + P(A)P(B_2) + P(A)P(B_3)
|
||||
$$
|
||||
$$
|
||||
P(A) = P(B_1)P(A|B_1) + P(B_2)P(A|B_2) + P(B_3)P(A|B_3)
|
||||
$$
|
||||
|
||||
> 划分 ,对于事件B1 到 Bn,两两互不相容,且合集为 S,则称 B1到Bn是样本空间的一个划分,则对于每次的随机试验,事件B1到Bn有且只有一个发生。
|
||||
样本空间的划分通常是不唯一的。
|
||||
|
||||
### 全概率公式
|
||||
$$
|
||||
P(A) = P(B_1)P(A|B_1) + P(B_2)P(A|B_2) + ... + P(B_n)P(A|B_n)
|
||||
$$
|
||||
$$
|
||||
即,P(A) = \sum_{i=1}^{n} P(B_i)P(A|B_i)
|
||||
$$
|
||||
|
||||
### 贝叶斯公式
|
||||
已知A已经发生,求B<sub>i</sub>发生的概率
|
||||
$$
|
||||
即,P(B_i) = P(B_i|A) = \frac{P(AB_i)}{P(A)} = \frac{P(B_i)P(A|B_i)}{\sum_{i=1}^{n} P(B_i)P(A|B_i)}
|
||||
$$
|
||||
|
||||
可以看出,贝叶斯 是由结果推出原因的公式
|
||||
|
||||
### 先验概率与后验概率
|
||||
|
||||
单纯的概率$P(B_i)$我们叫做**先验概率**,指的是在没有别的前提信息情况下的概率值,这个值一般需要借助我们的经验估计得到。
|
||||
而条件概率$P(B_i|A)$,我们把他叫做是**后验概率**,他代表了在获得了信息 之后出现的概率,可以说后验概率是先验概率在获取了新信息之后的一种修正。
|
||||
|
||||
---
|
||||
## 1.12 独立性
|
||||
|
||||
设 事件A 和事件B ,若满足 P(AB) = P(A)P(B)
|
||||
我们则称这两个事件A和B是相互独立的。
|
||||
互不相容 和 独立性是 不能同时存在的
|
||||
|
||||
两个事件独立则有$ P(AB) = P(A)P(B) > 0 $
|
||||
两个事件互不相容则有$ P(AB) = P(A)P(B) = \phi $
|
||||
不可能事件 和 任一事件 相互独立
|
||||
必然事件 和 任意事件 也 相互独立
|
||||
|
||||
---
|
||||
|
||||
## 2. 3. 随机变量的重要数字特征
|
||||
|
||||
<sub>bid: `2022102117153700000000000007`</sub>
|
||||
|
||||
## 1.1 样本均值
|
||||
>设 $X_1,X_2,\cdots,X_n$ 为总体 $X$ 的样本,样本容量为 $n$,则样本均值为
|
||||
$$
|
||||
\bar{X}=\frac{1}{n}\sum_{i=1}^{n}X_i
|
||||
$$
|
||||
|
||||
用样本均值来估计总体的期望$\mu$,$\bar{X}$是围绕$\mu$左右波动的,即多次采样计算出来的统计量 $\bar{X}$ 有的落在 $\mu$ 左边,有的落在 $\mu$ 右边,
|
||||
由于 $\bar{X}$ 落在 $\mu$ 左右两侧的情况是均匀的,即 $E(\bar{X})=\mu$,所以 $\bar{X}$ 就是 $\mu$ 的无偏估计。
|
||||
样本均值能够保持比较好的无偏性是因为它的计算过程本质还是一个线性过程,这个就是无偏。
|
||||
|
||||
## 1.2 加权平均
|
||||
## 1.3 数学期望
|
||||
|
||||
>离散型随机变量X的分布率
|
||||
$$
|
||||
P\{X=x_k\}=p_k, \quad k=1,2,3...
|
||||
$$
|
||||
级数
|
||||
$$
|
||||
\sum_{k=1}^{\infty}x_kp_k
|
||||
$$
|
||||
绝对收敛,则称级数为随机变量X的数学期望,记为$E(X)$,即
|
||||
$$
|
||||
E(x) = \sum_{k=1}^{\infty}x_kp_k
|
||||
$$
|
||||
注意* 数学期望可能不存在。
|
||||
**计算** 核心是确定分布率,数学期望,反映了随机变量X的取值的平均水平
|
||||
|
||||
|
||||
>连续性随机变量X的分布率
|
||||
概率密度函数$f(x)$
|
||||
若积分
|
||||
$$
|
||||
\int_{-\infty}^{+\infty} x \cdot p(x)dx
|
||||
$$
|
||||
绝对收敛,则称积分值$\int_{-\infty}^{+\infty} x \cdot p(x)dx$为随机变量X的数学期望,记为$E(X)$
|
||||
即
|
||||
$$
|
||||
E(x)=\int_{-\infty}^{+\infty} x \cdot p(x)dx
|
||||
$$
|
||||
注意绝对收敛,是取|x|
|
||||
|
||||
> 数学期望的性质
|
||||
(1) 设C为常数,则$E(C)=C$
|
||||
(2) 设$X,Y$是相互独立的随机变量,则$E(XY)=E(X) \cdot E(Y)$
|
||||
|
||||
## 1.4 总体方差(variance)
|
||||
>设$X$是随机变量,$E\{[X-E(X)]^2 \}$存在,则称$E\{[X-E(X)]^2 \}$为随机变量X的方差,记为$D(X)$或$Var(X)$即
|
||||
$$
|
||||
D(X)=Var(X)=E\{[X-E(X)]^2 \}
|
||||
$$
|
||||
|
||||
引入
|
||||
$$
|
||||
\sigma(X)=\sqrt{D(X)}
|
||||
$$
|
||||
为均方差,或者标准差。
|
||||
注意:
|
||||
$D(X)$表示随机变量的取值和他的数学期望的偏离程度。
|
||||
$D(X)$较小,则随机变量X大多分布在数学期望附近。
|
||||
$D(X)$较大,则随机变量X取值分散。
|
||||
$D(X)$刻画了随机变量X的分散程度的量度。
|
||||
|
||||
> 离散型随机变量的方差
|
||||
$$
|
||||
E\{[X-E(X)]^2 \}=D(X)=Var(X)=\sigma^{2}=\sum_{k=1}^{\infty}[x_k -\mu]^{2} \cdot P_k
|
||||
$$
|
||||
|
||||
> 连续型随机变量的方差
|
||||
$$
|
||||
E\{[X-E(X)]^2 \}=D(X)=Var(X)=\sigma^{2}=\int_{-\infty}^{+\infty} [x -\mu]^{2} \cdot f(x)dx
|
||||
$$
|
||||
|
||||
> 性质
|
||||
由
|
||||
$$
|
||||
E\{[x-E(X)]^2 \} = \int_{-\infty}^{+\infty}[x-E(X)]^2 \cdot f(x)dx
|
||||
$$
|
||||
$$
|
||||
= \int_{-\infty}^{+\infty}x^2 \cdot f(x)dx -2xE(x)\int_{-\infty}^{+\infty}f(x)dx + E^{2}(X)\int_{-\infty}^{+\infty}f(x)dx
|
||||
$$
|
||||
$$
|
||||
=E(x^2)-2E^{2}(x) + E^{2}(x) = E(x^2)-E^{2}(x)
|
||||
$$
|
||||
$$
|
||||
\sigma^{2}=E(x^2)-\mu^{2}
|
||||
$$
|
||||
## 1.5 样本方差
|
||||
> 样本方差和总体方差是不一样的,样本方差如下:
|
||||
$$
|
||||
S^{2}=\frac{1}{n-1} \sum_{i=1}^{n}(X_i - \bar{X})^{2}
|
||||
$$
|
||||
|
||||
下面我们从推导一下,样本方差为什么是$\frac{1}{n-1}$
|
||||
由方差的基本定义可知道,(样本值 - 均值) 的 平方后的 均值可知,暂时认为
|
||||
$$
|
||||
S^2 = \frac{1}{n}\sum_{k=1}^{n}[X_i - \bar{X}]^2
|
||||
$$
|
||||
那么该方差的数学期望为
|
||||
$$
|
||||
E(S^2) = E[\frac{1}{n}\sum_{k=1}^{n}[X_i - \bar{X}]^2]
|
||||
$$
|
||||
$$
|
||||
E(S^2) = E[\frac{1}{n}\sum_{k=1}^{n}[(X_i - \mu) - (\bar{X} - \mu)]^2 ]
|
||||
$$
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}\sum_{k=1}^{n}[(X_i - \mu)^2 - (X_i - \mu)(\bar{X} - \mu) + (\bar{X} - \mu)^2] ]
|
||||
$$
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}\sum_{k=1}^{n}(X_i - \mu)^2 - \frac{2}{n}\sum_{k=1}^{n}(X_i - \mu)(\bar{X} - \mu) + \frac{1}{n}\sum_{k=1}^{n}(\bar{X} - \mu)^2 ]
|
||||
$$
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}\sum_{k=1}^{n}(X_i - \mu)^2 - \frac{2}{n}(\bar{X} - \mu)\sum_{k=1}^{n}(X_i - \mu) + \frac{1}{n}\sum_{k=1}^{n}(\bar{X} - \mu)^2 ]
|
||||
$$
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}\sum_{k=1}^{n}(X_i - \mu)^2 - \frac{2}{n}(\bar{X} - \mu)n(\bar{X} - \mu) + \frac{1}{n}(\bar{X} - \mu)^2 ]
|
||||
$$
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}\sum_{k=1}^{n}(X_i - \mu)^2 - \frac{1}{n}(\bar{X} - \mu)^2 ]
|
||||
$$
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}(\sum_{k=1}^{n}(X_i - \mu)^2 - (\bar{X} - \mu)^2) ]
|
||||
$$
|
||||
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}\sum_{k=1}^{n}((X_i - \mu)^2 - (\bar{X} - \mu)^2) ]
|
||||
$$
|
||||
|
||||
$$
|
||||
E(S^2) = E [\frac{1}{n}\sum_{k=1}^{n}(X_i - \mu)^2] - \frac{1}{n}E[(\bar{X} - \mu)^2 ]
|
||||
$$
|
||||
|
||||
$$
|
||||
E(S^2) = \sigma^2 - \frac{1}{n}E[(\bar{X}^{2} -2\bar{X}\mu + \mu^2) ]
|
||||
$$
|
||||
|
||||
$$
|
||||
E(S^2) = \sigma^2 - \frac{1}{n}(E(\bar{X}^{2}) -2\mu E(\bar{X}) + E(\mu^2))
|
||||
$$
|
||||
|
||||
$$
|
||||
E(S^2) = \sigma^2 - \frac{1}{n}(E(\bar{X}^{2}) - E(\mu^2))
|
||||
$$
|
||||
|
||||
$$
|
||||
E(S^2) = \sigma^2 - \frac{1}{n}\sigma^2 = \frac{n-1}{n}\sigma^2 \neq \sigma^2
|
||||
$$
|
||||
我们看出,$E(S^2)$和总体方差是不相等的,即是有偏向的,为了修正这个问题,
|
||||
我们需要重新估计得到
|
||||
$$
|
||||
S^2 = \frac{1}{n-1}\sum_{k=1}^{n}[X_i - \bar{X}]^2
|
||||
$$
|
||||
|
||||
## 1.6 均方误差(mean-square error, MSE)
|
||||
均方误差是 反映估计量与被估计量之间差异程度的一种度量。
|
||||
>一般地,在样本量一定时,评价一个点估计的好坏标准使用的指标 是点估计与参数真值 的距离的函数,最常用的函数是距离的平方.
|
||||
由于估计量 具有随机性,可以对该函数求期望,这就是下式给出的均方误差:
|
||||
$$
|
||||
E(X_i) = \frac{1}{n} \sum_{i=1}^{n} (f(x_i) -y_i)^2
|
||||
$$其中 $f(x_i)$ 为预测值,$y_i$为真值。
|
||||
|
||||
## 1.6 相关系数
|
||||
## 1.7 矩阵
|
||||
|
||||
## 7.2 矩
|
||||
|
||||
**矩**
|
||||
|
||||
1. $k$阶矩($k$阶原点矩)
|
||||
|
||||
设$X$是随机变量,若
|
||||
$$
|
||||
E(X^k), \quad k=1,2,3...
|
||||
$$
|
||||
存在,称它为$X$的$k$阶**原点矩**,简称$k$阶矩。
|
||||
|
||||
注意:k=1,是1阶矩,$E(X)$,1阶矩是数学期望
|
||||
k=2,是2阶矩,$E(x^2)$的数学期望。
|
||||
|
||||
$$
|
||||
E(X^k)=\int_{-\infty}^{+\infty}x^{k}f(x)dx, \quad k=1,2,3...
|
||||
$$
|
||||
|
||||
2. $k$阶中心矩
|
||||
|
||||
设$X$是随机变量,若
|
||||
$$
|
||||
E\{[X-E(X)]^k\}, \quad k=2,3...
|
||||
$$
|
||||
存在,称它为$X$的$k$阶**中心矩**。
|
||||
注意:k=2的时候,2阶中心距就是方差。
|
||||
|
||||
$$
|
||||
E\{[X-E(X)]^k\}=\int_{-\infty}^{+\infty}[X-E(X)]^kf(x)dx, \quad k=2,3...
|
||||
$$
|
||||
|
||||
3. $k+l$阶混合矩
|
||||
|
||||
设$(X+Y)$是随机变量,若
|
||||
$$
|
||||
E(X^{k}Y^{l}), \quad k,l=2,3...
|
||||
$$
|
||||
存在,称它为$X,Y$的$k+l$阶**混合矩**。
|
||||
|
||||
注意:k=l=1的时候,E(XY)的数学期望。
|
||||
|
||||
4. $k+l$阶混合中心矩
|
||||
|
||||
设$(X+Y)$是随机变量,若
|
||||
$$
|
||||
E([X-E(X)]^{k}[Y-E(Y)]^{l}), \quad k,l=1,2,3...
|
||||
$$
|
||||
存在,称它为$X,Y$的$k+l$阶**混合中心矩**。
|
||||
|
||||
注意:当$k=l=1$的时候,$k+l=2$,即2阶混合中心距,协方差$Cov(X,Y)$是$X$和$Y$的2阶混合中心距。
|
||||
|
||||
**协方差矩阵**
|
||||
|
||||
对n维随机变量使用协方差矩阵研究。
|
||||
|
||||
1. 2维随机变量的协方差矩阵
|
||||
设2维随机变量(X,Y)有四个2阶中心距,分别为
|
||||
$c_{11}=E\{[X-E(X)]^{2}\}$
|
||||
$c_{12}=E\{[X-E(X)][Y-E(Y)]\}$
|
||||
$c_{21}=E\{[Y-E(Y)][X-E(X)]\}$
|
||||
$c_{22}=E\{[Y-E(Y)]^{2}\}$
|
||||
将他们排成矩阵的形式
|
||||
$$
|
||||
\begin{pmatrix}
|
||||
c_{11} & c_{12} \\
|
||||
c_{21} & c_{22} \\
|
||||
\end{pmatrix} \tag{1}
|
||||
$$
|
||||
这个矩阵就成为随机变量(X,Y)的协方差矩阵。是一个对称矩阵
|
||||
|
||||
2. n维随机变量$(X_1,X2,...X_n)$的协方差矩阵
|
||||
$c_{ij}=E[X_i-E[X_i]]E[X_j-E(X_j)]$的协方差都存在。
|
||||
则称矩阵
|
||||
$$
|
||||
\begin{pmatrix}
|
||||
c_{11} & c_{12} & ... & c_{1n}\\
|
||||
c_{21} & c_{22} & ... & c_{2n}\\
|
||||
\vdots & \vdots & \ & \vdots\\
|
||||
c_{n1} & c_{n2} & ... & c_{nn}\\
|
||||
\end{pmatrix} \tag{1}
|
||||
$$
|
||||
称为n维随机变量$(X_1,X2,...X_n)$的协方差矩阵
|
||||
|
||||
在数理统计中,往往并不知道n维随机变量的概率分布,或者太复杂,以至于无法处理,因此在实际应用中协方差矩阵就很重要了。
|
||||
|
||||
---
|
||||
|
||||
## 3. 2. 随机变量以及其分布率
|
||||
|
||||
<sub>bid: `2022102117154100000000000006`</sub>
|
||||
|
||||
## 第二部分 随机变量
|
||||
---
|
||||
|
||||
用随机变量 来表示 随机事件 是 probability 中最要用的应用。
|
||||
随机变量定义:
|
||||
设随机实验的样本空间
|
||||
$ S = \{e \},$ $X = X(e) $是定义在样本空间S上的单值函数,称$ X = X(e)$为随机变量。
|
||||
约定,用 X,Y,Z, W 来表示随机变量,用小写的x,y,z,w 实数
|
||||
X是指随机事件的描述。
|
||||
|
||||
离散型数学变量,我们用分布律来描述。
|
||||
分布律:
|
||||
设 离散型随机变量X的所有可能取值为$ x_k(k=1,2,3...) $
|
||||
事件{$X=x_k$}的概率P{$X=x_k$} = $p_k$,为离散型随机变量的分布率。
|
||||
|
||||
## 随机变量的分布函数
|
||||
---
|
||||
适合离散型和非离散型的各种应用
|
||||
**定义**
|
||||
设$X$是一个随机变量,$x$是任意实数,函数$f(x)=P{X≦x}, -\infty≦x≦+\infty$
|
||||
称为X的分布函数
|
||||
定义域: $-\infty<sub>≦</sub>x≦+\infty$
|
||||
值域 :$0≦F(x)≦1$
|
||||
性质:
|
||||
1,单调不减
|
||||
2,有界性
|
||||
3,右连续的
|
||||
离散型的概率分布都是左闭右开的。
|
||||
|
||||
## 离散型随机变量的分布率
|
||||
---
|
||||
### 2.1 0-1分布
|
||||
### 2.2 二项分布
|
||||
特性:重复,独立
|
||||
以X表示在n重伯努利实验中事件A发生的次数$P(A) = p, 0< p < 1$
|
||||
定义:若X 的分布律为
|
||||
$ P\{X=k\} = C_n^kP^k(1-P)^{n-k}$
|
||||
则称随机变量X服从参数为n,P的二项分布,记为$ X ~ b(n,P)$
|
||||
n发生次数,P为每次发生的规律。
|
||||
### 2.3 泊松分布
|
||||
大量次数,每次发生的概率很小的情况下,可以用泊松分布计算,
|
||||
此时λ = np
|
||||
$$
|
||||
P\{X=k\} =\frac{λ^k-e^{-λ}}{k!}
|
||||
$$
|
||||
### 2.4 几何分布
|
||||
重复独立的随机试验中,试验次数事先无法确定,每一次成功的概率为p,将实验进行至成功为止,以X表示实验进行的次数,则X的分布律为
|
||||
$$
|
||||
P\{X=k\} = (1-p)^{k-1}p
|
||||
$$
|
||||
像这样的随机分布为几何分布
|
||||
### 2.5 超几何分布
|
||||
从大N件产品中(包含M件次品)取出n件产品,以X表示取到的次品数,则X的分布律为
|
||||
$$
|
||||
P\{X=k\} = \frac{C_M^k C_{N-M}^{n-k}}{C_N^n}
|
||||
$$
|
||||
则称随机变量X服从参数为(N,M,n)的超几何分布。
|
||||
|
||||
## 连续性随机变量以及其概率密度
|
||||
---
|
||||
> 连续性随机变量 定义
|
||||
若对于随机变量$X$的分布函数$F(X)$,存在非负可积函数$f(x)$,使对于任意实数$x$有
|
||||
$$
|
||||
F(x)=\int_{-\infty}^{x}f(x)dx
|
||||
$$
|
||||
则称$X$为连续性随机变量,$f(x)$为$X$概率密度函数,简称概率密度。
|
||||
|
||||
### 2.6 均匀分布(uniform distribution)
|
||||
> 定义
|
||||
若随机变量的X的概率密度为
|
||||
$$
|
||||
f(x)= \begin{cases}
|
||||
\frac{1}{b-a}x, \quad a<x<b \\
|
||||
0 \quad, \text{others}\\
|
||||
\end{cases} \tag{1}
|
||||
$$
|
||||
则称$X$在区间$[a,b]$上服从均匀分布,记为$X \sim U(a,b)$,其概率分布函数为
|
||||
$$
|
||||
F(x)=\begin{cases}
|
||||
0, x <a \\
|
||||
\frac{x-a}{b-a}, \quad a \leq x<b \\
|
||||
1 \quad, x \leq b\\
|
||||
\end{cases} \tag{2}
|
||||
$$
|
||||
|
||||
### 2.7 正态分布(normal distribution)
|
||||
> 定义
|
||||
若随机变量的X的概率密度为
|
||||
$$
|
||||
f(x)=\frac{1}{\sqrt{2 \pi} \sigma} \cdot e^{- \frac{(x-\mu)^2}{2 \sigma^2}}
|
||||
$$
|
||||
其中$\mu, \sigma$为常数,且 $\sigma > 0$,则称$X$服从参数$\mu, \sigma$的正态分布,记为 $X \sim N(\mu,\sigma)$,其分布函数为
|
||||
$$
|
||||
F(x)=\int_{-\infty}^{x} \frac{1}{\sqrt{2 \pi} \sigma} \cdot e^{- \frac{(x-\mu)^2}{2 \sigma^2}} dx
|
||||
$$
|
||||
|
||||
|
||||
> 已知概率积分(Gaussian integral)或者 高斯积分
|
||||
$$
|
||||
\int_{-\infty}^{+\infty} e^{-x^2}dx = \sqrt{\pi}
|
||||
$$
|
||||
则有
|
||||
$$
|
||||
F(x)=\int_{-\infty}^{x} \frac{1}{\sqrt{2 \pi} \sigma} \cdot e^{- \frac{(x-\mu)^2}{2 \sigma^2}} dx
|
||||
$$
|
||||
设
|
||||
$$
|
||||
t = \frac{(x-\mu)}{\sqrt{2}\sigma} => dx = \sqrt{2}\sigma dt
|
||||
$$
|
||||
则
|
||||
$$
|
||||
F(x)=\int_{-\infty}^{x} \frac{1}{\sqrt{2 \pi} \sigma} \cdot e^{-t^2} \cdot \sqrt{2}\sigma dt
|
||||
$$
|
||||
$$
|
||||
F(x)=\frac{1}{\sqrt{\pi}}\int_{-\infty}^{x} e^{-t^2} dt = 1
|
||||
$$
|
||||
|
||||
### 概率密度函数的图形
|
||||
|
||||
- 对称性
|
||||
$f(x)$关于$x=\mu$对称
|
||||
$P\{ \mu-h<X <\mu \} = P\{ \mu<X <\mu + h\}$
|
||||
|
||||
- 最大值
|
||||
当$x=\mu$时,$f(x)$取最大值。
|
||||
$$
|
||||
f_{max}(x)=\frac{1}{\sqrt{2\pi}\sigma}
|
||||
$$
|
||||
- 凹凸性
|
||||
由高等数学可知,凹凸性是二阶导数等于0时存在凹凸拐点。
|
||||
$$
|
||||
f^{''}(x)=\frac{(x-\mu)^2-\sigma^2}{\sqrt{2 \pi} \sigma^5} \cdot e^{- \frac{(x-\mu)^2}{2 \sigma^2}} = 0
|
||||
$$
|
||||
可知
|
||||
$$
|
||||
(x-\mu)^2-\sigma^2 = 0
|
||||
$$
|
||||
在$x=\mu \underline{+} \sigma$ 处是 概率密度函数的凹凸拐点,其中$\mu$为数学期望,$\sigma$为总体样本的标准差。
|
||||
|
||||
- 渐进性
|
||||
$$
|
||||
\lim_{x \to \infty} \frac{1}{\sqrt{2 \pi} \sigma} \cdot e^{- \frac{(x-\mu)^2}{2 \sigma^2}} = 0
|
||||
$$
|
||||
|
||||
- $\mu,\sigma$变化时
|
||||
|
||||
$\mu$决定了概率密度曲线的未知
|
||||
$\sigma$决定了最大值,标准差越小,在$\mu$一定的情况下,说明X在$\mu$附近的概率越大。
|
||||
|
||||
### 标准正态分布函数
|
||||
$X \sim N(0,1)$时的正态分布就是标准正态分布。
|
||||
|
||||
### 正态分布的概率计算
|
||||
|
||||
$X \sim N(\mu,\sigma)$
|
||||
|
||||
由
|
||||
$$
|
||||
t= \frac{x-\mu}{\sigma}
|
||||
$$
|
||||
来代替$x$可知
|
||||
$$
|
||||
F(t)=\int_{-\infty}^{t} \frac{1}{\sqrt{2\pi}}e^{-t^2} dt = 1
|
||||
$$
|
||||
可知$t= \frac{x-\mu}{\sigma}$服从$N(0,1)$的正态分布。
|
||||
|
||||
### 2.8 指数分布(Exponential distribution)
|
||||
> 定义
|
||||
若随机变量的X的概率密度为
|
||||
$$
|
||||
f(x)= \begin{cases}
|
||||
\frac{1}{\theta}e^{x/\theta}, \quad x>0 \\
|
||||
0 \quad, \text{others}\\
|
||||
\end{cases} \tag{3}
|
||||
$$
|
||||
其中$\theta >0 $为常数,记为$X \sim exp(\theta)$则称$X$服从参数为$\theta$的指数分布。
|
||||
其概率分布为
|
||||
$$
|
||||
F(x)=\begin{cases}
|
||||
1 - e^{x/\theta}, \quad x>0 \\
|
||||
0 \quad, \text{others}\\
|
||||
\end{cases} \tag{4}
|
||||
$$
|
||||
|
||||
|
||||
### 2.9 边缘分布
|
||||
|
||||
### 2.10 条件分布
|
||||
|
||||
## 二维随机变量
|
||||
---
|
||||
### 3.1 随机变量的相互独立性
|
||||
已知
|
||||
$X,Y$的联合分布函数$F(x,y)$,边缘分布函数$F_X(x),F_Y(y)$
|
||||
$F(X,Y)=P\{X\leq x,Y \leq y \} =P\{ X \leq x \} \cdot P\{ Y \leq y \}$
|
||||
$= F_X(x) \cdot F_Y(y)$
|
||||
|
||||
---
|
||||
|
||||
## 4. 4. 参数估计
|
||||
|
||||
<sub>bid: `2022102117160500000000000008`</sub>
|
||||
|
||||
## 第七章 参数估计
|
||||
---
|
||||
|
||||
- 在进入数理统计学习之前,我们明确以下概念问题,有助于我们学习这些知识到底来干什么。
|
||||
|
||||
- probability and statistics are two faces of a coin。
|
||||
- from 【All of Statistics】 book
|
||||
|
||||
>The basic problem that we study in probability is:
|
||||
Given a data generating process, what are the properities of the outcomes?
|
||||
|
||||
>The basic problem of statistical inference is the inverse of probability:
|
||||
Given the outcomes, what can we say about the process that generated the data?
|
||||
|
||||
- 概率论,给出概率分布,算出概率,即知总体,估算样本
|
||||
- 数理统计,给出样本数据,推算出概率分布(参数),即知道样本估算总体。
|
||||
|
||||
about statistics, we will learn estimation。
|
||||
点估计,区间估计,最大似然估计(maximum likelihood estimation)
|
||||
|
||||
## 7.1 点估计
|
||||
点估计问题
|
||||
|
||||
> 设总体$X$的分布函数(概率密度,分布率)的形式已知,但他的一个或者多个参数未知,借助于总体$X$的一个样本来估计总体未知参数的值的问题,称为参数的点估计问题
|
||||
|
||||
点估计问题的提法
|
||||
|
||||
已知:总体$X$的分布函数的$F(x;\theta)$的形式
|
||||
|
||||
未知:$\theta$待估参数,此处的$\theta$可以理解为向量,$\theta=(\theta_1,\theta_2,\theta_3)$
|
||||
|
||||
利用:$X_1,X_2,...,X_n$是$X$的一个样本,$x_1,x_2,...,x_n$是样本值
|
||||
|
||||
点估计问题:
|
||||
|
||||
构造一个适当的统计量$\hat{\theta}(X_1,X_2,...,X_n)$
|
||||
|
||||
用它的观察值$\hat{\theta}(x_1,x_2,...,x_n)$
|
||||
作为位置$\theta$的近似值。
|
||||
|
||||
### 7.1.1 矩估计
|
||||
|
||||
### 知识点
|
||||
总体$X$
|
||||
- X的k阶原点矩 $E(X^k) \quad k=1,2,3..,n$
|
||||
总体1阶矩,$E(X)$
|
||||
总体2阶矩,$E(X^{2})$
|
||||
|
||||
样本$X_1,X_2,..,X_n$
|
||||
- 样本的k阶原点矩 $A_{k}=\frac{1}{n} \sum_{i=1}^{n}X_{i}^{k} \quad k=1,2,3..,n$
|
||||
样本1阶矩,$\bar{X}$
|
||||
样本2阶矩,$A_{2}=\frac{1}{n} \sum_{i=1}^{n}X_{i}^{2} $
|
||||
|
||||
### 理论基础
|
||||
样本的k阶矩是依概率而收敛于总体的k阶矩的。
|
||||
当样本足够大的时候,即n取无穷的时候$A_k$就近似于$E(X^{k})$
|
||||
|
||||
### 矩估计的求解步骤
|
||||
设总体X的分布中有m个未知参数$\theta_{1},\theta_{2},\theta_{3},...,\theta_{m}$
|
||||
1. 求总体的各阶矩
|
||||
2. 令样本的各阶矩等于总体的各阶矩,得到m个参数的方程,然后求解方程式
|
||||
|
||||
### 7.1.2 最大似然估计法
|
||||
最大似然估计(maximum likelihood estimation, MLE)一种重要而普遍的求估计量的方法。
|
||||
|
||||
一,离散型
|
||||
>设总体X为离散型,分布率已知,但是分布中有m个位置参数$\theta_{1},\theta_{2},...,\theta_{m}$,$X_{1},X_{2},...,X_{n}$是总体X的一个样本,$x_{1},x_{2},...,x_{n}$是对应的样本值。
|
||||
已知$X_{1},X_{2},...,X_{n}$取到观察值$x_{1},x_{2},...,x_{n}$的概率,
|
||||
即事件$P\{ X_{1}=x_{1},X_{2}=x_{2},...,X_{n}=x_{n} \}$发生的概率为
|
||||
$$
|
||||
L(x_1,x_2,...,x_n;\theta_{1},\theta_{2},...,\theta_{m})=\prod_{i=1}^{n}P\{ X=x_1 \} \quad (7.3)
|
||||
$$
|
||||
这一概率随$\theta_{1},\theta_{2},...,\theta_{m}$的取值而变化,他是m个未知参数$\theta_{1},\theta_{2},...,\theta_{m}$的函数,称为样本的似然函数,需要注意的是$x_{1},x_{2},...,x_{n}$是已知的样本值。
|
||||
|
||||
最大似然估计的思想是:
|
||||
已经取到样本值$x_{1},x_{2},...,x_{n}$,这就说明,这一样本值发生的概率$L(x_1,x_2,...,x_n;\theta_{1},\theta_{2},...,\theta_{m})$比较大。
|
||||
因此,可以固定样本观察值$x_{1},x_{2},...,x_{n}$,挑选使似然函数$L(x_1,x_2,...,x_n;\theta_{1},\theta_{2},...,\theta_{m})$达到最大值的
|
||||
$$
|
||||
\hat{\theta}_{i}(x_1,x_2,...,x_n) \quad i=1,2,...,m
|
||||
$$
|
||||
用这种思想求出的参数值
|
||||
|
||||
二,连续型
|
||||
|
||||
>设总体X为连续型,$X_{1},X_{2},...,X_{n}$是总体X的一个样本,$x_{1},x_{2},...,x_{n}$是对应的样本值,则$X_{1},X_{2},...,X_{n}$的联合概率密度$(X_{1},X_{2},...,X_{n})$的$f(x_{1},x_{2},...,x_{n})=f_{X_1}(x_1) \cdot f_{X_2}(x_2) \cdots f_{X_n}(x_n)$
|
||||
$$
|
||||
L(x_1,x_2,...,x_n;\theta_{1},\theta_{2},...,\theta_{m})=\prod_{i=1}^{n}f(x_i;\theta_{1},\theta_{2},...,\theta_{m}) \quad (7.4)
|
||||
$$
|
||||
|
||||
随机点$X_{1},X_{2},...,X_{n}$落在点$(x_{1},x_{2},...,x_{n})$的邻域(边长分别为$dx_1,dx_2,...,dx_n, $的n维立方体)内近似概率为
|
||||
$$
|
||||
\prod_{i=1}^{n}f(x_i;\theta_{1},\theta_{2},...,\theta_{m})dx_i \quad (7.5)
|
||||
$$
|
||||
$$
|
||||
\prod_{i=1}^{n}f(x_i;\theta_{1},\theta_{2},...,\theta_{m}) \cdot \prod_{i=1}^{n}dx_i \quad (7.6)
|
||||
$$
|
||||
这一概率随$\theta_{1},\theta_{2},...,\theta_{m}$的取值而变化,最大似然估计的思想是取$\theta_{1},\theta_{2},...,\theta_{m}$的估计值,使上述概率取得最大值,注意
|
||||
$$
|
||||
\prod_{i=1}^{n}dx_i \quad (7.7)
|
||||
$$
|
||||
不随$\theta_{1},\theta_{2},...,\theta_{m}$的改变而改变,故而只需考虑函数
|
||||
$$
|
||||
\prod_{i=1}^{n}f(x_i;\theta_{1},\theta_{2},...,\theta_{m})
|
||||
$$
|
||||
的最大值即可,我们称n维随机变量的联合概率密度函数(7.4)为样本的似然函数。
|
||||
|
||||
解题步骤
|
||||
(1)写出 似然函数
|
||||
(2)对似然函数左右两边取对数,由乘积变成对数和。
|
||||
(3)对各个参数求偏导数,形成方程组。
|
||||
(4)求解方程组,求出参数。
|
||||
|
||||
## 7.2 估计量评价标准
|
||||
|
||||
通过点估计,矩估计和最大似然估计求出的估计量是各不相同的,如何评价估计量的好坏就是估计量的评价标准。
|
||||
|
||||
- 无偏性
|
||||
> 定义
|
||||
设总体 $\xi$ 的概率分布函数为 $F(x; \theta)$,其中 $x$ 为变元,$ \theta∈ \Theta$为未知参数,$\Theta$称为参数空间。
|
||||
$(\xi_1,\xi_2, \cdots ,\xi_{n})$为取自总体$\xi$的随机样本,若$(\xi_1,\xi_2, \cdots ,\xi_{n})$是参数$\theta$的一个估计量,且对一切 $ \theta∈ \Theta$,关系式 $E_{\theta}=E[(\xi_1,\xi_2, \cdots ,\xi_{n})]$,其中$E_{\theta}=E[(\xi_1,\xi_2, \cdots ,\xi_{n})]$表示数学期望,则称$(\xi_1,\xi_2, \cdots ,\xi_{n})$为参数$\theta$的无偏估计,具有无偏性。
|
||||
|
||||
- 有效性
|
||||
- 相合性
|
||||
-
|
||||
|
||||
---
|
||||
|
||||
## 5. 5. 置信区间
|
||||
|
||||
<sub>bid: `2022102117166600000000000009`</sub>
|
||||
|
||||
## 5.1 置信区间
|
||||
---
|
||||
> 定义 设总体$X$的分布函数$F(x;\theta)$,含有一个位置参数$\theta, \theta \in \Theta, \Theta$是 $\theta$的可能的取值范围。
|
||||
对于给定值 $ 0<\alpha < 1$,来自X的一个样本$(X_1,X_2,\cdots, X_n)$确定的两个统计量,$\theta=\theta(X_1,X_2,\cdots, X_n)$和$\bar{\theta}=\theta(X_1,X_2,\cdots, X_n) \quad (\theta < \bar{\theta})$
|
||||
对于任意的$\theta \in \Theta$满足,
|
||||
$$
|
||||
P\{\underline{\theta}(X_1,X_2,\cdots, X_n) < \theta < \bar{\theta}(X_1,X_2,\cdots, X_n) \} \ge
|
||||
$$
|
||||
则称随机区间$(\underline{\theta}, \bar{\theta})$是 置信水平为 $1- \alpha$ 的置信区间。
|
||||
$\underline{\theta}$为置信下限,$\bar{\theta}$为置信上限,$1- \alpha$为置信水平。
|
||||
|
||||
## 5.1 置信区间
|
||||
|
||||
---
|
||||
|
||||
## 6. 10. 线性回归分析和方差分析
|
||||
|
||||
<sub>bid: `2022102509540400000000000001`</sub>
|
||||
|
||||
## 10.1 线性回归分析
|
||||
---
|
||||
线性回归分析中,通常要求$x$为普通变量,是可控制的变量,Y是随机变量,是可以观察但不可控制的变量。如$x$是施肥量,Y是产量。
|
||||
|
||||
### 10.1.1 线性回归模型
|
||||
>   设$x$是普通变量,Y是随机变量,且
|
||||
$$
|
||||
Y = \alpha + \beta x + \varepsilon, \quad \varepsilon \sim N(0,\sigma^2)
|
||||
\tag{10.1.1}
|
||||
$$
|
||||
其中,$\alpha,\beta,\sigma^2$是不依赖于 $x$ 的未知参数,称此模型为一元线性回归模型。
|
||||
  易见,此时
|
||||
$$
|
||||
Y \sim N(\alpha + \beta x,\sigma^2)
|
||||
\tag{10.1.2}
|
||||
$$
|
||||
称 $Y$ 的数学期望
|
||||
$$
|
||||
\tilde{Y} = E(Y) = \alpha + \beta x
|
||||
\tag{10.1.3}
|
||||
$$
|
||||
为 $Y$ 关于 $x$ 的线性回归函数,$\alpha,\beta$ 为回归系数,$x$ 为回归变量。
|
||||
  取得样本观测值 $(x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n)$,若能得到$\alpha,\beta$的点估计$\hat{\alpha},\hat{\beta}$,称
|
||||
$$
|
||||
\tilde{Y} = \hat{\alpha} + \hat{\beta} x
|
||||
\tag{10.1.4}
|
||||
$$
|
||||
为线性回归方程。
|
||||
|
||||
### 10.1.2 α,β 和 σ<sup>2</sup>的极大似然估计及性质
|
||||
|
||||
  取的样本观测值$(x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n)$ 后,由(10.1.2),得到似然函数
|
||||
$$
|
||||
L(\alpha,\beta,\sigma^2)= \prod_{i=1}^{n} f(x_i;\alpha,\beta,\sigma^2)
|
||||
$$
|
||||
$$
|
||||
= \prod_{i=1}^{n} \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(y_i - (\alpha + \beta x_i))^2}{2\sigma^2}}
|
||||
$$
|
||||
$$
|
||||
= \frac{1}{(\sqrt{2\pi}\sigma)^n}e^{\sum_{i=1}^{n}-\frac{(y_i - (\alpha + \beta x_i))^2}{2\sigma^2}}
|
||||
$$
|
||||
$$
|
||||
= (2\pi)^{-\frac{n}{2}}(\sigma)^{-\frac{n}{2}} e^{-\frac{1}{2\sigma^2} \sum_{i=1}^{n}[ y_i - (\alpha + \beta x_i)]^2}
|
||||
$$
|
||||
|
||||
从而有
|
||||
$$
|
||||
\ln{L(\alpha,\beta,\sigma^2)}= -\frac{n}{2}\ln(2\pi) -\frac{n}{2}\ln \sigma^2 - \frac{1}{2\sigma^2} \sum_{i=1}^{n}[ y_i - (\alpha + \beta x_i)]^2
|
||||
$$
|
||||
故而取对数方程组,对个参数取偏导
|
||||
$$
|
||||
\begin{cases}
|
||||
\frac{\large{\partial{(\ln (\alpha,\beta,\sigma^2))}}}{\large{\partial{\alpha}}} = \frac{\large{1}}{\large{\sigma^2}}\sum_{i=1}^{n}( y_i - (\alpha + \beta x_i)) = 0\\
|
||||
\frac{\large{\partial{(\ln (\alpha,\beta,\sigma^2))}}}{\large{\partial{\beta}}} = \frac{\large{1}}{\large{\sigma^2}}\sum_{i=1}^{n}x_i( y_i - (\alpha + \beta x_i)) = 0\\
|
||||
\frac{\large{\partial{(\ln (\alpha,\beta,\sigma^2))}}}{\large{\partial{\sigma^2}}} = - \frac{\large{n}}{\large{2\sigma^2}} + \frac{\large{1}}{\large{2\sigma^4}} \sum_{i=1}^{n}[ y_i - (\alpha + \beta x_i)]^2 = 0
|
||||
\end{cases}
|
||||
$$
|
||||
整理为关于 $\alpha,\beta,\sigma^2$ 的方程组。
|
||||
$$
|
||||
\begin{cases}
|
||||
n\alpha +\beta\sum_{i=1}^{n}x_i=\sum_{i=1}^{n}y_i\\
|
||||
\alpha\sum_{i=1}^{n}x_i + \beta\sum_{i=1}^{n}x_i^2 = \sum_{i=1}^{n}x_i y_i\\
|
||||
\sigma^2=\frac{1}{n}\sum_{i=1}^{n}[y_i - (\alpha + \beta x_i)]^2
|
||||
\end{cases}
|
||||
$$
|
||||
解得$\alpha,\beta,\sigma^2$的最大似然估计值为
|
||||
$$
|
||||
\begin{cases}
|
||||
\hat{\alpha} = \bar{y} - \hat{\beta}\bar{x}\\
|
||||
\hat{\beta} = \frac{s_xy}{s_xx}\\
|
||||
\hat{\sigma}^2= \frac{1}{n}\sum_{i=1}^{n}[y_i - (\hat{\alpha} + \hat{\beta} x_i)]^2
|
||||
\end{cases}
|
||||
\tag{10.1.5}
|
||||
$$
|
||||
其中
|
||||
$$
|
||||
s_{xy}=\sum_{i=1}^{n}(x_i-\bar{x})(y_i-\bar{y})=\sum_{i=1}^{n}x_iy_i -n\bar{x}\bar{y}
|
||||
\tag{10.1.6}
|
||||
$$
|
||||
$$
|
||||
s_{xx}=\sum_{i=1}^{n}(x_i-\bar{x})^2=\sum_{i=1}^{n}x_i^2 -n\bar{x}^2
|
||||
\tag{10.1.7}
|
||||
$$
|
||||
(10.1.5),(10.1.6),(10.1.7)中,观测值 $y_i$ 改为 $Y_i$ 则得到相应的最大似然估计量
|
||||
$$
|
||||
\begin{cases}
|
||||
\hat{\alpha} = \bar{Y} - \hat{\beta}\bar{x}\\
|
||||
\hat{\beta} = \frac{s_xY}{s_xx}\\
|
||||
\hat{\sigma}^2= \frac{1}{n}\sum_{i=1}^{n}[Y_i - (\hat{\alpha} + \hat{\beta} x_i)]^2
|
||||
\end{cases}
|
||||
\tag{10.1.5}
|
||||
$$
|
||||
   注意,$\alpha$ 和 $\beta$ 的最大似然估计值是似然函数中e的指数部分
|
||||
$$
|
||||
Q(\alpha,\beta)= \sum_{i=1}^{b}[y_i - (\hat{\alpha} + \hat{\beta} x_i)]^2
|
||||
$$
|
||||
达到最小的估计,所以 $\alpha$ 和 $\beta$ 的最大似然估计 $\hat{\alpha}$ 和 $\hat{\beta}$ 又叫做最小二乘估计。
|
||||
  事实上,$Q(\hat{\alpha},\hat{\beta})$ 是数据$(x_i,y_i)$对估计$\hat{y}=\hat{\alpha}+\hat{\beta}x_i$ 的变差平方和。最小二乘估计使数据点到回归线的垂直距离平方和达到最小,而且回归线是通过点 $(\bar{x},\bar{y})$.
|
||||
|
||||
## 10.2 单因素试验的方差分析
|
||||
---
|
||||
### 10.2.1单因素实验的方差分析模型
|
||||
> 若实验中,只让一个因素A变化,而让其他因素保持不变,这样的试验称为单因素试验。
|
||||
|
||||
---
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,151 @@
|
||||
[{
|
||||
"_id": {
|
||||
"$oid": "626e92e3ff47411696bdc502"
|
||||
},
|
||||
"btId": "00000000000003",
|
||||
"btName": "深入理解Java虚拟机",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 0
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "627009d357c0264f499c3112"
|
||||
},
|
||||
"btId": "00000000000002",
|
||||
"btName": "Java and Spring",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 1
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6270c35457c0264f499c3114"
|
||||
},
|
||||
"btId": "00000000000004",
|
||||
"btName": "服务器和系统",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 2
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "62711385ce1c9f5320a2d06a"
|
||||
},
|
||||
"btId": "2022050319356100000000000001",
|
||||
"btName": "Kubernetes 最佳实践",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 4
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6271e199ce1c9f5320a2d06c"
|
||||
},
|
||||
"btId": "2022050410146100000000000003",
|
||||
"btName": "计算机网路",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 7
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6273350ace1c9f5320a2d06e"
|
||||
},
|
||||
"btId": "2022050510233200000000000005",
|
||||
"btName": "AWS",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 6
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6275315fce1c9f5320a2d07f"
|
||||
},
|
||||
"btId": "2022050622313300000000000022",
|
||||
"btName": "十万个为什么",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 3
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6282353f1425aa536ca456d2"
|
||||
},
|
||||
"btId": "2022051619278900000000000002",
|
||||
"btName": "深入刨析Kubernetes",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 5
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "628ae75d1425aa536ca456da"
|
||||
},
|
||||
"btId": "2022052309468900000000000004",
|
||||
"btName": "Azure",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 8
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6282759a1425aa536ca456d4"
|
||||
},
|
||||
"btId": "2022051700024800000000000003",
|
||||
"btName": "quantitative trading",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "",
|
||||
"_class": "com.g.estate.entity.BlogType",
|
||||
"order": 9
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6352618afe546b1de2f76d41"
|
||||
},
|
||||
"btId": "2022102117088800000000000001",
|
||||
"btName": "machine learning",
|
||||
"updateTime": "",
|
||||
"_class": "cn.violin.home.book.entity.BlogType",
|
||||
"owner": "3272499474",
|
||||
"order": 10
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "635262bbfe546b1de2f76d44"
|
||||
},
|
||||
"btId": "2022102117130200000000000002",
|
||||
"btName": "probability and statistics",
|
||||
"updateTime": "",
|
||||
"_class": "cn.violin.home.book.entity.BlogType",
|
||||
"owner": "3272499474",
|
||||
"order": 11
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "63f71a39f3eea8401859f543"
|
||||
},
|
||||
"btId": "2023022315480800000000000001",
|
||||
"btName": "Golang",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "2023-02-23 15:48:16",
|
||||
"order": 12,
|
||||
"_class": "cn.violin.wiki.entity.BlogType"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6432acd0da833126fae88eae"
|
||||
},
|
||||
"btId": "20230409",
|
||||
"btName": "常用 Command",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "2023-04-09 20:17:25",
|
||||
"order": 13,
|
||||
"_class": "cn.violin.wiki.entity.BlogType"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6732018fd2715f2cf34fa09e"
|
||||
},
|
||||
"btId": "2024111121076600000000000003",
|
||||
"btName": "violin-home",
|
||||
"owner": "3272499474",
|
||||
"updateTime": "2024-11-11 21:07:39",
|
||||
"order": 14,
|
||||
"_class": "cn.violin.wiki.entity.BlogType"
|
||||
}]
|
||||
@@ -0,0 +1,125 @@
|
||||
# violin-home
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2024111121076600000000000003` · 排序:14 · 文章数:3
|
||||
|
||||
## 目录
|
||||
|
||||
1. [腾讯云证书从申请到发布](#腾讯云证书从申请到发布)
|
||||
2. [腾讯云账号](#腾讯云账号)
|
||||
3. [gogs ci/cd](#gogs-cicd)
|
||||
|
||||
---
|
||||
|
||||
## 1. 腾讯云证书从申请到发布
|
||||
|
||||
<sub>bid: `2024111121075900000000000042`</sub>
|
||||
|
||||
### 申请
|
||||
略
|
||||
|
||||
### 解析
|
||||
略
|
||||
|
||||
### 手动发布
|
||||
|
||||
// 创建k8s secret
|
||||
kubectl create secret tls https-ca-${yyyyMMdd} --cert=violin-home.cn_bundle.crt --key=violin-home.cn.key -n devops
|
||||
// 编辑ingress
|
||||
kubectl edit ingress violin-ingress -n devops
|
||||
// 替换名字
|
||||
略,保存退出
|
||||
|
||||
---
|
||||
|
||||
## 2. 腾讯云账号
|
||||
|
||||
<sub>bid: `2024111121297600000000000043`</sub>
|
||||
|
||||
### 云账号
|
||||
1. 索克
|
||||
|
||||
账号ID:ID100031913163
|
||||
qq号: 244385414
|
||||
账号有效时间: 2023-06-11 ~ 2026-06-11
|
||||
2. 张奎
|
||||
|
||||
|
||||
账号ID:100031899966
|
||||
微信账号:
|
||||
账号有效时间: 2023-06-11 ~ 2026-06-11
|
||||
|
||||
---
|
||||
|
||||
## 3. gogs ci/cd
|
||||
|
||||
<sub>bid: `2024111122270400000000000044`</sub>
|
||||
|
||||
### 1. Service
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: gogs
|
||||
name: gogs
|
||||
namespace: devops
|
||||
spec:
|
||||
ports:
|
||||
- name: gogs
|
||||
port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: gogs
|
||||
type: NodePort
|
||||
|
||||
### 2. Deployment
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: gogs
|
||||
name: gogs
|
||||
namespace: devops
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gogs
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: gogs
|
||||
spec:
|
||||
containers:
|
||||
- image: gogs/gogs
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: gogs
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: volv
|
||||
volumes:
|
||||
- hostPath:
|
||||
path: /root/k8s/moonfdd/gogs/data
|
||||
type: DirectoryOrCreate
|
||||
name: volv
|
||||
|
||||
### 3. PVC
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: gogs-server-data
|
||||
namespace: devops
|
||||
annotations:
|
||||
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
|
||||
---
|
||||
@@ -0,0 +1,183 @@
|
||||
# 十万个为什么
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2022050622313300000000000022` · 排序:3 · 文章数:4
|
||||
|
||||
## 目录
|
||||
|
||||
1. [java基础面试问题1](#java基础面试问题1)
|
||||
2. [31.序列化](#31序列化)
|
||||
3. [反射的原理是什么](#反射的原理是什么)
|
||||
4. [为什么JDK动态代理只能代理接口](#为什么jdk动态代理只能代理接口)
|
||||
|
||||
---
|
||||
|
||||
## 1. java基础面试问题1
|
||||
|
||||
<sub>bid: `2022050622313400000000000023`</sub>
|
||||
|
||||
## java基础面试问题
|
||||
|
||||
### 1. JAVA中的几种基本数据类型是什么,各自占用多少字节。
|
||||
基本数据类型有8种:
|
||||
|
||||
整数型
|
||||
byte 1个字节
|
||||
short 2 字节
|
||||
int 4字节
|
||||
long 8个字节
|
||||
|
||||
浮点型
|
||||
float 4字节
|
||||
double 8字节
|
||||
|
||||
布尔型
|
||||
boolean 4字节
|
||||
|
||||
字节型
|
||||
Char 两字节
|
||||
|
||||
### 2. String类能被继承吗,为什么。
|
||||
String类是被final修饰的。
|
||||
|
||||
不可以的
|
||||
被final修饰的类是不能被继承的,
|
||||
final修饰的方法是不能被重写的
|
||||
被final修饰的变量是无法重新指向另一个对象的。
|
||||
|
||||
可以的
|
||||
但是被final的方法是可以重载的。
|
||||
|
||||
### 3. StringBuilder和Stringbuffer区别
|
||||
都是字符串的类,性能String最低,Stringbuffer较好,StringBuilder最快。
|
||||
安全性上StringBuilder是线程不安全的。
|
||||
Stringbuffer是线程安全的。
|
||||
|
||||
### 4. 用过哪些Map类,都有什么区别,
|
||||
HashMap是线程安全的吗,并发下使用的Map是什么,他们
|
||||
内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。
|
||||
|
||||
比较我比较常用的
|
||||
线程不安全的HashMap,TreeMap。
|
||||
线程安全的ConcurrentHashMap,
|
||||
|
||||
### 5. ArrayList和LinkedList有什么区别
|
||||
|
||||
### 6. hashMap
|
||||
|
||||
JDK1.8 开始, 数组 + 链表 或者 数组 + 红黑树
|
||||
HashMap 维护了 一个 Node[] 的数组,默认的初始数组大小是16
|
||||
负载因子为0.75,当数组中超出容量的0.75倍时,进行容量x2扩容。
|
||||
|
||||
## 重要源码部分
|
||||
|
||||
|
||||
默认的负载因子,为什么是0.75?
|
||||
static final float DEFAULT_LOAD_FACTOR = 0.75f;
|
||||
默认的初始容量为16
|
||||
1 -》 10000 —-》 16
|
||||
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
|
||||
最大容量为2的30次方
|
||||
static final int MAXIMUM_CAPACITY = 1 << 30;
|
||||
链表到红黑树转化的阈值
|
||||
static final int TREEIFY_THRESHOLD = 8;
|
||||
红黑树到链表转化的阈值
|
||||
static final int UNTREEIFY_THRESHOLD = 6;
|
||||
转树所必要的最小容量
|
||||
static final int MIN_TREEIFY_CAPACITY = 64;
|
||||
public HashMap() {
|
||||
this.loadFactor = DEFAULT_LOAD_FACTOR;
|
||||
}
|
||||
|
||||
为什么是 异或 ? 保持更好的散列性
|
||||
右移 16位,高位补0,为什么
|
||||
static final int hash(Object key) {
|
||||
int h;
|
||||
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
|
||||
}
|
||||
|
||||
这个loadFactor 会在 resize()方法中被调用
|
||||
resize() 也是node 节点初始化的
|
||||
|
||||
## 为什么是 异或
|
||||
^ 表示 异或 运算符 - 》 相同为0 不相同为1
|
||||
异或 可以保持更好的散列性。
|
||||
与 运算 1/4 的是1 ,3/4 的是0,所以得到的数更小
|
||||
或 运算 1/4 的是0 ,3/4 的是1,所以得到的数更大
|
||||
异或 运算 2/4 的是1 ,2/4 的是0,所以得到的数更有散列性
|
||||
|
||||
## HashMap源码中在计算hash值的时候为什么要右移16位
|
||||
|
||||
(h = key.hashCode()) ^ (h >>> 16)
|
||||
h & (length-1) 与运算
|
||||
|
||||
|
||||
## 为什么 负载因子 是 0.75
|
||||
|
||||
## mod 取模运算符
|
||||
|
||||
在java 中
|
||||
取 商 运算符 /
|
||||
取 余 运算符 %
|
||||
|
||||
计算整数商 c = a/b
|
||||
计算模 r = a - c*b
|
||||
|
||||
x mod 2^n = x & (2^n - 1)
|
||||
|
||||
还是 以 10 / 8 为类
|
||||
x -》 1010
|
||||
2^n 0111
|
||||
& 运算 0010
|
||||
-----------
|
||||
2
|
||||
从二进制角度来说,x (1010)向右移动3位,得到商(1)
|
||||
除掉的部分010 则是余数,即2
|
||||
|
||||
---
|
||||
|
||||
## 2. 31.序列化
|
||||
|
||||
<sub>bid: `2022050822283700000000000002`</sub>
|
||||
|
||||
### 序列化
|
||||
---
|
||||
什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决。
|
||||
|
||||
du
|
||||
|
||||
---
|
||||
|
||||
## 3. 反射的原理是什么
|
||||
|
||||
<sub>bid: `2022050900177700000000000003`</sub>
|
||||
|
||||
反射的原理,反射创建类实例的三种方式是什么
|
||||
|
||||
Jvm加载类(包括接口,注解,枚举,接口)信息时,会将该信息以类对象(包名.类名)的形式存储于方法区。
|
||||
|
||||
Java反射是指,在Jvm运行时,对于一个类,都能通过反射获取,这个类的属性,方法,构造器等,对于一个对象,通过反射可以调用他的全部属性和方法,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
|
||||
|
||||
Java反射作为动态编译而存在,极大的提高了Java语言的灵活性。
|
||||
|
||||
Java反射有三种方式获取类实例(不是对象实例):
|
||||
1.Class.forName(),通过指定包名类名的方式在方法区去需要找该类。
|
||||
2.XXX.class, 通过类名.class,局限性是非动态。
|
||||
3.实例对象.getClass()。
|
||||
|
||||
第一种类加载方式,是加载外部类的最常用方式。
|
||||
第三种方式,是已知对象情况下的,获取该类的最好方式
|
||||
|
||||
---
|
||||
|
||||
## 4. 为什么JDK动态代理只能代理接口
|
||||
|
||||
<sub>bid: `2022122811384800000000000013`</sub>
|
||||
|
||||
为什么JDK动态代理只能代理接口,不能直接代理类?CGlib为什么可以代理类?
|
||||
|
||||
动态代理生成的Proxy\$0类是继承了Proxy类并且implements代理接口,但由于java是不能多继承的,所以动态代理不能代理类。
|
||||
|
||||
cglib实现动态代理的逻辑是使用子类继承代理类,就没有单继承的限制了.
|
||||
|
||||
---
|
||||
@@ -0,0 +1,120 @@
|
||||
# 常用 Command
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`20230409` · 排序:13 · 文章数:3
|
||||
|
||||
## 目录
|
||||
|
||||
1. [Docker](#docker)
|
||||
2. [Git](#git)
|
||||
3. [Linux](#linux)
|
||||
|
||||
---
|
||||
|
||||
## 1. Docker
|
||||
|
||||
<sub>bid: `2023040920175500000000000033`</sub>
|
||||
|
||||
## docker 常用 命令
|
||||
|
||||
### 1. 删除 None 镜像
|
||||
```
|
||||
docker images | grep none | awk '{print $3}' | xargs docker rmi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Git
|
||||
|
||||
<sub>bid: `2023040920200300000000000034`</sub>
|
||||
|
||||
该写点什么么...
|
||||
https://biprogy.box.com/s/f0du3rvo97p4rvazzfrq4235djxqjsvj
|
||||
|
||||
---
|
||||
|
||||
## 3. Linux
|
||||
|
||||
<sub>bid: `2023040920200900000000000035`</sub>
|
||||
|
||||
### 1. linux系统版本
|
||||
```bash
|
||||
uname -a
|
||||
cat /proc/version
|
||||
```
|
||||
|
||||
### 2. CPU
|
||||
```bash
|
||||
echo "wuli cpu geshu:"
|
||||
cat /proc/cpuinfo | grep "physical id" | wc -l
|
||||
echo "wuli cpu geshu:"
|
||||
cat /proc/cpuinfo | grep "processor" | wc -l
|
||||
echo "per cpu has cores:"
|
||||
cat /proc/cpuinfo | grep "cpu cores" | uniq
|
||||
```
|
||||
```bash
|
||||
cat /proc/cpuinfo | grep "name" | cut -f2 -d: | uniq -c
|
||||
```
|
||||
|
||||
```bash
|
||||
lscpu
|
||||
```
|
||||
|
||||
```bash
|
||||
top -c
|
||||
```
|
||||
|
||||
## 3. memory
|
||||
```bash
|
||||
cat /proc/meminfo
|
||||
free
|
||||
```
|
||||
|
||||
### 4. 更改hostname
|
||||
|
||||
```bash
|
||||
vi /etc/hostname
|
||||
```
|
||||
```bash
|
||||
vi /etc/hosts
|
||||
```
|
||||
```bash
|
||||
reboot
|
||||
```
|
||||
|
||||
## 5. netstat
|
||||
```bash
|
||||
netstat -ano | findstr 5000
|
||||
taskkill /f /pid 104152
|
||||
```
|
||||
|
||||
|
||||
## 6. ps查看进程
|
||||
- 查看正处于Running的进程
|
||||
```bash
|
||||
ps -ef
|
||||
```
|
||||
- 查看所有的进程
|
||||
```bash
|
||||
ps aux
|
||||
```
|
||||
|
||||
## 7. mount
|
||||
|
||||
mount是Linux下的一个命令,它可以将分区挂接到Linux的一个文件夹下,从而将分区和该目录联系起来,因此我们只要访问这个文件夹,就相当于访问该分区了。
|
||||
|
||||
- show all the mount
|
||||
```bash
|
||||
mount -l
|
||||
```
|
||||
其中 tmpfs 是临时文件系统,而tmpfs是一个文件系统,并不是块设备,只是安装它,就可以使用了。tmpfs是最好的基于RAM的文件系统
|
||||
|
||||
|
||||
## 8. alias
|
||||
|
||||
- alias [别名]='真实命令'
|
||||
```bash
|
||||
alias ku="kubectl"
|
||||
```
|
||||
|
||||
---
|
||||
@@ -0,0 +1,214 @@
|
||||
# 服务器和系统
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`00000000000004` · 排序:2 · 文章数:7
|
||||
|
||||
## 目录
|
||||
|
||||
1. [Windows](#windows)
|
||||
2. [关于Oauth的第三方授权登录](#关于oauth的第三方授权登录)
|
||||
3. [网关(gateway)](#网关gateway)
|
||||
4. [自己紹介](#自己紹介)
|
||||
5. [ssh 免密登录](#ssh-免密登录)
|
||||
6. [订单库存](#订单库存)
|
||||
7. [2024-05-02](#2024-05-02)
|
||||
|
||||
---
|
||||
|
||||
## 1. Windows
|
||||
|
||||
<sub>bid: `2022051820523400000000000007`</sub>
|
||||
|
||||
我们通过powershell安装时,经常提示
|
||||
|
||||
更改 Windows PowerShell 执行策略的用户首选项。
|
||||
Set-ExecutionPolicy
|
||||
[Doc](https://docs.microsoft.com/zh-CN/previous-versions//dd347628(v=technet.10)?redirectedfrom=MSDN)
|
||||
|
||||
Enable-WindowsOptionalFeature
|
||||
[Doc](https://docs.microsoft.com/en-us/powershell/module/dism/enable-windowsoptionalfeature?view=windowsserver2022-ps)
|
||||
|
||||
PS C:\WINDOWS\system32> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Tools-All
|
||||
Enable-WindowsOptionalFeature : 功能名称 Microsoft-Hyper-V-Tools-All 未知。
|
||||
所在位置 行:1 字符: 1
|
||||
+ Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V- ...
|
||||
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
+ CategoryInfo : NotSpecified: (:) [Enable-WindowsOptionalFeature
|
||||
], COMException
|
||||
+ FullyQualifiedErrorId : Microsoft.Dism.Commands.EnableWindowsOptionalFea
|
||||
tureCommand
|
||||
|
||||
---
|
||||
|
||||
## 2. 关于Oauth的第三方授权登录
|
||||
|
||||
<sub>bid: `2022102117264100000000000010`</sub>
|
||||
|
||||
## 关于vilin-home的 安全认证
|
||||
---
|
||||
采用third part(第三方)认证 + token,暂时只支持百度云认证。
|
||||
|
||||
采用token 是防止 设备丢失等情况发生时,可以将用户暂时剔除租户体系,保证数据安全。是作为jwt认证的一种补充手段。
|
||||
|
||||
基本的认证flow如下:
|
||||
|
||||
> 用户 -> 登录 violin-home 网站
|
||||
|
||||
> token check -> 没有token的话,进入wolcome 页面,进入登录诱导页面,有token则进入home页面
|
||||
|
||||
> 点击 百度云登录 跳转到 百度扫码 页面
|
||||
|
||||
> 扫码成功,返回 回调code的连接,同时使用code 访问 violin-book 进入token获取
|
||||
|
||||
> violin-book 获取到code后 向 百度云 进行认证,获取 token,同时进行租户check,没有租户情报的认证用户,返回sorrypage,有租户情报的认证用户,跟新认证token到redis,并且重定向到 violin-home-manage 连接
|
||||
|
||||
> 解析 violin-home-manage 连接,获取token,通过token ,向violin-book获取租户基本信息,然后 跳转到home页面
|
||||
|
||||
> 至此 认证 完了
|
||||
|
||||
---
|
||||
|
||||
## 3. 网关(gateway)
|
||||
|
||||
<sub>bid: `2022121609222900000000000008`</sub>
|
||||
|
||||
https://biprogy.box.com/s/e2k26k78uhd2x4yo4skjfghp0y7ipc2w
|
||||
|
||||
https://app.boxcn.net/folder
|
||||
|
||||
---
|
||||
|
||||
## 4. 自己紹介
|
||||
|
||||
<sub>bid: `2023021420423600000000000018`</sub>
|
||||
|
||||
本日は貴重な時間をいただきありがとうございます。
|
||||
|
||||
カンショウイと申します。今年35歳です。
|
||||
|
||||
卒業した大学は中国の東北大学ですが、大学院生の出身大学はつくば大学、専門はシステム情報工学です。
|
||||
|
||||
卒業後、1年ぶりの土木系の仕事と一年ぶりの金融知識学習をしました。2017年からITに転職、それから創科技術会社、日本ハイロン株式会社、IBM株式会社の三社で働きました。
|
||||
|
||||
経験したプロジェクトは10個以上で、設計、開発、テスト、POC検証などのいくつかのフェーズも参加しました。
|
||||
|
||||
得意な開発言語はJava、Js、Go、kubernetesです。
|
||||
|
||||
IBMに入社後、フルスタックエンジニア、コンサルタントとアーキテクチャとして活躍しております。
|
||||
|
||||
去年はクラウドネイティブ CKA と Azure Iotの資格を取りました。
|
||||
|
||||
この経験をぜひ御社でも生かしていきたいと考えております。
|
||||
|
||||
どうぞよろしくお願いいたします。
|
||||
|
||||
https://teams.microsoft.com/l/meetup-join/19%3ameeting_NjRlMmEwN2QtNTU1My00M2Q3LWEyNDEtODAyODE5OWFkODAy%40thread.v2/0?context=%7b%22Tid%22%3a%22b2c6da00-de63-4f6a-90ed-17e48a1f64a2%22%2c%22Oid%22%3a%2252e6675f-d902-4939-b53f-6b69aabfdf35%22%7d
|
||||
|
||||
---
|
||||
|
||||
## 5. ssh 免密登录
|
||||
|
||||
<sub>bid: `2023033021097900000000000028`</sub>
|
||||
|
||||
## ssh
|
||||
|
||||
### 1. ssh install
|
||||
```bash
|
||||
apt-get install openssh-server openssh-client
|
||||
```
|
||||
```bash
|
||||
service ssh start
|
||||
```
|
||||
|
||||
### 2. ssh免密登录的设置十分简单
|
||||
|
||||
|
||||
1、cd ~回到主目录,进入.ssh文件
|
||||
```bash
|
||||
cd ~/.ssh
|
||||
```
|
||||
2、ssh-keygen -t rsa 后,连续敲三次回车,生成两个文件 id_rsa是私钥,id_rsa.pub是公钥
|
||||
```bash
|
||||
ssh-keygen -t rsa
|
||||
```
|
||||
3、将公钥拷贝到目标机器上
|
||||
```bash
|
||||
ssh-copy-id node1
|
||||
```
|
||||
|
||||
简单来说,就是在master机器生成密钥对。将公钥分发给其他的机器。
|
||||
node1,node2,node3,这只是单向的情况。
|
||||
如果互相免密登录的话,就需要做N*N的设置
|
||||
|
||||
---
|
||||
|
||||
## 6. 订单库存
|
||||
|
||||
<sub>bid: `2023102715164400000000000039`</sub>
|
||||
|
||||
一.订单
|
||||
|
||||
- 商品Master表
|
||||
商品ID
|
||||
分类ID
|
||||
商品名称
|
||||
|
||||
|
||||
- 订单表
|
||||
订单ID
|
||||
收货人
|
||||
收货地址
|
||||
总金额
|
||||
实收金额
|
||||
联系电话
|
||||
订单状态
|
||||
日期
|
||||
备注
|
||||
|
||||
- 订单详细表
|
||||
订单ID
|
||||
商品ID
|
||||
日期
|
||||
批次
|
||||
状态: 退货还是购买
|
||||
单价
|
||||
数量
|
||||
总金额
|
||||
备注
|
||||
|
||||
---
|
||||
|
||||
二.在库管理
|
||||
- 库存表
|
||||
商品ID
|
||||
商品数量
|
||||
商品价格
|
||||
进货批次
|
||||
进货日期
|
||||
|
||||
- 入库
|
||||
入库ID
|
||||
入库原因:进货 还是客户退货
|
||||
入库时间
|
||||
|
||||
- 出库
|
||||
出库ID
|
||||
出库原因: 销售 还是 返品厂家
|
||||
出库时间
|
||||
---
|
||||
|
||||
三.客户管理
|
||||
客户名称
|
||||
手机
|
||||
|
||||
https://teams.microsoft.com/l/meetup-join/19%3ameeting_Yzg3NWRlOTMtMjJlOS00YWYxLTk0NWYtMTFmNzcxMzIxNWIy%40thread.v2/0?context=%7b%22Tid%22%3a%223d05ac27-c0a2-42f7-bd86-26ef7db5b382%22%2c%22Oid%22%3a%22df104270-a861-48af-b9dc-7a0600128f10%22%7d
|
||||
|
||||
---
|
||||
|
||||
## 7. 2024-05-02
|
||||
|
||||
<sub>bid: `2024050210383100000000000041`</sub>
|
||||
|
||||
作業定義
|
||||
|
||||
---
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,351 @@
|
||||
# 深入理解Java虚拟机
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`00000000000003` · 排序:0 · 文章数:9
|
||||
|
||||
## 目录
|
||||
|
||||
1. [谈一下垃圾回收算法](#谈一下垃圾回收算法)
|
||||
2. [Jvm](#jvm)
|
||||
3. [2.1运行时数据区域](#21运行时数据区域)
|
||||
4. [2.2对象内存](#22对象内存)
|
||||
5. [13.1线程安全与锁优化](#131线程安全与锁优化)
|
||||
6. [12.1Java内存模型和线程](#121java内存模型和线程)
|
||||
7. [12.2关键字volatile](#122关键字volatile)
|
||||
8. [12.3 原子性,可见性,有序性](#123-原子性可见性有序性)
|
||||
9. [12.4 Happens-Before](#124-happens-before)
|
||||
|
||||
---
|
||||
|
||||
## 1. 谈一下垃圾回收算法
|
||||
|
||||
<sub>bid: `00000000000001`</sub>
|
||||
|
||||
## Garbage Collection アルゴリズム ##
|
||||
---
|
||||
[参考文章](https://blog.csdn.net/Extraordinarylife/article/details/124309502)
|
||||
|
||||
  对于Java开发人员来说,失去了引用的对象通常会被GC回收,而我们的方法都是我们的虚拟机栈中执行的,方法执行完毕后,引用被销毁,剩余的对象自然而然就是会被GC回收。
|
||||
就如参考文章所说,JVM种虚拟机栈是随线程开启而创建,线程销毁而结束。
|
||||
  由于新的垃圾回收器G1的的出现,和方法区(永久代)的废弃,取而代之的metaspace的出现,以往的游戏知识已过时。但是其中的基本算法思想还是学要学习的。
|
||||
|
||||
基本算法思想:
|
||||
### 标记-清除(mark-sweep)
|
||||
---
|
||||
标记是一个过程,他是通过**可达性分析算法**来实现的。
|
||||
这里标记的通常是不被清除的对象,因为这样的对象很少。因为大多数对象的都是一次性的。
|
||||
清除也是一个过程,它是基于**分代收集理论**实现的。清除未被标记的对象。
|
||||
这种算法很明显会产生内存碎片化,内存不连续会直接导致提前gc的发生。
|
||||
|
||||
为了避免内存的碎片化,就有了复制算法。
|
||||
### 复制算法
|
||||
---
|
||||
复制算法是建立在标记清除算法的基础上的(即也存在标记和清除的过程)。
|
||||
标记存活对象,复制对象到存活区,清除其他区域所有对象。
|
||||
复制算法,既然是复制,就要保证左右两边的容量相等,否则会出现数组越界等情况。
|
||||
这种算法典型用在年轻代的minor gc上。
|
||||
基于这种算法,jvm内存 配分成eden,s0和s1,8:1:1的比例。
|
||||
其中s0和s1的0和1没有任何区别。这样的设计比例较好的保证了大部分对象的产生和一小部分的对象进入存活区。虽然牺牲了1的部分的空间。
|
||||
new 出来的对象都会在eden中,当eden满了后,触发minor gc,
|
||||
将存活对象移动到s0,清除eden,当eden第二次满了之后,将存活对象复制到s1,清除eden和s0,以后反复如此。
|
||||
### a
|
||||
|
||||
---
|
||||
|
||||
## 2. Jvm
|
||||
|
||||
<sub>bid: `00000000000004`</sub>
|
||||
|
||||
# Jvm #
|
||||
---
|
||||
Java Virtual Machine(Jvm)Java虚拟机
|
||||
是跨平台的关键因素。
|
||||
对于Jvm需要了解的有两大模块,一是内存模型,二是垃圾回收机制。
|
||||
## 内存模型 ##
|
||||
---
|
||||
随着Java的版本的变化,内存模型也有一定的变化。
|
||||
比如Java8后,Metaspace代替了permanent space。
|
||||
但是内存模型这个抽象概念没有消失,java虚拟机内存通常被划分为以下几个部分。
|
||||
heap:
|
||||
stack:
|
||||
native method stack
|
||||
程序计数器
|
||||
|
||||
## 垃圾回收机制/Garbage collections ##
|
||||
---
|
||||
垃圾回收机制包括算法部分和堆内存分配两部分。
|
||||
heap内存:按照java的对象的存活时间分为以下几个部分。
|
||||
Young Generation:
|
||||
Old Generation:
|
||||
由于Meta Space是使用本地内存,他不算到heap里面。
|
||||
Eden space:所有的
|
||||
|
||||
---
|
||||
|
||||
## 3. 2.1运行时数据区域
|
||||
|
||||
<sub>bid: `2022050519382600000000000012`</sub>
|
||||
|
||||
### 1.程序计数器(Program Counter Register)
|
||||
---
|
||||
**线程独有**:用于记录线程的指令位置(内存地址)。
|
||||
 如果线程正在执行的是一个java方法,那么程序计数器记录的正在执行的虚拟机字节码指令的地址;如果,正在执行的是本地Native方法,这个计数器的值应该为空(Undefined)。
|
||||
此内存区域是《Java虚拟机规范》中唯一没有规定OutofMemoryError的区域。
|
||||
|
||||
### 2.虚拟机栈(Java Virtual Machine Stack)
|
||||
---
|
||||
**线程独有**:是Java方法执行的内存模型。
|
||||
 每一个方法被执行的时候,Jvm会为该方法在该线程中创建一个栈帧(Stack Frame),用于存储 **局部变量表**,**操作数栈**,**动态链接**,**方法出口**等信息。
|
||||
 一个方法被调用,即为入栈(压栈),一个方法调用结束,即为出栈(弹栈)。不难发现栈是一个先进后出的QUEUE。
|
||||
局部变量表中存放了编译器可知的基本类型,对象引用,returnAddress类型(指向一条字节码指令的地址)。
|
||||
 这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)表示。其中64位的long和double需要两个槽。其余的数据类型只占一个Slot,局部变量表的所需的内存空间在编译期间完成分配,当进入一个方法后,方法需要在栈帧中分配的变量空间是完全确定的。这个“大小”是指的槽的数量。真正一个槽多大空间是虚拟机决定的。
|
||||
 虚拟机栈中有两个异常:一个是,StackOverFlowError,栈深度异常。另一个是OutofMemoryError,是可选的(当如果虚拟机栈可以动态扩展,但又申请不到足够内存时,发生,HotSpot虚拟机不允许,动态扩展)。
|
||||
|
||||
### 3.本地方法栈
|
||||
---
|
||||
**线程独有**:是Java native方法执行的空间区域。
|
||||
 本地方法栈和虚拟机的作用是极其相识的,只是本地方法栈只为native method服务。
|
||||
|
||||
### 4.Java 堆
|
||||
---
|
||||
**线程共享**:是Java对象和数组的存放的主要区域。
|
||||
 heap,随着java的技术的进步,所有的对象和数组都分配在堆中的z,已经不是那么绝对了。
|
||||
但是java垃圾回收器管理的区域就是堆。
|
||||
由于垃圾回收算法是基于分代类论的,但是随着java的垃圾回收技术的提升,堆的分配已经复杂化了,至少在G1垃圾回收器目前来看。
|
||||
|
||||
### 5.方法区
|
||||
---
|
||||
《Java虚拟机规范中的》的Non-heap。
|
||||
线程共享:存储已被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓冲的数据。
|
||||
其中运行时常量池作
|
||||
|
||||
### 6.直接内存
|
||||
---
|
||||
 既不是,运行时数据的一部分,也不是《虚拟机规范》中定义的区域,但这部分内存也会被频繁使用,而且可能导致OutOfMemoryError。
|
||||
JDK1.4加入了NIO类,引入了一种基于通道(channel)和缓冲区(buffer)的I/O模型,它可以使用native 方法直接分配堆外内存,然后通过Java堆中的DirectByteBuffer对象,作为这块内存的引用来进行操作,从而避免了Java堆和Native堆中的来回复制。
|
||||
|
||||
---
|
||||
|
||||
## 4. 2.2对象内存
|
||||
|
||||
<sub>bid: `2022050620338300000000000015`</sub>
|
||||
|
||||
在HotSpot虚拟机里,对象在堆中的存储布局可以划分为三个部分:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)
|
||||
|
||||
#### 对象头(Header)
|
||||
---
|
||||
对象头部包括两类信息,一类是用来存储对象自身的运行时数据,包括HashCode,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,这里的偏向是指 offset,毕竟引用所指向的对象位置不是一个区域,而是一个点。
|
||||
这部分数据长度在32/64中的长度为,4个和8个字节,被称为Mark Word。
|
||||
比如在32位下,对象未被同步锁的情况下。
|
||||
| 存储内容 | bit | state |
|
||||
| - | - | - |
|
||||
| HashCode | 25 | |
|
||||
| 分代年龄 | 4 | |
|
||||
| 存储锁标志位 | 2 | |
|
||||
| 固定为0 | 1 | |
|
||||
|
||||
---
|
||||
|
||||
## 5. 13.1线程安全与锁优化
|
||||
|
||||
<sub>bid: `2022050710179900000000000027`</sub>
|
||||
|
||||
## synchronized
|
||||
|
||||
既可以用作对象锁也可以用做类锁
|
||||
|
||||
## 类锁和对象锁
|
||||
|
||||
synchronized 对象锁: 每个对象都有一个monitor,而一个monitor只能被一个线程所拥有,当一个线程a进入monitorenter,monitor的进入数为1,同时,其他的线程就无法获取monitor,如果a再次进入monitorenter,monitor的进入数为2,所以synchronized 是可重入锁。当a monitorexit退出对象锁,则monitor的进入数减少为1,只有monitor的进入数为0时候,即没有任何线程拥有monitor
|
||||
|
||||
对象锁
|
||||
synchronizded method // 直接获取该方法的对象的对象锁
|
||||
synchronizded(object) { // 获取object的对象锁
|
||||
}
|
||||
|
||||
类锁
|
||||
static synchronizded method
|
||||
synchronizded(xxx.class) {
|
||||
}
|
||||
|
||||
-- 类锁和对象锁不会产生竞争,二者的加锁方法不会相互影响
|
||||
|
||||
## 锁在哪? biased lock 偏向锁
|
||||
|
||||
我们知道java对象有三部分组成
|
||||
对象头部 object header
|
||||
实例数据 object data
|
||||
对齐填充 向2的*n填充
|
||||
|
||||
而对象头部由Mark Word和klass pointer组成
|
||||
前8个字节为Mark Word,后4个字节为klass pointer
|
||||
其中Mark Word长度为jvm一个word的大小。64位jvm是64bit,即8个字节。
|
||||
-------------------------------------------------
|
||||
OFFSET SIZE TYPE DESCRIPTION
|
||||
0 4 (object header) markword
|
||||
0 4 (object header) markword
|
||||
8 4 (object header) klass pointer
|
||||
-------------------------------------------------
|
||||
[open jdk document](http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/oops/markOop.hpp)
|
||||
|
||||
// 64 bits:
|
||||
// --------
|
||||
// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)
|
||||
// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)
|
||||
// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
|
||||
// size:64 ----------------------------------------------------->| (CMS free block)
|
||||
//
|
||||
// unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object)
|
||||
// JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object)
|
||||
// narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)
|
||||
// unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)
|
||||
|
||||
unused hash unused age biased_lock lock
|
||||
25 -> 31 -> 1 -> 4 -> 1 -> 2 normal object(sum = 64)
|
||||
|
||||
|
||||
无锁状态下的mark word
|
||||
Java 对象刚创建时,还没有任何线程来竞争
|
||||
unused hash unused age biased_lock lock
|
||||
25 -> 31 -> 1 -> 4 -> 0 -> 01
|
||||
|
||||
偏向状态下的mark word
|
||||
偏向锁是指一段同步代码一直被一同个线程所访问,那么该线程会自动获取锁,降低获取锁的代价
|
||||
偏向锁在竞争不激烈的情况下,效率非常高。
|
||||
线程ID epoch unused age biased_lock lock
|
||||
54 -> 2 -> 1 -> 4 -> 1 -> 01
|
||||
|
||||
轻量级锁状态下的mark word
|
||||
当有两个线程开始竞争这个锁对象,锁会升级为轻量级锁,两个线程公平竞争,哪个线程先占有锁对象,Mark Word 就指向哪个线程的栈帧中的锁记录
|
||||
锁记录指针 lock
|
||||
62 -> 00
|
||||
|
||||
重量级锁状态的mark word
|
||||
重量级锁会让其他申请的线程之间进入阻塞,性能降低。
|
||||
重量级锁也就叫做同步锁,这个锁 对象 Mark Word 再次发生变化,会指向一个监视器(Monitor)对象,该监视器对象用集合的形 式,来登记和管理排队的线程。
|
||||
monitor对象指针 lock
|
||||
62 -> 10
|
||||
|
||||
## synchronized 的锁优化
|
||||
|
||||
JDK1.6开始的减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”。
|
||||
需要注意的是锁可以升级但不能降级
|
||||
|
||||
## 关于 Object 和 Thread
|
||||
|
||||
Object 类 有native 的 wait方法
|
||||
调用wait 前, obtain monitor,
|
||||
调用wait 后,释放对象锁,然后当前线程进入等待状态wait set 队列中
|
||||
|
||||
sleep() 不释放锁,sleep 可以在没有锁的情况下调用,
|
||||
|
||||
---
|
||||
|
||||
## 6. 12.1Java内存模型和线程
|
||||
|
||||
<sub>bid: `2022050920343900000000000005`</sub>
|
||||
|
||||
### 概述
|
||||
---
|
||||
衡量一个服务性能好坏的,每秒事务处理数(Transactions Per second,TPS ),是重要指标之一。
|
||||
### 硬件的效率和一致性
|
||||
---
|
||||
 由于计算机的存储效率和计算效率的相差甚大,计算机不得不引入读写速度接近于处理器运算速度的高速缓存(cache),来作为内存和cpu直接的缓冲,但也增加了计算机系统的复杂性,尤其在多核处理器时代,每个处理器都有自己的缓存,而他们又共享同一块内存,这样就导致了一个新的问题:内存一致性。
|
||||
 为了解决内存一致性,各个处理器访问缓存时都遵循一些协议,比如MSI,MESI等,而java虚拟机同样有自己的内存模型,并且和上述介绍的硬件和缓存访问操作具有高度的类比性。
|
||||
 除了增加高速缓存之外,为了使处理器的运算单元尽量的被充分利用,处理器可能对输入的代码进行乱序执行优化,,处理器会在计算后将乱序执行的结果重组,保证最终结果一致性。
|
||||
而与处理器的乱序执行优化类似,Java虚拟机的即时编译器中也有指令重排序(Instruction Recorder)优化。
|
||||
### Java 内存模型
|
||||
---
|
||||
主内存和工作内存。
|
||||
首先要明确一点,很容易混淆的是,虚拟机栈是一个jvm运行时的存储结构,并不是运算。
|
||||
从更基础的层次来说,主内存直接对应物理硬件的内存,工作内存对应于寄存器和高速缓存。
|
||||
而工作内存直接存储了被该线程使用的变量的主内存副本,这里的副本,有可能是对象的引用或者,对象的某个字段,但不会有虚拟机把整个java对象复制一次的。
|
||||
### 内存间的交互操作
|
||||
---
|
||||
Java内存模型规定了一些操作来实现内存间交互,JVM会保证它们是原子的
|
||||
lock:
|
||||
锁定,把变量标识为线程独占,作用于主内存变量
|
||||
unlock:
|
||||
解锁,把锁定的变量释放,别的线程才能使用,作用于主内存变量
|
||||
read:
|
||||
读取,把变量从主内存读取到工作内存
|
||||
load:
|
||||
载入,把read读取到的值放入工作内存的变量副本中
|
||||
use:
|
||||
使用,把工作内存中的一个变量的值传递给执行引擎
|
||||
assign:
|
||||
复制,把从执行引擎接收到的值赋给工作内存里面的变量
|
||||
store:
|
||||
存储,把工作内存中一个变量的值传递到主内存中
|
||||
write:
|
||||
写入,把store进来的数据存放到主内存的变量中
|
||||
|
||||
注意,Java内存模型,只要求上述两个操作必须按顺序执行,但没有要求连续执行。也就是说read和load之间store与write之间是可以插入其他的指令的。比如对主内存中a,b变量进行访问时,可能出现,read a,read b,load b,load a。
|
||||
后来java设计团队,对java内存模型进行了简化,read,write,lock,unlock四种
|
||||
|
||||
---
|
||||
|
||||
## 7. 12.2关键字volatile
|
||||
|
||||
<sub>bid: `2022050921201400000000000006`</sub>
|
||||
|
||||
关键字volatile是java虚拟机提供的最轻量级的同步机制。
|
||||
当一个变量被定义为volatile时,它具备两种特性。
|
||||
第一种是**可见性**。
|
||||
即每次get时,强制刷新。
|
||||
一个误解区,字节码就是原子操作,这是不对的,一个字节码指令在解释执行时,如果是编译执行,一条字节码会有可能被转化为若干个本地机器指令。此处,用-XX:+PrintAssembly参数输出反汇编来分析。
|
||||
|
||||
第二种是,**有序性**。
|
||||
即,禁止指令重排序(Instruction Recorder)优化。
|
||||
被volatile修饰的变量,赋值后会多执行一个"lock addl"操作,这个操作相当于一个memory barrier(内存屏障),指令重拍时,不能把后面的指令排序到内存屏障前面去,只有一个处理器访问时,不需要内存屏障。
|
||||
addl 是一个空操作,(把ESP寄存器的值 + 0),这个操作相当于把缓存中的变量做了一次store和write操作。
|
||||
lock iddl指令把修改同步到内存时,意味着所有的之前的操作都已完成,便形成了指令重排序无法穿越内存屏障的效果。
|
||||
针对于long和double的类型变量,不通虚拟机是有着不同的实现,此处不做描述。
|
||||
|
||||
---
|
||||
|
||||
## 8. 12.3 原子性,可见性,有序性
|
||||
|
||||
<sub>bid: `2022050921544800000000000007`</sub>
|
||||
|
||||
Java内存模型,是围绕着在并发过程中如何处理原子性,可见性,和有序性的这三个特点建立的。
|
||||
### 原子性(Atomicity)
|
||||
---
|
||||
由Java内存模型直接保证的原子性操作有,read,load,assign,use,store,write这6个,我们大致可以认为,对基本类型的访问读写都是原子性的(long double类外)。
|
||||
尽管,虚拟机没有把lock和unlock操作直接开放给用户,但是却提供了更高层次的字节码指令monitorenter和monitorexit来隐式地这两个操作,反映到同步块就是synchronized关键字,因此synchronzed块之间的操作也属于原子操作。
|
||||
### 可见性 (Visibility)
|
||||
---
|
||||
可见性,即变量的修改对其他线程是可见的,无论是普通变量还是volatile变量都是会将结果刷新到主内存的,只是volatile是其他线程获取该变量时强制刷新到主内存,而普通变量并没有。
|
||||
除此之外,java还有两个关键字能够实现可见性,即synchronized和final
|
||||
synchronized的可见性是因为"对一个变量unlock操作之前,必须先把此变量同步回到主内存中(即执行了store,write操作)"的这条规则获得的。
|
||||
而final的可见性是指,被final修饰的字段在构造器中一旦完成了初始化,并且构造器并没有把这个引用传递出去,那么其他线程就能看见final字段。
|
||||
### 有序性 (Ordering)
|
||||
---
|
||||
Java语言提供了volatile和synchronized两个关键字来保证线程之间的操作是有序性的。
|
||||
volatile本身就是禁止了指令重排序。
|
||||
而synchronized是由"一个变量在同一时刻只允许有一条线程对其进行lock操作"
|
||||
|
||||
synchronzed能保证以上三个特性,但是并发场景会影响性能。
|
||||
|
||||
---
|
||||
|
||||
## 9. 12.4 Happens-Before
|
||||
|
||||
<sub>bid: `2022050922310000000000000008`</sub>
|
||||
|
||||
### 先行发生原则(Happens-Before)
|
||||
Java内存模型中如果所有的有序性都仅靠volatile和synchronized来完成的话,会有很多操作变得啰嗦。
|
||||
Java语言有一个先行发生原则(Happens-Before)。
|
||||
规则:
|
||||
1.程序次序规则
|
||||
2.Monitor Lock Rule
|
||||
3.volatile Variable Rule
|
||||
4.Thread Start Rule,start方法最先执行
|
||||
5.Thread Termination Rule,所有方法都优先于
|
||||
6.线程中断规则。
|
||||
7.对象终结规则,一个对象初始化完成先行发生于finalize()方法。
|
||||
8.传递性,A》B,B》C,那么A》C
|
||||
jintian
|
||||
1111
|
||||
|
||||
---
|
||||
@@ -0,0 +1,475 @@
|
||||
# 计算机网路
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`2022050410146100000000000003` · 排序:7 · 文章数:5
|
||||
|
||||
## 目录
|
||||
|
||||
1. [curl 详解](#curl-详解)
|
||||
2. [Route](#route)
|
||||
3. [Tptables概念](#tptables概念)
|
||||
4. [iptables 规则和ACTION](#iptables-规则和action)
|
||||
5. [协议](#协议)
|
||||
|
||||
---
|
||||
|
||||
## 1. curl 详解
|
||||
|
||||
<sub>bid: `2023031518364800000000000023`</sub>
|
||||
|
||||
### Header
|
||||
|
||||
使用 -H 来传递参数
|
||||
|
||||
curl -H "tenantId=321" -H "authorization=xxxx:XXxx"
|
||||
|
||||
### Method
|
||||
|
||||
使用 -X 来指定方法
|
||||
|
||||
curl -X GET
|
||||
|
||||
### URL
|
||||
|
||||
对url 进行添加双引号
|
||||
|
||||
curl "www.baidu.com"
|
||||
|
||||
### example
|
||||
|
||||
#### 1. Get
|
||||
curl -H "authorization:X:XX" -H "tenantid:sssss" -X GET "localhost:8080/violin-api/api/v1/reminder?reminder_id=xxxxxx"
|
||||
|
||||
#### 2. Post
|
||||
|
||||
curl -H "Content-Type: application/json" -H "authorization:X:XX" -H "tenantid:sssss" -X POST -d '{"title":"xxxxx","info":"xxxxxxxxxxxxx"}' "localhost:8080/violin-api/api/v1/reminder"
|
||||
|
||||
### 使用注意
|
||||
|
||||
- powershell 中的curl 只是个alise 不适用
|
||||
- window下的curl 会出现编码问题,尤其"并不会编码 会导致 后台 出现下列错误
|
||||
|
||||
{"error":"invalid character '\\'' looking for beginning of value"}
|
||||
|
||||
---
|
||||
|
||||
## 2. Route
|
||||
|
||||
<sub>bid: `2023032623183000000000000024`</sub>
|
||||
|
||||
### 路由表
|
||||
---
|
||||
`ip route`
|
||||
|
||||
ip route 其实是没有体现网关存在。描述的是网卡和目的ip,源ip之间的关系
|
||||
默认 经过 10.0.8.1 走默认网卡eth0
|
||||
意思是说,下面路由要是匹配不到的话,就是经过10.0.8.1 网关(网卡设备eth0)
|
||||
去 10.0.8.0/22 也走 eth0 网卡,但是源ip是10.0.8.13
|
||||
如果是去172.17.0.0/16 走 docker0网卡,源ip是172.17.0.1
|
||||
[root@node2 dev]# ip route
|
||||
default via 10.0.8.1 dev eth0
|
||||
10.0.8.0/22 dev eth0 proto kernel scope link src 10.0.8.13
|
||||
169.254.0.0/16 dev eth0 scope link metric 1002
|
||||
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
|
||||
|
||||
|
||||
`route -n`
|
||||
|
||||
route -n 更多的体现着ip地址的设置问题,
|
||||
直接可以看到默认的网关gateway是10.0.8.1,通过子网掩码,确定网络地址,访问10.0.8.0的网关是0.0.0.0 即,内部网络,不走网关。
|
||||
[root@node2 dev]# route -n
|
||||
Kernel IP routing table
|
||||
Destination Gateway Genmask Flags Metric Ref Use Iface
|
||||
0.0.0.0 10.0.8.1 0.0.0.0 UG 0 0 0 eth0
|
||||
10.0.8.0 0.0.0.0 255.255.252.0 U 0 0 0 eth0
|
||||
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
|
||||
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
|
||||
|
||||
`ip addr`
|
||||
|
||||
inet表示主机地址和所处网络段。
|
||||
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
|
||||
link/ether 52:54:00:39:ea:c4 brd ff:ff:ff:ff:ff:ff
|
||||
inet 10.0.8.13/22 brd 10.0.11.255 scope global eth0
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 fe80::5054:ff:fe39:eac4/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
|
||||
`Flags 标记`
|
||||
|
||||
U(route is up)该路由是启动的
|
||||
H(target is a host)目标是一台主机(ip)
|
||||
G(use gateway)需要通过外部的主机传送数据包
|
||||
R(reinstate route for dynamic routing)使用动态路由时恢复路由标记
|
||||
D(dynamically installed by daemon or redirect)
|
||||
已经由服务器或转port功能设置为动态路由!
|
||||
(reject route)这个路由将不会被接受(用来组织不安全的网段)
|
||||
注:显示路由信息从上到下是从范围大到小。
|
||||
|
||||
`ip neigh`
|
||||
|
||||
10.0.8.1 这个ip地址对象的网卡是eth0还有mac,但网卡本省绑定的ip地址10.0.8.3,又和ip addr中 link src 10.0.8.3 一样。
|
||||
这样就说明了一个问题,同一网段的访问,是不通过网关直接走网卡,不同网段,需要走10.0.8.1
|
||||
[root@node3 ~]# ip neigh
|
||||
10.0.8.1 dev eth0 lladdr fe:ee:30:30:20:26 REACHABLE
|
||||
|
||||
`gateway:指的是路由通过哪个gateway出去`
|
||||
`Gateway是0.0.0.0或者*表示目标是本主机所属的网络,不需要路由`
|
||||
|
||||
|
||||
|
||||
### take in actions
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 3. Tptables概念
|
||||
|
||||
<sub>bid: `2023032623302100000000000025`</sub>
|
||||
|
||||
### Tptables概念
|
||||
---
|
||||
[新手教学](https://www.zsythink.net/archives/1199)
|
||||
iptables is a package filter firewall for linux system.
|
||||
|
||||
iptables cad do below:
|
||||
- filter package (封包过滤)
|
||||
- package redirect (封包重定向)
|
||||
- network address translation (网络地址转换)
|
||||
|
||||
to learn iptables, you should to understand the concepts of below:
|
||||
#### 1. rules
|
||||
---
|
||||
- match :符合指定的条件,比如指定的 IP 地址和端口。
|
||||
- drop :当一个包到达时,简单地丢弃,不做其它任何处理。
|
||||
- accept:和丢弃相反,接受这个包,让这个包通过。
|
||||
- reject:和丢弃相似,但它还会向发送这个包的源主机发送错误消息。这个错误消息可以指定,也可以自动产生
|
||||
- target:指定的动作,说明如何处理一个包,比如:丢弃,接受,或拒绝。
|
||||
- jump:指定的动作,说明如何处理一个包,比如:丢弃,接受,或拒绝。
|
||||
- rule:一个或多个匹配及其对应的目标。
|
||||
|
||||
#### 2. iptables和netfilter的关系
|
||||
---
|
||||
iptables只是Linux防火墙的管理工具而已,位于/sbin/iptables
|
||||
真正实现防火墙功能的是 netfilter,它是Linux内核中实现包过滤的内部结构。
|
||||
|
||||
#### 3. iptables的规则表和链
|
||||
---
|
||||
- 表(tables):
|
||||
iptables内置了4个表,即filter表、nat表、mangle表和raw表。
|
||||
分别用于实现包过滤,网络地址转换、包重构(修改)和数据跟踪处理。
|
||||
|
||||
- 链(chains):
|
||||
一个有顺序的check list,每一条链中可以有一条或数条规则。
|
||||
如果满足,系统就会根据该条规则所定义的方法处理该数据包;
|
||||
否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。
|
||||
|
||||
- 规则表:
|
||||
1)filter表——三个链:INPUT、FORWARD、OUTPUT
|
||||
作用:过滤数据包 内核模块:iptables_filter.
|
||||
2)Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT
|
||||
作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat
|
||||
3)Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
|
||||
作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它)
|
||||
4)Raw表——两个链:OUTPUT、PREROUTING
|
||||
作用:决定数据包是否被状态跟踪机制处理 内核模块:iptable_raw
|
||||
|
||||
- 规则链:
|
||||
1)INPUT——进来的数据包应用此规则链中的策略
|
||||
2)OUTPUT——外出的数据包应用此规则链中的策略
|
||||
3)FORWARD——转发数据包时应用此规则链中的策略
|
||||
4)PREROUTING——对数据包作路由选择前应用此链中的规则
|
||||
(记住!所有的数据包进来的时侯都先由这个链处理)
|
||||
5)POSTROUTING——对数据包作路由选择后应用此链中的规则
|
||||
(所有的数据包出来的时侯都先由这个链处理)
|
||||
---
|
||||
### command
|
||||
[参照](http://t.zoukankan.com/sixloop-p-iptables-save-help.html)
|
||||
[命令参照](https://zhuanlan.zhihu.com/p/160840906)
|
||||
|
||||
|
||||
iptables --help 也能看到,先列出一些常用的.
|
||||
|
||||
-A --append
|
||||
Append to chain
|
||||
-m --match match
|
||||
extended match (may load extension)
|
||||
-s --source address[/mask][...]
|
||||
source specification
|
||||
-d --destination -d address[/mask][...]
|
||||
destination specification
|
||||
-j --jump -j target
|
||||
target for rule (may load target extension)
|
||||
-p --protocol -p proto
|
||||
protocol: by number or name, eg. 'tcp'
|
||||
-N --new -N chain
|
||||
Create a new user-defined chain
|
||||
-t --table -t table
|
||||
table to manipulate (default: `filter')
|
||||
-i --in-interface -i [!] input name[+]
|
||||
network interface name ([+] for wildcard)
|
||||
-o --out-interface -o [!] output name[+]
|
||||
network interface name ([+] for wildcard)
|
||||
### 一些memo
|
||||
---
|
||||
[新手教学](https://www.zsythink.net/archives/1199)
|
||||
|
||||
1. 通常我们只关系nat表和filter表
|
||||
`raw -> mangle -> nat -> filter`
|
||||
2. 创建 chain 时候,如果不指定-t table,默认是filter表
|
||||
3. ! 表示 取非
|
||||
`-p ! tcp 表示不是tcp的`
|
||||
4. iptables -h 中的[!]表示支持 非 规则
|
||||
`[!] --protocol -p proto protocol: by number or name, eg. tcp`
|
||||
5. -i -o 是匹配网卡
|
||||
6. iptables -m comment 模块
|
||||
`iptables -m comment --comment "xxx"`
|
||||
就是对该chain进行解释。其中comment是扩展模块,常见的模块有addrtype 模块了。
|
||||
`iptables -m addrtype --dst-type LOCAL -j DOCKER`
|
||||
`iptables -m addrtype --help 可以看更详细解说`
|
||||
addrtype表示对报文的地址类型进行匹配,-dst-type 表示destination
|
||||
LOCAL:表示地址是本地地址,指本地一切地址含:127.0.0.1回环地址
|
||||
|
||||
7. -j DNAT 和 -j SNAT
|
||||
8.
|
||||
|
||||
---
|
||||
|
||||
## 4. iptables 规则和ACTION
|
||||
|
||||
<sub>bid: `2023032623358600000000000026`</sub>
|
||||
|
||||
### 规则查询
|
||||
---
|
||||
`iptables -t filter -L`
|
||||
`iptables -nvL INPUT`
|
||||
|
||||
[root@node3 ~]# iptables -nvL INPUT
|
||||
# policy 表示默认规则
|
||||
Chain INPUT (policy ACCEPT 344K packets, 31M bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
0 0 in_test tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000
|
||||
1741K 187M KUBE-FIREWALL all -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
|
||||
### 规则管理
|
||||
---
|
||||
`iptables -F INPUT`
|
||||
|
||||
# 清空filter表的INPUT链
|
||||
iptables -F INPUT
|
||||
|
||||
# 添加拒绝INPUT规则
|
||||
# -I 表示链首插入规则,-A 表示链尾添加规则
|
||||
# 来自49.233.4.79 的 丢弃
|
||||
iptables -t filter -I INPUT -s 49.233.4.79 -j DROP
|
||||
# 所以就算添加了下面的ACCEPT规则,也是ping不同的,因为在链首已经被丢弃
|
||||
iptables -t filter -A INPUT -s 49.233.4.79 -j ACCEPT
|
||||
# 如果我再把这个规则添加到链首,就可以ping通了。
|
||||
iptables -t filter -I INPUT -s 49.233.4.79 -j ACCEPT
|
||||
|
||||
[root@node3 ~]# iptables -nvL INPUT
|
||||
Chain INPUT (policy ACCEPT 451 packets, 45257 bytes)
|
||||
pkts bytes target prot opt in out source destination
|
||||
2 168 ACCEPT all -- * * 49.233.4.79 0.0.0.0/0
|
||||
5 420 DROP all -- * * 49.233.4.79 0.0.0.0/0
|
||||
0 0 ACCEPT all -- * * 49.233.4.79 0.0.0.0/0
|
||||
|
||||
### 删除规则
|
||||
---
|
||||
|
||||
# 指定编号删除 -D INPUT 3 ,删除INPUT 链中,编号为3的规则
|
||||
# 先查看规则编号 使用--line
|
||||
iptables -nvL INPUT --line
|
||||
iptables -t filter -D INPUT 3
|
||||
|
||||
# 根据匹配条件删除
|
||||
iptables -t filter -D INPUT -s 49.233.4.79 -j ACCEPT
|
||||
|
||||
# 整体删除
|
||||
iptables -t filter -F
|
||||
|
||||
### 修改规则
|
||||
---
|
||||
|
||||
# 使用-R 指定链,使用数字 来指定 具有相同数字编号的规则
|
||||
iptables -t filter -R INPUT 1 -s 49.233.4.79 -j REJECT
|
||||
|
||||
# 可以看到 REJECT是拒绝行为
|
||||
[root@node1 tomcat]# ping 43.138.73.106
|
||||
PING 43.138.73.106 (43.138.73.106) 56(84) bytes of data.
|
||||
From 43.138.73.106 icmp_seq=1 Destination Port Unreachable
|
||||
From 43.138.73.106 icmp_seq=2 Destination Port Unreachable
|
||||
### 保存规则
|
||||
---
|
||||
|
||||
service iptables save
|
||||
|
||||
### 匹配规则
|
||||
---
|
||||
1. 如果匹配不到任何规则,那么就匹配默认规则(policy)。
|
||||
|
||||
# 小误区,关于! 的用法理解,
|
||||
iptable -t filter -F
|
||||
# 不是 49.233.4.79 的都接受,但是并没有说是49.233.4.79的拒绝
|
||||
# 只是说49.233.4.79的没有匹配到这个规则,因为INPUT 默认都是 ACCEPT
|
||||
# 所以,49.233.4.79的也会通过
|
||||
iptables -t filter -A INPUT 1 -s !49.233.4.79 -j ACCEPT
|
||||
# -s -d 如果不指定,即0.0.0.0/0 即所有ip
|
||||
# 多个条件是 and 关系,必须都符合
|
||||
2. 匹配条件:协议类型
|
||||
|
||||
# 使用-p选项,指定需要匹配的报文的协议类型
|
||||
# 比如我们拒绝tcp协议
|
||||
iptables -t filter -F
|
||||
iptables -t filter -I INPUT -s 49.233.4.79 -p tcp -j REJECT
|
||||
# 这样我们ping 是可以ping通的,因为ping是icmp协议
|
||||
# 而curl 43.138.73.106 是被拒绝的,因为是http(tcp)协议
|
||||
# centos7中 支持以下协议
|
||||
# tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh
|
||||
# 不指定协议,即 -p all 任意匹配
|
||||
|
||||
3. 匹配条件:网卡接口
|
||||
|
||||
# -i -o
|
||||
# -i 表示来自哪个网卡
|
||||
# PREROUTING 和 INPUT FORWARD 使用
|
||||
# -o 表示要去哪个网卡
|
||||
# POSTROUTING 和 OUTPUT FORWARD 使用
|
||||
4. -m match 扩展匹配
|
||||
|
||||
# 如果想要使用扩展匹配条件,则需要依赖一些扩展模块
|
||||
# 即扩展匹配,需要使用-m来指定模块
|
||||
iptables -A INPUT -s 49.233.4.79 -p tcp -m tcp --dport 80 -j REJECT
|
||||
[root@node3 ~]# iptables -nvL INPUT --line
|
||||
Chain INPUT (policy ACCEPT 14 packets, 964 bytes)
|
||||
num pkts bytes target prot opt in out source destination
|
||||
1 2 120 REJECT tcp -- * * 49.233.4.79 0.0.0.0/0 reject-with icmp-port-unreachable
|
||||
2 0 0 REJECT tcp -- * * 49.233.4.79 0.0.0.0/0 tcp dpt:80 reject-with icmp-port-unreachable
|
||||
# 可以看出 上面是使用-m tcp 使用tcp扩展模块
|
||||
# 如果-p tcp 和 -m tcp 是一样的时候,-m tcp是可以省略的
|
||||
# --sport 表示源端口号
|
||||
# –dport 22:25 表示22,23,24,25 范围
|
||||
# :22 和 80: 表示 0:22 80:65535
|
||||
# 多个离散端口使用 multiport 模块
|
||||
-m multiport –dports 22,36,80
|
||||
|
||||
5. -m iprange 扩展模块
|
||||
|
||||
使用iprange扩展模块可以指定”一段连续的IP地址范围”,用于匹配报文的源地址或者目标地址
|
||||
# --src-range --dst-range
|
||||
-m iprange --src-range 192.168.1.127-192.168.1.146
|
||||
|
||||
6. -m conntrack 扩展模块
|
||||
|
||||
conntrack 状态跟踪
|
||||
conntrack共可以为连接标记五种状态:
|
||||
NEW,ESTABLISHED,RELATED,INVALID,UNTRACKED
|
||||
|
||||
|
||||
### 自定义链
|
||||
---
|
||||
|
||||
自定义链并不能直接使用,而是需要被默认链引用才能够使
|
||||
# 自定义链IN-WEB
|
||||
iptables -F INPUT
|
||||
iptables -N IN-WEB
|
||||
# 可以看到,自定义链没有被任何默认的链引用,即无效状态。
|
||||
Chain IN-WEB (0 references)
|
||||
pkts bytes target prot opt in out source destination
|
||||
|
||||
删除 -X 自定义链,但是删除前必须要清空链上的规则
|
||||
iptables -F IN-WEB
|
||||
iptables -X IN-WEB
|
||||
|
||||
### ACTION
|
||||
---
|
||||
我们知道-j target ,target既可以接ACTION,也可以接Chain
|
||||
我们已知的ACTION有 ACCEPT,DROP,REJECT
|
||||
|
||||
`ACCPET`
|
||||
|
||||
ACCEPT 将封包放行,进行完此处理动作后,将不再比对其它规则,直接跳往下一个规则炼。
|
||||
`MARK`
|
||||
|
||||
MARK 将封包标上某个代号,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续比对其它规则
|
||||
`RETURN`
|
||||
|
||||
结束在目前规则炼中的过滤程序,返回主规则炼继续过滤.
|
||||
如果把自定义规则炼看成是一个子程序,那么这个动作,就相当于提早结束子程序并返回到主程序中。
|
||||
`SNAT`
|
||||
|
||||
改写封包来源 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后
|
||||
将直接跳往下一个规则炼(mangle:postrouting)。范例如下:
|
||||
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000
|
||||
`DNAT`
|
||||
|
||||
DNAT 改写封包目的地 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,
|
||||
将会直接跳往下一个规则炼(filter:input 或 filter:forward)。范例如下:
|
||||
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10:80-100
|
||||
`REJECT`
|
||||
|
||||
拦阻该封包,并传送封包通知对方
|
||||
|
||||
`DROP`
|
||||
|
||||
丢弃封包不予处理,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序
|
||||
|
||||
`REDIRECT`
|
||||
|
||||
...
|
||||
`MASQUERADE`
|
||||
|
||||
...
|
||||
|
||||
|
||||
`NAT这个概念:`
|
||||
|
||||
NAT是Network Address Translation的缩写,译为”网络地址转换”,NAT说白了就是修改报文的IP地址
|
||||
-j SNAT --to-source xxx.xxx.xxx.x
|
||||
-j DNAT --to-destination xxx.xx
|
||||
|
||||
### 关于链的顺序
|
||||
---
|
||||
|
||||
- nat 表中的规则可以被哪些链使用:PREROUTING,OUTPUT,POSTROUTING(centos7中还有INPUT,centos6中没有)
|
||||
|
||||
- filter 表中的规则可以被哪些链使用:INPUT,FORWARD,OUTPUT
|
||||
|
||||
raw 和 mangle不去考虑的话
|
||||
表的顺序是 nat -> filter
|
||||
1. 当一个数据包进入网卡时,它首先进入PREROUTING链
|
||||
nat -> PREROUTING
|
||||
|
||||
2.1 如果数据包就是进入本机的
|
||||
nat -> INPUT
|
||||
filter -> INPUT
|
||||
nat -> OUTPUT
|
||||
filter -> OUTPUT
|
||||
|
||||
2.2 如果数据包是需要转发的
|
||||
filter -> FORWARD
|
||||
|
||||
3. 最后进入POSTROUTING
|
||||
nat -> POSTROUTING
|
||||
|
||||
1
|
||||
2
|
||||
|
||||
---
|
||||
|
||||
## 5. 协议
|
||||
|
||||
<sub>bid: `2023032623438200000000000027`</sub>
|
||||
|
||||
## 协议
|
||||
传输层TCP -
|
||||
网路层协议IP - 报文
|
||||
数据链路层协议MAC - 帧
|
||||
---
|
||||
### ARP协议
|
||||
---
|
||||
[ARP](https://blog.csdn.net/weixin_39761696/article/details/110578444)
|
||||
ADDRESS Resolution protocol 是一个通过第三层IP地址,找到第二层MAC的协议。
|
||||
OSI模型把网络运营分成七层,IP地址在OSI模型的第三层,MAC地址在第二层,彼此之间不立即相处。在根据以太网接口推送IP数据时,必须先封装形式第三层(32位IP地址)、再封装第二层(48位MAC地址)的报头,但因为推送时只了解总体目标IP地址,不清楚其MAC地址,又不可以跨第二、三层,因此必须应用地址解析协义。
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user