rclone同步文件到Google云盘
安装unzip
rclone安装用的到unzip
apt install -y unzip
安装fuse3
apt install -y fuse3
安装socat (可选)
socat 用于后续配置的时候, 代理127.0.0.1上的端口.也可以用其他代理工具代理
apt install -y socat
安装rclone
curl https://rclone.org/install.sh | sudo bash
创建本地文件夹,用于同步远程
mkdir -p /google_drive_local
配置
rclone config
注意是 google drive,不是 google cloud 或 google photos
socat代理端口
配置的过程中, 会等待回调http:127.0.0.1:xxxx这样的端口 由于Linux上没有安装桌面端,需要代理出来,在桌面端浏览器访问
如下,将服务器上的127.0.0.1的xxxx端口映射到Linux公网IP上的1234端口
#如 控制台这样提示的时候, 使用下面命令 2024/05/10 01:38:21 NOTICE: If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=Czs9IR66wt5eLQYQtlogbQ
socat TCP-LISTEN:1234,fork,reuseaddr TCP:127.0.0.1:53682
代理成功后, 在桌面端浏览器访问, 访问完成,授权登录后,Linux终端会提示Success,即完成了配置
创建Service, 启动挂载
需要特别注意的是: rclone mount 每次挂载后,总是用云盘的数据覆盖本地的挂载文件夹, 所以云盘上不存在,但是存在于本地挂载文件夹/google_drive_local下的数据一定要先做备份,避免覆盖丢失
vim /etc/systemd/system/rclone-mount.service 文件内容如下
[Unit]
Description=RClone Mount Service
After=network-online.target
[Service]
User=root
Group=root
ExecStart=/usr/bin/rclone mount google_drive:/vps_backup/xjp /google_drive_local --allow-other --allow-non-empty --vfs-cache-mode writes
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
重新加载 systemd 并启动服务
sudo systemctl daemon-reload
sudo systemctl start rclone-mount.service
sudo systemctl enable rclone-mount.service
创建备份脚本
vim /usr/local/bin/vps_backup 内容如下
cd / && tar -zcvf app.tar.gz /app/ && mv app.tar.gz /google_drive_local/
赋予执行权限chmod +x /usr/local/bin/vps_backup
编写定时任务
执行crontab -e
打开定时任务配置文件,
增加以下内容
#12小时同步一次
0 */12 * * * /usr/local/bin/vps_backup
#30分钟执行一次
*/30 * * * * /usr/local/bin/vps_backup
查看所有的rclone配置
rclone config show
docker-compose网络
docker-compose网络
网段隔离
在不同的文件下存放docker-compose.yml, 如mysql/docker-compose.yml, redis/docker-compose.yml, 当执行docker-compose up -d会自动创建一个新的网络. 通过docker network ls
可以看到. 每一个网络相互隔离.
root@ec2-0804:# docker network ls
NETWORK ID NAME DRIVER SCOPE
8fbc5468dcab bridge bridge local
46e3affd9d7c host host local
e778a30f25d4 mysql_default bridge local
3b2337441be6 vaultwarden_default bridge local
网段打通
有时候, 并不想隔离, 比如zk和kafka共享一个网络. 比如应用微服务和mysql共享同一个网络
方法一
nginx和kafka存放在同一个nginx\docker-compose.yml中,启动后自然就是同一个网络. 如
version: '3.8'
services:
nginx:
image: zookeeper
container_name: nginx
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
启动后, 会创建一个新的网络nginx_default,前缀来自于当前docker-compose.yml所在的文件夹的名字
方法二
手动创建一个网络
docker network create --driver=bridge --subnet=172.16.238.0/24 --gateway=172.16.238.1 my_docker_network
在不同的docker-compose.yml中指定想要加入的网络
version: '3.8'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
environment:
#
- WEBSOCKET_ENABLED=true
# 禁止邀请
- INVITATIONS_ALLOWED=false
# 禁止注册. 注意, 初始化搭建的时候.需要改成true,启动后注册用户.注册成功后,改成false,重新执行docker-compose up -d
- SIGNUPS_ALLOWED=false
- ADMIN_TOKEN=AqaiTTm4LbMaTCyVFLTFzwmHPxxYa4Kg
volumes:
- /app/docker/vaultwarden/data:/data/
#ports:
# 由于vaultwarden和nginx部署在了同一个网络下,所以用服务名通信了.因此不需要暴漏80端口
#- "80:80"
networks:
- my_docker_network
networks:
my_docker_network:
external: true
docker常用操作记录
容器中执行apt update报错
解决办法
sed -i 's/stretch/buster/g' /etc/apt/sources.list
查看指定容器的近10条日志
docker logs --tail 10 -f mariadb1
docker指定常用参数
- 指定网络
- 指定ipv4地址
- 绑定hosts
version: '3.8'
services:
nginx:
image: nginx:1.21.1
container_name: nginx
restart: always
ports:
- 80:80
- 443:443
volumes:
- /app/docker/nginx/nginx:/etc/nginx
- /root/.acme.sh/*.nguone.eu.org_ecc/fullchain.cer:/etc/nginx/ssl/vaultwarden.crt:ro
- /root/.acme.sh/*.nguone.eu.org_ecc/*.nguone.eu.org.key:/etc/nginx/ssl/vaultwarden.key:ro
extra_hosts:
- "remotework.nguone.eu.org:172.31.5.162"
networks:
my_docker_network:
ipv4_address: 172.16.238.6
networks:
my_docker_network:
external: true
docker gitea搭建
docker-compose.yml
version: '3.8'
services:
gitea:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gitea/gitea:1.22.3
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- DB_TYPE=sqlite3
restart: always
volumes:
- ./data:/data
ports:
- "3000:3000" # Gitea 的 Web UI 端口,也是通过http 克隆项目的端口
- "2222:22" # 如果这里使用22端口. 拉取项目的时候可以省去端口号.因为通过ssh key clone项目用的是22端口
启动
需要注意的时候, git要使用22端口.默认情况下22端口被宿主机的ssh占用.所以需要修改宿主机下的Port 22 为其他端口, 修改后切记放行新的ssh端口,防止无法ssh .
systemctl resetart sshd
重新启动sshd
docker-compose up -d
启动成功后,访问http://宿主机IP:3000访问web控制台.注册一个管理员
需要注意的是,如果端口改成非22端口了,比如2222.那么初始化安装的时候, [SSH Server Port]要修改ssh端口为2222,而不是默认的22 这里的修改的2222是指以后拉取项目用的端口地址,而不是容器的内部端口,内部端口仍然是22
注册好管理员后, 通过命令行把注册禁用掉
docker exec -it gitea bash
vi /data/gitea/conf/app.ini
# 找到 DISABLE_REGISTRATION, 将值从false,改为true.
修改完后,退出docker容器. 重启gitea docker restart gitea
ssh key clone
gitea 默认使用3071长度的ssh key拉取项目.所以Windows或者Linux默认的2048无法使用.
生成3071长度的密钥
3071 表示 位长的 RSA 密钥
ssh-keygen -t rsa -b 3071
生成之后, 登录gitea web控制台将公钥添加到SSH / GPG Kyes 中 就可以正常clone项目了
补充说明
通过ssh拉取项目
推荐搭建gitea的时候使用22端口
- 使用22端口拉取项目
git clone git@git服务器IP/项目组或者用户名/work-record.git
- 使用2222端口拉取项目
git clone ssh://git@git服务器IP:2222/项目组或者用户名/work-record.git
docker anylink搭建
生成web控制台登录密码
nooqu6aifahsh5Ae为web控制台登录密码
docker run -it --rm stilleshan/anylink:0.9.3 tool -p nooqu6aifahsh5Ae
生成 jwt secret
docker run -it --rm stilleshan/anylink:0.9.3 tool -s
docker-compose搭建Nextcloud
docker-compose.yml
version: '3.9'
services:
nextcloud:
image: nextcloud:latest
container_name: nextcloud
ports:
- "8080:80" # 将主机的 8080 端口映射到容器的 80 端口
volumes:
- nextcloud_data:/var/www/html
- ./config/config.php:/var/www/html/config/config.php
environment:
- MYSQL_HOST=mysql5.7.28 # 使用你的 MySQL 容器名称作为主机名
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud_user
- MYSQL_PASSWORD=Aphu2jieChie6mo2
networks:
- mysql_default
networks:
mysql_default:
external: true
volumes:
nextcloud_data:
./config/config.php配置
支持HTTPS域名访问,输入自己的域名
'trusted_domains' =>
array (
0 => 'nextcloud.mydomain.xyz',
),
赋予权限
docker exec -it nextcloud bash
chown -R www-data:www-data /var/www/html/config
chmod -R 755 /var/www/html/config
chown www-data:www-data /var/www/html/config/config.php
chmod 644 /var/www/html/config/config.php
然后使用Nginx转发即可, 最后重启Nginx,即可完成https访问.可以参考**Linux常用技巧篇的Nginx https配置**
彻底删除
docker rm -f nextcloud
docker volume ls
docker volume rm nextcloud_data
rm -rf ./nextcloud_data
docker rmi nextcloud:latest
基于阿里云盘webdav实现owncloud双备份
创建目录
mkdir -p /app/docker/aliyundrive-webdav
创建docker-compose.yml
cd /app/docker/aliyundrive-webdav && nano docker-compose.yml
version: '3.8'
services:
aliyundrive-webdav:
image: messense/aliyundrive-webdav
container_name: aliyundrive-webdav
restart: always
# ports:
# - "28080:8080"
environment:
- REFRESH_TOKEN=${REFRESH_TOKEN} # REFRESH_TOKEN写在.env文件中,防止太长的字符串在docker-compose中被截断,注意这里实际上是对应access_token
- WEBDAV_AUTH_USER=这里是webdav的网页登录用户名,自定义
- WEBDAV_AUTH_PASSWORD=这里是webdav的网页登录密码,自定义
env_file:
- .env
.env
nano .env
REFRESH_TOKEN=xxxx改成自己的token
-
参考 :https://github.com/messense/aliyundrive-webdav?tab=readme-ov-file
启动aliyundrive-webdav
docker-compose up -d
通过rclone webdav配置
rclone config
# 按照提示配置。选webdav。密码和密码就是上面配置的
挂载
假如上面配置的阿里云盘名叫aliyun_drive
mkdir /aliyun_drive_local && nohup rclone mount aliyun_drive:/ /aliyun_drive_local --vfs-cache-mode writes >> /tmp/aliyun_drive_local.log 2>&1 &
开机自动挂载
sudo nano /etc/systemd/system/rclone-mount.service
[Unit]
Description=Mount Aliyun Drive with Rclone
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/rclone mount aliyun_drive:/ /aliyun_drive_local --vfs-cache-mode writes
ExecStop=/bin/fusermount -u /aliyun_drive_local
Restart=on-failure
User=root
Group=root
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl restart rclone-mount.service
安装inotify,用于监听owncloud文件变化
sudo apt update
sudo apt install inotify-tools
配置脚本sync_with_inotify.sh
nano /app/sync_with_inotify.sh
通过
inotifywait
实现对指定目录的实时监控,一旦检测到文件的创建、修改、删除或移动事件,就会触发rclone sync
命令,将本地目录同步到远程存储(如阿里云盘)。它还包含一些优化措施,例如延迟处理、避免重复触发等
#!/bin/bash
LOCAL_DIR="/app/docker/owncloud/owncloud/data/files/admin/files"
LOG_FILE="/tmp/rclone_owncloud.log"
## 使用 inotifywait 监听本地文件夹变化
inotifywait -m -r -e create,modify,delete,move "$LOCAL_DIR" |
while read -r directory events filename; do
echo "Detected $events on $filename"
# 延迟执行,避免频繁触发
sleep 10
# 防止重复同步
if pgrep -f "rclone sync" > /dev/null; then
echo "Sync is already running, skipping this event."
continue
fi
rclone sync "$LOCAL_DIR" aliyun_drive:/owncloud_backup \
--exclude "*.d*" \
--transfers 2 \
--checkers 2 \
--delete-during \
--log-level DEBUG \
--log-file "$LOG_FILE"
done
-
命令解释:
-
-m
:开启持续监控模式。 -
-r
:递归监听子目录中的变化。 -
-e create,modify,delete,move
:监听以下事件:
create
:文件或目录的创建。modify
:文件内容的修改。delete
:文件或目录的删除。move
:文件或目录的移动或重命名。
-
"$LOCAL_DIR"
:指定要监听的目录。
功能:当监控的目录中发生指定的事件时,将事件信息通过管道传递到
while
循环中。 -
添加执行权限
chmod +x /app/sync_with_inotify.sh
作为服务启动
sudo nano /etc/systemd/system/sync_with_inotify.service
[Unit]
Description=Sync files with Aliyun Drive using rclone and inotify
After=network.target
[Service]
ExecStart=/bin/bash /app/sync_with_inotify.sh
Restart=always
RestartSec=10s
User=root
WorkingDirectory=/app
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
重新加载 systemd 配置
sudo systemctl daemon-reload
启动并使服务开机启动
sudo systemctl start sync_with_inotify.service
sudo systemctl enable sync_with_inotify.service
sudo systemctl status sync_with_inotify.service
sudo systemctl restart sync_with_inotify.service
sudo systemctl stop sync_with_inotify.service
查看日志
journalctl -u sync_with_inotify.service -f
手动同步
多次同步不影响
rclone sync "/app/docker/owncloud-ok/files/files/" aliyun_drive:/owncloud_backup --exclude "*.d*" --transfers 2 --checkers 2 --delete-during --log-level DEBUG --log-file /app/rclone_owncloud.log
查看日志文件
tail -f /tmp/rclone_owncloud.log
需要将webdav的IP固定
避免重启服务后,IP变化....最终导致rclone中的webdav地址发生变化,无法连接到webdav
不想挂载时,卸载已挂载的文件夹
fusermount -uz /aliyun_drive_local
基于docker-compose安装fail2ban
安装rsyslog
fail2ban依赖rsyslog,安装并启动后,会产生日志文件 /var/log/auth.log
apt update
apt install rsyslog -y
rsyslogd
docker-compose.yml
mkdir -p /app/docker/fail2ban/
cd /app/docker/fail2ban/
cat <<EOF > docker-compose.yml
version: '3.8'
services:
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: always
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- ./data:/data
- /var/log:/var/log:ro
EOF
启动
docker-compose up -d
配置SSH规则
vim data/jail.d/sshd.conf
#内容如下
cat <<EOF > data/jail.d/sshd.conf
[sshd]
enabled = true
chain = INPUT
port = ssh
filter = sshd[mode=aggressive]
logpath = /var/log/auth.log
maxretry = 3
findtime = 60 # 1 分钟内
bantime = 31536000 # 封禁 365 天(31,536,000 秒)
EOF
重启启动
docker-compose restart
查看被ban的记录
docker exec fail2ban fail2ban-client status sshd
如下:
root@:/app/docker/fail2ban# docker exec fail2ban fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 3
|- Total banned: 3
`- Banned IP list: 123.58.207.155 92.255.85.107 92.255.85.253
解封IP
docker exec fail2ban fail2ban-client set sshd unbanip 1.1.1.1
ban一个ip
docker exec fail2ban fail2ban-client set sshd banip 103.167.64.9
查看有效的登录用户
grep -E '/bin/bash|/bin/zsh' /etc/passwd
显示当前登录到系统的用户信息
who
显示系统中所有的登录和注销记录
last
who 与 last 的区别:
who:显示当前系统中正在登录的用户。
实时信息,反映当前在线的用户。 不包括注销的历史记录。 last:显示所有的登录和注销历史记录。
包括历史记录,反映所有曾经登录过的用户(包括已注销的)。 可以查看每个用户的登录时长和注销信息。
docker-compose部署apollo 2.2.0
- 创建文件夹
mkdir -p /app/docker/apollo
- 最终目录结构如下:
tree
.
├── docker-compose.yml
└── sql
├── 01-apolloconfigdb.sql
├── 02-apolloconfigdb.sql
├── 03-init-user.sql
└── 04-init-eureka-url.sql
2 directories, 5 files
- 01-apolloconfigdb.sql 文件内容
services:
apollo-db:
image: mariadb:10.11
container_name: apollo-db
environment:
MYSQL_ROOT_PASSWORD: xoopooth4gie6doo5Aechieteev9genu
MYSQL_USER: apollo
MYSQL_PASSWORD: apollo123
volumes:
- ./sql:/docker-entrypoint-initdb.d
- db_data:/var/lib/mysql
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-uapollo", "-papollo123", "--silent"]
interval: 5s
timeout: 10s
retries: 10
apollo-configservice:
image: apolloconfig/apollo-configservice:2.2.0
container_name: apollo-configservice
depends_on:
apollo-db:
condition: service_healthy
environment:
SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_URL: jdbc:mysql://apollo-db:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
SPRING_DATASOURCE_USERNAME: apollo
SPRING_DATASOURCE_PASSWORD: apollo123
EUREKA_INSTANCE_HOSTNAME: apollo-configservice
EUREKA_INSTANCE_IP_ADDRESS: apollo-configservice
EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE: http://apollo-configservice:8080/eureka/
EUREKA_SERVER_ENABLE_SELF_PRESERVATION: "false"
EUREKA_SERVER_EVICTION_INTERVAL_TIMER_IN_MS: "5000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 5
apollo-adminservice:
image: apolloconfig/apollo-adminservice:2.2.0
container_name: apollo-adminservice
depends_on:
apollo-configservice:
condition: service_healthy
environment:
SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_URL: jdbc:mysql://apollo-db:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
SPRING_DATASOURCE_USERNAME: apollo
SPRING_DATASOURCE_PASSWORD: apollo123
EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE: http://apollo-configservice:8080/eureka/
EUREKA_INSTANCE_HOSTNAME: apollo-adminservice
EUREKA_INSTANCE_IP_ADDRESS: apollo-adminservice
EUREKA_CLIENT_REGISTER_WITH_EUREKA: "true"
EUREKA_CLIENT_FETCH_REGISTRY: "true"
# 显式覆盖所有可能的配置键(不同大小写和格式)
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://apollo-configservice:8080/eureka/
SPRING_CLOUD_CONFIG_ENABLED: "false" # 禁用配置服务器覆盖
SPRING_APPLICATION_JSON: '{"eureka":{"client":{"serviceUrl":{"defaultZone":"http://apollo-configservice:8080/eureka/"}}}}' # 最高优先级
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8090/health"]
interval: 30s
timeout: 10s
retries: 5
apollo-portal:
image: apolloconfig/apollo-portal:2.2.0
container_name: apollo-portal
depends_on:
apollo-configservice:
condition: service_healthy
environment:
SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_URL: jdbc:mysql://apollo-db:3306/ApolloPortalDB?useSSL=false&characterEncoding=utf8
SPRING_DATASOURCE_USERNAME: apollo
SPRING_DATASOURCE_PASSWORD: apollo123
APOLLO_PORTAL_ENVS: dev
DEV_META: http://apollo-configservice:8080
PRO_META: http://apollo-configservice:8080
APOLLO_CONFIG_SERVICE: http://apollo-configservice:8080
ports:
- "8070:8070"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8070/health"]
interval: 30s
timeout: 10s
retries: 5
networks:
- nginx_ngu_network #此处是为了加入已经创建好的nginx网络中.用于nginx代理.可选
- default
networks:
nginx_ngu_network:
external: true
volumes:
db_data:
- sql/01-apolloconfigdb.sql
下载文件 https://github.com/apolloconfig/apollo/blob/master/scripts/sql/profiles/mysql-default/apolloconfigdb.sql
- sql/02-apolloconfigdb.sql
下载文件 https://github.com/apolloconfig/apollo/blob/master/scripts/sql/profiles/mysql-default/apolloportaldb.sql
- sql/03-init-user.sql
CREATE USER IF NOT EXISTS 'apollo'@'%' IDENTIFIED BY 'apollo123';
GRANT ALL PRIVILEGES ON ApolloConfigDB.* TO 'apollo'@'%';
GRANT ALL PRIVILEGES ON ApolloPortalDB.* TO 'apollo'@'%';
FLUSH PRIVILEGES
- sql/04-init-eureka-url.sql
非常重要. apollo 2.2.0版本. apollo-adminservice默认的注册中心是http://localhost:8080/eureka/,启动后总是无法找到正常的apollo-configservice.用执行初始化sql的办法修改
UPDATE `ApolloConfigDB`.`ServerConfig`
SET `Value` = 'http://apollo-configservice:8080/eureka/'
WHERE `Key` = 'eureka.service.url';
- 启动
docekr-compose up -d
- 访问 http://localhost:8070
默认登录账户 apollo/admin, 尽快修改密码
docker搭建达梦数据库
Docker 安装
docker run -d -p 30236:5236 \
--restart=always \
--name dm8 \
--privileged=true \
-e PAGE_SIZE=16 \
-e LD_LIBRARY_PATH=/opt/dmdbms/bin \
-e EXTENT_SIZE=32 \
-e BLANK_PAD_MODE=1 \
-e LOG_SIZE=1024 \
-e UNICODE_FLAG=1 \
-e LENGTH_IN_CHAR=1 \
-e INSTANCE_NAME=dm8 \
-e CASE_SENSITIVE=0 \
-e CHARSET=1 \
tommyyusky/dm8_20230808_rev197096_x86_rh6_64
默认账户
SYSDBA/SYSDBA001
达梦官网资料下载
达梦 JDBC 驱动下载
常用命令
修改数据库密码
ALTER USER CURRENT_USER IDENTIFIED BY eizeejee3oh REPLACE SYSDBA001;
# ALTER USER SYSDBA IDENTIFIED BY eizeejee3oh;
环境
root@x:~# cat /etc/issue
Debian GNU/Linux 12 \n \l
Fail2Ban 安装相关
# 安装
apt install fail2ban -y
# 启动进程
systemctl start fail2ban
# 开机启动
systemctl enable fail2ban
查看状态
systemctl status fail2ban.service
发现没有启动成功,控制台如下:
× fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Mon 2024-08-05 03:41:24 UTC; 3 days ago
Duration: 195ms
Docs: man:fail2ban(1)
Main PID: 1981 (code=exited, status=255/EXCEPTION)
CPU: 160ms
Aug 05 03:41:24 lightsail systemd[1]: Started fail2ban.service - Fail2Ban Service.
Aug 05 03:41:24 lightsail fail2ban-server[1981]: 2024-08-05 03:41:24,878 fail2ban.configreader [1981]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
Aug 05 03:41:24 lightsail fail2ban-server[1981]: 2024-08-05 03:41:24,912 fail2ban [1981]: ERROR Failed during configuration: Have not found any log file for sshd jail
Aug 05 03:41:24 lightsail fail2ban-server[1981]: 2024-08-05 03:41:24,919 fail2ban [1981]: ERROR Async configuration of server failed
Aug 05 03:41:24 lightsail systemd[1]: fail2ban.service: Main process exited, code=exited, status=255/EXCEPTION
解决办法: vim /etc/fail2ban/jail.local
vim /etc/fail2ban/jail.local
#内容如下
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
backend = auto
创建日志文件/var/log/auth.log
touch /var/log/auth.log
重启并且查看状态
systemctl restart fail2ban
systemctl status fail2ban
启动成功,控制台输出如下:
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: active (running) since Thu 2024-08-08 09:23:46 UTC; 4s ago
Docs: man:fail2ban(1)
Main PID: 17051 (fail2ban-server)
Tasks: 5 (limit: 2303)
Memory: 14.0M
CPU: 189ms
CGroup: /system.slice/fail2ban.service
└─17051 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
Aug 08 09:23:46 lightsail systemd[1]: Started fail2ban.service - Fail2Ban Service.
Aug 08 09:23:46 lightsail fail2ban-server[17051]: 2024-08-08 09:23:46,319 fail2ban.configreader [17051]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
Aug 08 09:23:46 lightsail fail2ban-server[17051]: Server ready
Linux常用技巧
每次vim的时候总是粘贴不了.需要输入:set mouse-=a回车,才行
解决办法, vim ~/.vimrc 内容如下
set mouse-=a
保存后, souce ~/.vimrc
, 再次编辑文件, 就可以粘贴了
apt安装ping
apt install iputils-ping
给泛解析加一个匹配不到的预留映射
vim *.nguone.eu.org.conf
server {
listen 80;
listen 443 ssl;
server_name *.nguone.eu.org;
ssl_certificate /etc/nginx/ssl/vaultwarden.crt;
ssl_certificate_key /etc/nginx/ssl/vaultwarden.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
# 可以选择进行适当的处理或返回404
# 开启HSTS后能够提升到A+. SSL评估 https://myssl.com/
add_header Strict-Transport-Security "max-age=31536000";
return 404;
}
Nginx Docker 部署
创建网络
docker network create --driver=bridge --subnet=172.16.238.0/24 --gateway=172.16.238.1 my_docker_network
version: '3.8'
services:
nginx:
image: nginx:1.21.1
container_name: nginx
ports:
- 80:80
- 443:443
volumes:
- /app/docker/nginx/nginx:/etc/nginx
- /root/.acme.sh/*.nguone.eu.org_ecc/fullchain.cer:/etc/nginx/ssl/vaultwarden.crt:ro
- /root/.acme.sh/*.nguone.eu.org_ecc/*.nguone.eu.org.key:/etc/nginx/ssl/vaultwarden.key:ro
networks:
- my_docker_network
networks:
my_docker_network:
external: true
Nginx https 配置
当前nginx版本
nginx -v
nginx version: nginx/1.21.1
vaultwarden.conf示例配置如下
server {
listen 80; #侦听80端口,如果强制所有的访问都必须是HTTPs的,这行需要注销掉
listen 443 ssl;
server_name vaultwarden.nguone.eu.org;
ssl_certificate /etc/nginx/ssl/vaultwarden.crt;
ssl_certificate_key /etc/nginx/ssl/vaultwarden.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
client_max_body_size 1024m;
# 开启HSTS后能够提升到A+. SSL评估 https://myssl.com/
add_header Strict-Transport-Security "max-age=31536000";
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://vaultwarden;
}
}
添加一个http登录认证 配置如下:
server {
listen 80; #侦听80端口,如果强制所有的访问都必须是HTTPs的,这行需要注销掉
server_name work;
client_max_body_size 1024m;
# 开启HSTS后能够提升到A+. SSL评估 https://myssl.com/
add_header Strict-Transport-Security "max-age=31536000";
location / {
# 启用 HTTP Basic Authentication
auth_basic "Restricted Access"; # 提示信息
auth_basic_user_file /etc/nginx/.htpasswd; # 指定存放用户名和密码的文件
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://host.docker.internal:3000;
}
}
生成验证密码,保存在/etc/nginx/.htpasswd
密码错误, 会导致nginx提示500错误
htpasswd -c -b /etc/nginx/.htpasswd nguone AiQuaichei2Eer2C
location
location = /abc {
add_header Content-Type text/plain;
add_header X-Server-IP $server_addr always;
return 200 'Success';
}
解释:
location = /abc
:表示精确匹配/abc
,只有请求的 URI 正好是/abc
时才会匹配这个块.其他以/abc/
开头的路径(比如/abc/jlljlk
)将不会匹配这个配置,将会返回404- 如果设置为
/abc
,那么访问/abc
以及/abc
开头的任何路径都会当做/abc
处理 add_header Content-Type text/plain
表示返回的信息是纯文本add_header X-Server-IP $server_addr always
强制在响应头信息中返回nginx的IP
匹配进程的名字并且全部杀掉进程
如杀掉所有kafka进程
pgrep -f kafka | xargs kill -9
解释
- pgrep -f kafka:查找所有匹配 kafka 的进程 PID。
- xargs kill -9:将找到的 PID 传递给 kill -9,强制终止所有这些进程。
这个命令将会找到所有 Kafka 相关的进程,并使用 kill -9 发送信号强制终止它们。
注意事项
- 确保匹配准确:确认 pgrep -f kafka 只会匹配到 Kafka 进程,避免误杀其他重要进程。
- 检查进程:在执行命令前,可以运行 pgrep -f kafka 先查看将会被杀掉的进程。
- 这种方式是一条命令的解决方案,但请务必在执行之前确认对系统的影响。
在不关闭shell的情况下重新启动Bash Shell
exec bash
主要作用
- 应用配置更改
- 当你修改了 ~/.bashrc 或其他 shell 配置文件(如 ~/.bash_profile)后,使用 exec bash 可以使这些更改立即生效,而无需重新登录或重启终端
- 刷新环境
- 有时需要重新加载环境变量或 shell 配置时,exec bash 会刷新当前 shell 的所有设置,使得新的环境变量或配置被加载
重置终端root@后的别名.
# 重置PS1
echo "export PS1='[\u@\h \W]\$ '" >> ~/.bashrc && exec bash
端口扫描
安装
sudo apt-get install nmap # Debian/Ubuntu 系统
sudo yum install nmap # CentOS/Red Hat 系统
扫描单个主机
nmap -sT 192.168.1.1
扫描整个网段
nmap -p 1-65535 192.168.1.0/24
查看硬盘类型
cat /sys/block/sda/queue/rotational
#如果输出是 1,则表示该磁盘是 旋转硬盘(HDD)。
#如果输出是 0,则表示该磁盘是 固态硬盘(SSD)。
查看所有自启服务列表
systemctl list-units --type=service
docker 容器安装telnet
# 查看操作系统信息
cat /etc/os-release
# alpine 安装telnet
apk add busybox-extras
grafana 重置admin密码
grafana-cli admin reset-admin-password <new password>
find跳过无权限目录
find / -path /proc -prune -o -name "*.jar" -print
# 等价于
find / -not -path "/proc/*" -name "*.jar" -print
/proc
目录 是一个虚拟文件系统,包含系统和进程的实时信息。
权限限制:某些 /proc
目录下的文件和进程信息只有 root
用户或进程的所有者才能访问,普通用户会遇到 Permission denied
错误。
解决方法:使用 -prune
排除 /proc
目录,避免遍历该目录时出现权限问题。
debian设置上海时区
sudo timedatectl set-timezone Asia/Shanghai
容器内运行arthas防止挂断
# 在openjdk8环境下运行 出现问题的解决方案
# export PATH=$PATH:/usr/lib/jvm/java-1.8-openjdk/bin
pid=1 ;\
touch /proc/${pid}/cwd/.attach_pid${pid} && \
kill -SIGQUIT ${pid} && \
sleep 2 &&
ls /proc/${pid}/root/tmp/.java_pid${pid}
curl -sL https://arthas.aliyun.com/arthas-lite-boot.jar
java -jar arthas-boot.jar
windows 多块网卡切换
检查路由表
route print
删除 WLAN(无线网卡)的默认路由
route delete 0.0.0.0 mask 0.0.0.0 172.20.10.1 if 14
删除以太网(Realtek PCIe GbE)的默认路由
route delete 0.0.0.0 mask 0.0.0.0 10.99.95.254
恢复默认路由
route add 0.0.0.0 mask 0.0.0.0 10.99.95.254 if 20 -p
网络知识积累
局域网(LAN)常用的私有IP地址网段
通常包括以下三个主要的网段,它们是专门保留给私有网络使用的,不会在互联网中路由
-
10.0.0.0/8 网段: 范围:10.0.0.0 - 10.255.255.255 子网掩码:255.0.0.0 可用地址数:16,777,216(即 2^24)
-
172.16.0.0/12 网段: 范围:172.16.0.0 - 172.31.255.255 子网掩码:255.240.0.0 可用地址数:1,048,576(即 2^20)
-
192.168.0.0/16 网段: 范围:192.168.0.0 - 192.168.255.255 子网掩码:255.255.0.0 可用地址数:65,536(即 2^16)
防火墙-firewalld
重载防火墙
firewall-cmd --reload
查看已开启的端口
firewall-cmd --zone=public --list-ports
防火墙-ufw
journalctl查看ssh连接日志
使用 journalctl 查看认证日志
sudo journalctl -u ssh
持续监控这些日志,可以使用 -f 选项,类似于 tail -f
sudo journalctl -u ssh -f
查看所有与认证相关的日志记录
sudo journalctl | grep ssh
查看登录成功的记录
sudo journalctl | grep ssh | grep 'Accepted'
查看被拒绝的记录
sudo journalctl | grep ssh | grep preauth
日志分析
Oct 16 06:10:01 amd2 sshd[7597]: Connection reset by invalid user admin 154.47.27.80 port 42672 [preauth]
对主机名为amd2的VPS进行ssh连接,invalid user 表示无效用户, 即使用不存在的用户admin进行ssh连接. preauth被拒绝 即 用户输入的用户名还未通过认证程序校验,系统已经发现这是一个无效用户并且连接已被重置
删除所有超过 1 秒的日志
sudo journalctl --vacuum-time=1s
清空日志文件(彻底清除)
sudo rm -rf /var/log/journal/*
Linux创建完整用户
创建用户
- 创建用户
sudo useradd -m -s /bin/bash myuser
- 设置用户密码
sudo passwd myuser
给用户赋予sudo权限
- 添加用户到 sudo 组
sudo usermod -aG wheel myuser
wheel组的用 配置无密码 sudo 权限
注意这是放行所有wheel组的用户, 无密码执行sudo
sudo visudo
找到这一行 %wheel ALL=(ALL) NOPASSWD: ALL
将前面的#去掉.
指定用户,配置无密码执行sudo权限
新增一行
myuser ALL=(ALL) NOPASSWD: /bin/chmod
其他辅助性命令
- 查看所有用户
cat /etc/passwd
- 查看用户组
cat /etc/group
- 查看用户的权限和组
id myuser
会输出类似于以下的信息
uid=1001(myuser) gid=1001(myuser) groups=1001(myuser),10(wheel)
- 查看所有组
getent passwd
- 使用 groups 命令查看当前用户的组
groups
- 使用 getent 命令检查特定组
getent group docker
- 将用户添加到 docker 组
sudo usermod -aG docker myuser
添加后, 执行sudo docker 命令可能提示无权限. 解决办法有两种:
- 完全退出并重新登录
- newgrp docker
删除一个用户
sudo userdel -r xxxx
Linux历史记录
使用 HISTSIZE 和 HISTFILESIZE 将这两个环境变量设置为 0,这样将不会记录任何历史记录
以在你的 shell 配置文件(如 ~/.bashrc 或 ~/.bash_profile)中添加以下行
export HISTSIZE=0
export HISTFILESIZE=0
刷新终端
source ~/.bashrc
临时禁用历史记录
set +o history
临时启用历史记录
set -o history
删除历史文件
rm ~/.bash_history
Linux代理搭建和使用
sudo yum install squid
sudo systemctl start squid
sudo systemctl enable squid
- 查看配置文件
cat /etc/squid/squid.conf
默认配置如下
http_port 8087
cache_mem 128 MB
cache_dir ufs /var/spool/squid 4096 16 256
cache_effective_user squid #设置用户
cache_effective_group squid #设置用户组
access_log /var/log/squid/access.log #设置访问日志文件
cache_log /var/log/squid/cache.log #设置缓存日志文件
cache_store_log /var/log/squid/store.log #设置缓存记录文件
visible_hostname cdn.abc.com #设置squid服务器主机名
cache_mgr root@root.com
acl all src 0.0.0.0/0.0.0.0 #设置访问控制列表,默认开启
http_access allow all
acl client dstdomain -i www.abc.com #找到TAG: acl标签,在其最后添加下面内容
http_access deny client #禁止所有客户机访问www.abc.com域名
acl client131 src 192.168.237.131 #禁止IP地址为192.168.237.131的客户机访问外网
http_access deny client131
acl client129 dst 192.168.237.129 #禁止所有用户访问IP地址为192.168.237.129的网站
http_access deny client129
acl client163 url_regex -i 163.com #禁止所有用户访问域名中包含有163.com的网站
http_access deny client163
acl clientdate src 192.168.237.0/255.255.255.0 #禁止这个网段所有的客户机在周一到周五的18:00-21:00上网
acl worktime time MTWHF 18:00-21:00
http_access deny clientdate worktime
#acl clientxiazai urlpath_regex -i \.mp3$ \.exe$ \.zip$ \.rar$
#http_access deny clientxiazai #禁止客户机下载*.mp3、*.exe、*.zip和*.rar类型的文件
- 在需要代理的机器上执行
export http_proxy=http://instance1_ip:8087
export https_proxy=http://instance1_ip:8087
docker使用代理
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
http-proxy.conf
内容如下:
[Service]
Environment="HTTP_PROXY=http://instance1_ip:8087"
Environment="HTTPS_PROXY=http://instance1_ip:8087"
Environment="NO_PROXY=localhost,127.0.0.1"
重载系统守护进程并重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
自签证书
特别注意openssl
版本
低版本按以下命令生成的自签证书,有可能添加信任后浏览器仍然提示无法信息.当前环境版本
OpenSSL 3.0.15
root@tw:~/ssl# openssl version
OpenSSL 3.0.15 3 Sep 2024 (Library: OpenSSL 3.0.15 3 Sep 2024)
低版本的openssl升级
apt update
apt install openssl -y
生成带有 Subject Alternative Name (SAN) 的自签名证书。现代浏览器(如 Chrome 和 Firefox)要求证书中必须明确设置 SAN,否则即使 CN 匹配也会拒绝连接。 使用
openssl x509 -in work.xyz.me.crt -text -noout
确认证书中是否有 SAN 字段
单域名
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 \
-keyout work.xyz.me.key -out work.xyz.me.crt \
-out work.xyz.me.csr \
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Company/OU=IT Department/CN=work.xyz.me" \
-addext "subjectAltName=DNS:work.xyz.me"
泛解析域名
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 \
-keyout work.xyz.me.key -out work.xyz.me.crt \
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Company/OU=IT Department/CN=*.xyz.me" \
-addext "subjectAltName=DNS:*.xyz.me"
软路由安装
修改静态IP
特别注意,要添加网关,否则无法上网,ping外网不通 特别注意,要添加dns,否则无法解析域名 网关指向主路由IP 192.168.1.1(每个路由器可能不同,可以手机连接WIFI,网络详细中查看)
vi /etc/config/network
,找到 config interface 'lan' 部分,按以下格式调整成自己的信息
config interface 'lan'
option type 'bridge'
option ifname 'eth0'
option proto 'static'
option ipaddr '192.168.1.100'
option netmask '255.255.255.0'
option gateway '192.168.1.1'
option ip6assign '60'
option dns '192.168.1.1'
option dns '8.8.8.8'
修改好之后, 重启网络 service network restart
然后查看路由,没看到网关192.128.1.1,表示网关没有添加
root@OpenWrt:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 br-lan
root@OpenWrt:~# ip route
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.100
临时添加网关测试,如果能上网,通过修改/etc/config/network
配置持久化即可
root@OpenWrt:~# ip route add default via 192.168.1.1
root@OpenWrt:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 br-lan
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 br-lan
root@OpenWrt:~# ip route
default via 192.168.1.1 dev br-lan proto static
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.100
root@OpenWrt:~# ping baidu.com
PING baidu.com (39.156.66.10): 56 data bytes
64 bytes from 39.156.66.10: seq=0 ttl=53 time=29.502 ms
64 bytes from 39.156.66.10: seq=1 ttl=53 time=29.328 ms
64 bytes from 39.156.66.10: seq=2 ttl=53 time=29.238 ms
opkg update
报错解决
rm -rf /etc/opkg/*
/etc/opkg.conf
内容如下:
src/gz openwrt_base https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/base
src/gz openwrt_luci https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/luci
src/gz openwrt_packages https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/packages
src/gz openwrt_routing https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/routing
samba模板配置备份
[global]
netbios name = |NAME|
interfaces = |INTERFACES|
server string = |DESCRIPTION|
unix charset = |CHARSET|
workgroup = |WORKGROUP|
## This global parameter allows the Samba admin to limit what interfaces on a machine will serve SMB requests.
bind interfaces only = yes
## time for inactive connections to-be closed in minutes
deadtime = 15
## disable core dumps
enable core files = no
## set security (auto, user, domain, ads)
security = user
## This parameter controls whether a remote client is allowed or required to use SMB encryption.
## It has different effects depending on whether the connection uses SMB1 or SMB2 and newer:
## If the connection uses SMB1, then this option controls the use of a Samba-specific extension to the SMB protocol introduced in Samba 3.2 that makes use of the Unix extensions.
## If the connection uses SMB2 or newer, then this option controls the use of the SMB-level encryption that is supported in SMB version 3.0 and above and available in Windows 8 and newer.
## (default/auto,desired,required,off)
#smb encrypt = default
## set invalid users
invalid users = root
## map unknow users to guest
map to guest = Bad User
## allow client access to accounts that have null passwords.
null passwords = yes
## The old plaintext passdb backend. Some Samba features will not work if this passdb backend is used. (NOTE: enabled for size reasons)
## (tdbsam,smbpasswd,ldapsam)
passdb backend = smbpasswd
## Set location of smbpasswd ('smbd -b' will show default compiled location)
#smb passwd file = /etc/samba/smbpasswd
## LAN (IPTOS_LOWDELAY TCP_NODELAY) WAN (IPTOS_THROUGHPUT) WiFi (SO_KEEPALIVE) try&error for buffer sizes (SO_RCVBUF=65536 SO_SNDBUF=65536)
socket options = IPTOS_LOWDELAY TCP_NODELAY
## If this integer parameter is set to a non-zero value, Samba will read from files asynchronously when the request size is bigger than this value.
## Note that it happens only for non-chained and non-chaining reads and when not using write cache.
## The only reasonable values for this parameter are 0 (no async I/O) and 1 (always do async I/O).
## (1/0)
#aio read size = 0
#aio write size = 0
## If Samba has been built with asynchronous I/O support, Samba will not wait until write requests are finished before returning the result to the client for files listed in this parameter.
## Instead, Samba will immediately return that the write request has been finished successfully, no matter if the operation will succeed or not.
## This might speed up clients without aio support, but is really dangerous, because data could be lost and files could be damaged.
#aio write behind = /*.tmp/
## lower CPU useage if supported and aio is disabled (aio read size = 0 ; aio write size = 0)
## is this still broken? issue is from 2019 (NOTE: see https://bugzilla.samba.org/show_bug.cgi?id=14095 )
## (no, yes)
#use sendfile = yes
## samba will behave as previous versions of Samba would and will fail the lock request immediately if the lock range cannot be obtained.
#blocking locks = No
## disable loading of all printcap printers by default (iprint, cups, lpstat)
load printers = No
printcap name = /dev/null
## Enabling this parameter will disable Samba's support for the SPOOLSS set of MS-RPC's.
disable spoolss = yes
## This parameters controls how printer status information is interpreted on your system.
## (BSD, AIX, LPRNG, PLP, SYSV, HPUX, QNX, SOFTQ)
printing = bsd
## Disable that nmbd is acting as a WINS server for unknow netbios names
#dns proxy = No
## win/unix user mapping backend
#idmap config * : backend = tdb
## Allows the server name that is advertised through MDNS to be set to the hostname rather than the Samba NETBIOS name.
## This allows an administrator to make Samba registered MDNS records match the case of the hostname rather than being in all capitals.
## (netbios, mdns)
mdns name = mdns
## Clients that only support netbios won't be able to see your samba server when netbios support is disabled.
#disable netbios = Yes
## Setting this value to no will cause nmbd never to become a local master browser.
#local master = no
## (auto, yes) If this is set to yes, on startup, nmbd will force an election, and it will have a slight advantage in winning the election. It is recommended that this parameter is used in conjunction with domain master = yes, so that nmbd can guarantee becoming a domain master.
#preferred master = yes
## (445 139) Specifies which ports the server should listen on for SMB traffic.
## 139 is netbios/nmbd
#smb ports = 445 139
## This is a list of files and directories that are neither visible nor accessible.
## Each entry in the list must be separated by a '/', which allows spaces to be included in the entry. '*' and '?' can be used to specify multiple files or directories as in DOS wildcards.
veto files = /Thumbs.db/.DS_Store/._.DS_Store/.apdisk/
## If a directory that is to be deleted contains nothing but veto files this deletion will fail unless you also set the delete veto files parameter to yes.
delete veto files = yes
################ Filesystem and creation rules ################
## reported filesystem type (NTFS,Samba,FAT)
#fstype = FAT
## Allows a user who has write access to the file (by whatever means, including an ACL permission) to modify the permissions (including ACL) on it.
#dos filemode = Yes
## file/dir creating rules
#create mask = 0666
#directory mask = 0777
#force group = root
#force user = root
#inherit owner = windows and unix
################################################################
kubernetes
Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、扩缩和管理
搭建一个kubernetes集群
安装工具kubectl
安装
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# 查看版本
kubectl version --client
安装 bash-completion
apt-get install bash-completion -y && source /usr/share/bash-completion/bash_completion
全局启用启动 kubectl 自动补全功能
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
sudo chmod a+r /etc/bash_completion.d/kubectl
source ~/.bashrc
安装集群:生产环境
安装netcat-openbsd
apt update && apt install netcat-openbsd -y
# 用于直观地看端口是否启用
root@tw:~# nc 127.0.0.1 443 -v
Connection to 127.0.0.1 443 port [tcp/https] succeeded!
安装 kubeadm
sudo apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
ip route show | grep "default via"
default via 10.140.0.1 dev ens4 proto dhcp src 10.140.0.7 metric 100
sudo kubeadm init --pod-network-cidr=192.168.0.0/16
cat /etc/kubernetes/kubelet.conf | grep server
重置k8s集群
sudo kubeadm reset
rm -rf /etc/cni/net.d
rm -rf $HOME/.kube/config
rm -rf /etc/kubernetes
docker run -d --name=rancher --privileged --network nginx_ngu_network --memory="2g" rancher/rancher:latest
dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
docker logs --tail 10 nginx
列出所有命名空间下的所有的服务
可以看到端口
kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cattle-fleet-local-system fleet-agent ClusterIP None <none> <none> 30m
cattle-provisioning-capi-system capi-webhook-service ClusterIP 10.101.178.158 <none> 443/TCP 29m
cert-manager cert-manager ClusterIP 10.103.216.116 <none> 9402/TCP 35m
cert-manager cert-manager-webhook ClusterIP 10.102.68.102 <none> 443/TCP 35m
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h46m
default nginx-service NodePort 10.104.63.107 <none> 80:30001/TCP 79m
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 3h46m
删除服务
kubectl delete svc nginx-service -n default
kubectl delete deployment nginx -n default
root@tw:/app/docker/nginx/nginx/conf.d# kubectl get deployments -n default
No resources found in default namespace.
删除 Namespace
kubectl get namespace cattle-system -o json
kubectl patch namespace cattle-system -p '{"metadata":{"finalizers":null}}'
kubectl get namespaces
kubectl delete all --all -n cattle-system
kubectl get all -n cattle-system
kubectl delete namespace cattle-system --force --grace-period=0
kubectl get namespace cattle-system -o json > cattle-system.json
kubectl delete validatingwebhookconfiguration rancher.cattle.io
kubectl delete validatingwebhookconfiguration cert-manager-webhook
方法一:将服务类型修改为 LoadBalancer
如果您使用的是云环境(如 GCP、AWS、Azure),可以通过将服务类型改为 LoadBalancer
来使 Rancher 获得一个外部 IP 地址。
执行以下命令来修改 Rancher 服务类型:
bash
复制代码
kubectl -n cattle-system patch svc rancher -p '{"spec":{"type":"LoadBalancer"}}'
此时,您可以通过 EXTERNAL-IP
来访问 Rancher。例如:
bash
复制代码
kubectl -n cattle-system get svc rancher
您将看到 EXTERNAL-IP
字段已分配一个外部 IP 地址,您可以使用该 IP 地址在浏览器中访问 Rancher UI。
方法二:将服务类型修改为 NodePort
如果您没有负载均衡器或不希望使用它,您可以将服务类型修改为 NodePort
,然后使用集群节点的外部 IP 和端口访问 Rancher。
执行以下命令来修改 Rancher 服务类型:
bash
复制代码
kubectl -n cattle-system patch svc rancher -p '{"spec":{"type":"NodePort"}}'
然后,使用以下命令查看端口映射:
bash
复制代码
kubectl -n cattle-system get svc rancher
您将看到类似如下的输出:
scss复制代码NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rancher NodePort 10.104.162.113 <none> 80:30001/TCP 1m
如果 Rancher 部署了多个 Pod,可以通过以下命令查看所有 Pod 的日志:
bash
复制代码
kubectl logs -n cattle-system -l app=rancher --follow
helm安装的rancher重置admin密码
cp /root/.kube/config .
KUBECONFIG=./config
kubectl --kubeconfig $KUBECONFIG -n cattle-system exec $(kubectl --kubeconfig $KUBECONFIG -n cattle-system get pods -l app=rancher --no-headers | head -1 | awk '{ print $1 }') -c rancher -- reset-password
kubectl get svc --namespace default
等价于 kubectl get svc --namespace default
kubectl get svc --all-namespaces
表示列出所有空间下的服务
# dokcer方式搭建
docker run -d --privileged -p 60080:80 -p 60443:443 -v ./rancher_data:/var/lib/rancher --restart=always --name rancher-2.7.1 rancher/rancher:v2.7.1
helm方式搭建
helm install rancher rancher-latest/rancher \
--namespace cattle-system \
--set hostname=k8s.nguone.eu.org --set bootstrapPassword=Ni4phughiotieCoo
kubectl apply -f nginx-pvc.yaml
kubectl get pvc
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
kubectl delete pvc nginx-pvc
kubectl apply -f nginx-test-pod.yaml
让其他节点加入到
个体词
谓词
复合命题的谓词符号化
总结
量词
符号函数
自由变元和约束变元
举例
两个规则
闭式
自反性与反自反性
对称性与反对称性
传递性
关系性质的保守性
闭包求解
利用关系运算求闭包
哈斯图
最大元和最小元
极大元和极小元
总结
上下(确)界关系总结
全序关系的哈斯图
良序关系
函数
函数的数量
关系和函数的差别
函数类型
函数的复合
保守性
结点的度数
通路与回路举例
记号的简化
树
无向树
24下软考总结
时间分配问题,多做题,计时做题. 严格把控时间 上午题2小时, 尽量控制在1小时内完成,30分钟检查,剩下的30分钟留给下午 下午题也要严格计算时间
因为考试题型的位置性.一定要把已知的题目熟悉透彻
上午题
面广,只能多刷:全部, 可以经常看电子书,不会做的题目极有可能会成为考点(除了老题型已经改革了新题型的除外.但是基本上只是换个花样考).归纳总结.反复温故
- python 基础必刷.最好做一些python的卷子.把基础过一下
- 设计模式
- 操作系统
下午题
提前复习,整套题目做,计时最好提前30分钟完成.
需要把上午题和下午题每一种题型都做成一个自己的题库. 每种类型一题,反复学习
做题心得总结
结构化开发
给出实体名称
第一道大题找实体E1到En 实体的特点是: 主语, 名词, 找实体就是找名词
结合数据流和加工来看,描述一般是, 某一个加工接收XXX的数据,举例
解析: 数据接收这个加工接收到了充电数据, 接收, 是指数据流流入, 既然接收的是计量装置的数据,那么E1就是计量装置
向XXX发出/发送什么, XXX接收了什么, 结合子图,得到XXX就是对应的实体,举例
XXX根据什么做了什么,这里的XXX就是实体,如下
给出数据存储的名称
关键词, 信息 / 文件 / 表 , 发现这类关键词的时候, 表示当前的存储名称以这些关键字结尾
没有关键字出现的时候, 可以不写关键字后缀,也可以加后缀 表
数据库设计
特别要仔细, 不要丢分.......争取满分.不要丢实体中的联系
不需要补全题目没要求的子实体
两个实体有联系, 要把单个关系的主键加入到另外一个实体中
特别注意这一点. 会导致扣分. 补全属性错了. 会导致第3问也一起错. 错一道就是错两道
最后一问,存在某种情况, 问你有什么问题, 需要怎么解决?
回答模板:
题目抄一遍,(一般都是重复记录某个关系模式的属性),会导致冗余,插入,删除,更新等异常,需要进行拆解,拆解后的关系模式是:
原关系模式抄一遍,去掉一对多的关系,
新的关系模式写一遍. 主要主键和外键不要丢
在线验证工具 http://easycode.top/
案例1: 二叉树前序ABDHIEJCFKG,中序HDIBEJAFKCG,得到的后序是什么?
案例2: 二叉树前序是abdgcefh,中序
编译
IO系统
内聚类型
RUP
图
浮点数
编译
二分查找
IO系统
注意:这里求的是最大段, 每段最大页,以及页的大小
并发进程与互斥信号
内聚类型
RUP
图
设计模式
抽象工厂模式(Abstract Factory):提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
构建器模式(Builder):将一个复杂类的表示与其构造相分离,使得相同的构建过程能够得出不同的表示。
工厂方法模式(Factory Method):定义一个创建对象的接口,但由子类决定需要实例化哪一个类。工厂方法使得子类实例化的过程推迟。
原型模式(Prototype):用原型实例指定创建对象的类型,并且通过拷贝这个原型来创建新的对象。
单例模式(Singleton):保证一个类只有一个实例,并提供一个访问它的全局访问点。
适配器模式(Adapter):将一个类的接口转换成用户希望得到的另一种接口。它使原本不相容的接口得以协同工作。
桥接模式(Bridge):将类的抽象部分和它的实现部分分离开来,使它们可以独立地变化。
组合模式(Composite):将对象组合成树型结构以表示“整体-部分”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
装饰模式(Decorator):动态地给一个对象添加一些额外的职责。它提供了用子类扩展功能的一个灵活的替代,比派生一个子类更加灵活。
外观模式(Facade):定义一个高层接口,为子系统中的一组接口提供一个一致的外观,从而简化了该子系统的使用。
享元模式(Flyweight):提供支持大量细粒度对象共享的有效方法。
代理模式(Proxy):为其他对象提供一种代理以控制这个对象的访问。
职责链模式(Chain of Responsibility):通过给多个对象处理请求的机会,减少请求的发送者与接收者之间的耦合。将接收对象链接起来,在链中传递请求,直到有一个对象处理这个请求。
命令模式(Command):将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作。
解释器模式(Interpreter):给定一种语言,定义它的文法表示,并定义一个解释器,该解释器用来根据文法表示来解释语言中的句子。
迭代器模式(Iterator):提供一种方法来顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。
中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。它使各对象不需要显式地相互调用,从而达到低耦合,还可以独立地改变对象间的交互。
备忘录模式(Memento)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,从而可以在以后将该对象恢复到原先保存的状态。
观察者模式(Observer):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
状态模式(State):允许一个对象在其内部状态改变时改变它的行为。
策略模式(Strategy):定义一系列算法,把它们一个个封装起来,并且使它们之间可互相替换,从而让算法可以独立于使用它的用户而变化。
模板方法模式(Template Method):定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤。
访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,使得在不改变各元素的类的前提下定义作用于这些元素的新操作
定义一系列的算法,把他们封装起来, 并且使得他们可以相互替换
原码 反码 补码
正数的原 反 补 一致
负数的反码: 符号位不变, 其余各位按位取反
负数的补码: 等于 反码+1
最高位是符号位, 0表示正数, 1表示负数
对补码再求一次补码,就得到了原码
+0 和 -0 的补码一样,如下
[+0]原码 = 0000 0000 = [+0]补码
[-0]原码 = 1000 0000, [-0]反码 = 1111 1111 ,[-0] = 补码 = [-0]反码 + 1 = 0000 0000
由于只使用 8 位二进制数表示,结果中的第 9 位会被丢弃,所以最终的补码是 0000000000000000
所以 无论是 +0 还是 -0,它们的补码表示都是相同的,即 0000000000000000
计算 -3-4
-3 -4 = -3 + (-4) = ((-3 + (-4))补码)补码
0 | 000 |
---|---|
1 | 001 |
2 | 010 |
3 | 011 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
所以得到 -3 -4 = (1000 0011补码 + 1000 0100补码)补码
1000 0011的补码 = 1111 1100 + 1 = 1111 1101
1000 0100的补码=1111 1011 + 1 = 1111 1100
所以 -3 -4 = (1111 1101 + 1111 1100)的补码 = (1111 1001)的补码 = 1000 0110 + 1 = 1000 0111 = -7
TCP UDP 以及端口号
UML
UML中有4种关系
- 依赖是两个事物之间的语义关系,其中一个事物发生变化会影响另一个事物的语义
- 关联描述一组对象之间连接的结构关系
- 泛化是一般化和特殊化的关系,描述特殊元素的对象可替换一般元素的对象
- 实现是类之间的语义关系,其中的一个类指定了由另一个类保证执行的契约
UML建模
- 用例图:主要用在面向对象需求分析阶段。系统在它的周边环境的语境中所提供的外部可见服务
- 对象图: 展示某一时刻一组对象以及它们之间的关系
- 活动图: 系统内从一个活动到另一个活动的流程
- 序列图: 以时间顺序组织的对象之间的交互活动
- 部署图:部署图描述系统中硬件和软件的物理架构,它描述构成系统架构的软件结构、处理器和设备
软件开发模型
- 螺旋模型。综合了瀑布模型和原型模型中的演化模型的优点,还增加了风险分析,特别适用于庞大而复杂的、高风险的管理信息系统的开发
- 瀑布模型是以文档为驱动的模型,适合需求明确的软件项目的模型,优点是容易理解,管理成本低,但缺乏灵活性,难以适应需求的变化,如果软件在后期出现需求变化,整个系统需要从头开始
编译或解释
解释型: 不产生目标程序,每使用一次就要解释一次,运行效率低,可移植性好. 不会生成目标代码 编译型: 产生目标程序,运行效率高,可移植性差. 中间代码生成和代码优化不是必须的. 在编译方式下,必须进行词法、语法和语义分析,再产生源程序的目标代码
白盒测试原则
(1)程序模块中的所有独立路径至少执行一次
(2)在所有的逻辑判断中,取“真”和取“假”的两种情况至少都能执行一次
(3)每个循环都应在边界条件和一般条件下各执行一次
(4)测试程序内部数据结构的有效性等
非平凡子串
主动攻击
-
拒绝服务攻击
-
分布式拒绝服务(DDos)
-
信息篡改
-
资源使用
-
欺骗
-
伪装
-
重放
-
会话拦截
-
修改数据命令
著作权
保护期限为作者终身及死后50年的,包括:发表权、使用权和获得报酬权
可移植性
适应性、易安装性、共存性和易替换性四个特性
媒体
表示媒体指的是为了传输感觉媒体而人为研究出来的媒体,借助于此种媒体,能有效地存储感觉媒体或将感觉媒体从一个地方传送到另一个地方。如语言编码、电报码、条形码等。
表现媒体指的是用于通信中使电信号和感觉媒体之间产生转换用的媒体。如输入、输出设备,包括键盘、鼠标器、显示器、打印机等。需要供电才可以使用的媒体/设备
复杂度
存储设备按访问速度
通用寄存器 > Cache > 内存 > 硬盘
安全
机房安全属于物理安全,入侵检测属于网络安全,漏洞补丁管理属于系统安全,而数据库安全则是应用安全
螺旋模型
适应于:
- 庞大而复杂
- 高风险
寻址速度
立即寻址最快,寄存器寻址次之,直接寻址最慢
VIEW是超长指令字的简称
视频格式
MOV
FTP
20和21,其中20为数据口(上传文件),21为控制口
二叉树
最高有最多有2^h-1个结点
数据库设计
淘汰表
计算机病毒是特殊小程序
组合结构图用于画出结构化类的内部内容。
顺序图由一组对象或参与者以及它们之间可能发送的消息构成。强调消息的时间次序的交互图。
通信图强调收发消息的对象或参与者的结构组织。强调的是对象之间的组织结构(关系)
函数依赖的Armstrong公理系统
-
自反律:若属性集Y 包含于属性集X,属性集X 包含于U,则X→Y 在R 上成立。(此处X→Y是平凡函数依赖)
-
增广律:若X→Y 在R 上成立,且属性集Z 包含于属性集U,则XZ→YZ 在R 上成立。
-
传递律:若X→Y 和 Y→Z在R 上成立,则X →Z 在R 上成立。
-
其他的所有函数依赖的推理规则可以使用这三条规则推导出。
-
合并规则:若X→Y,X→Z同时在R上成立,则X→YZ在R上也成立。
-
分解规则:若X→W在R上成立,且属性集Z包含于W,则X→Z在R上也成立。
-
伪传递规则:若X→Y在R上成立,且WY→Z,则XW→Z。
软件维护
计算机网络协议5层体系结构
-
传输层: 四层交换机 、四层的路由器
-
网络层:三层交换机、路由器
-
数据链路层:网桥、以太网交换机、网卡
-
物理层:中继器、集线器、双绞线
CPU中的寄存器
- 指令寄存器IR 存储即将执行的指令
- 状态条件寄存器PSW 存储状态标志与控制标志
- 程序计数器PC 存储下一条要执行的指令的地址
- 主存地址寄存器MAR 保存当前CPU访问内存单元的地址
UML类图建模
-
聚合关系:整体与部分生命周期不同,属于关联关系。 如计算机类与鼠标类
-
依赖关系:一个事物发生变化影响另一个事物。
-
泛化关系:表示两类事物之间的特殊/一般关系。
-
实现关系:接口和类的关系。
存储类别
-
CPU对应的存储类别:寄存器
-
Cache对应的存储类别:缓存
-
主存对应的存储类别:DRAM
-
辅存对应的存储类别:硬盘、光盘等
面向对象软件测试
-
算法层:测试类中定义的每个方法,基本相当于传统软件测试的单元测试。
-
类层:测试封装在同一个类中的所有方法与属性之间的相互作用。可以认为是面向对象测试中特有的模块测试。
-
模板层:测试一组协调工作的类之间的相互作用。大体上相当于传统软件测试中的集成测试。
-
系统层:把各个子系统组装成完整的面向对象软件系统。
面向对象系统设计原则
-
稳定抽象原则:此原则强调的是包的抽象程度与其稳定程度一致。
-
稳定依赖原则:此原则要求包之间的依赖关系都应该是稳定方向依赖的,即包要依赖的包要比自己更具有稳定性。
-
依赖倒置原则:此原则强调的是程序应该依赖于抽象接口,而不是具体的实现,从而降低客户与实现模块间的耦合。
-
无环依赖:这个原则明确指出,在组件的依赖关系在图中不允许存在环。从给出的设计描述中,包A、包B、包C之间的依赖关系形成了一个环,这直接违反了无环依赖原则。
关系表
-
投影:在关系表中选出若干属性列组成新的关系表
-
笛卡儿积:两表之间的乘积,组成之后的新表,属性列为两表的属性列,元组为两表的乘积
-
选择:选择满足某个条件的元组
-
差:指的是取一个表中存在而另一个表中不存在的记录
数据流图
由数据流、外部实体、数据加工和数据存储组成。
-
数据流(Data Flow):数据流是数据在系统中从一个地方流向另一个地方的路径。它表示数据从数据源流向数据接收者(如处理过程、数据存储或另一个数据源)的方向。数据流通常用带箭头的线段表示。
-
外部实体(External Entity):数据源是数据的起点,即数据的来源。它可以是用户、外部系统、设备或其他外部因素。在数据流图中,数据源通常用矩形表示,并标有相应的名称。
-
数据加工(Data Process):数据加工是数据流图中对数据进行操作或变换的部分。它表示数据在系统内部如何被处理或转换。在数据流图中,处理过程用圆形或圆角矩形表示,并标有相应的名称和操作描述。
-
数据存储(Data Storage):数据存储是系统中用于存储数据的部分。它可以是数据库、文件、内存中的数据等。在数据流图中,数据存储用两根平行线表示,并标有相应的名称。
算法
-
SHA-1:这是一个哈希函数,用于生成数据的哈希值(或摘要)。
-
AES:这是一个对称加密算法,它本身不使用哈希算法。AES 是一种块密码,用于加密和解密数据。
-
DES:同样,这也是一个对称加密算法,不使用哈希算法。DES 是较早的加密标准,现在已经不再安全。
-
RSA:这是一个公钥加密算法,它主要用于加密、解密和数字签名。
甘特图
- 一种进度管理工具
- 能清晰地描述每个任务从何时开始,到何时结束
- 任务的进展情况以及各个任务之间的并行性
- 不能清晰地反映出各任务之间的依赖关系
- 难以确定整个项目的关键所在
- 不能反映计划中有潜力的部分
测试覆盖
-
语句覆盖(Statement Coverage):也称为行覆盖,它关注的是程序中每一行代码是否至少被执行一次。这是最基本的测试覆盖标准,但往往只能发现简单的错误。
-
判定覆盖(Decision Coverage):也称为分支覆盖,它要求程序中的每一个判定(例如if-else语句)的每一种可能结果(真或假)都至少发生一次。这比语句覆盖更全面,但可能仍会遗漏一些错误。
-
路径覆盖(Path Coverage):它要求测试覆盖程序中所有可能的执行路径。这通常意味着测试需要遍历程序中所有可能的条件组合。路径覆盖是这些选项中最全面的测试覆盖方法,因为它考虑了程序中所有可能的执行路径。
-
条件覆盖(Condition Coverage):它要求程序中的每一个条件(例如if语句中的条件)的每一种可能结果(真或假)都至少发生一次。虽然这比判定覆盖更全面,但它仍然可能遗漏一些错误,因为它不保证所有条件的组合都被测试到。
综上所述,路径覆盖是这些测试方法中覆盖程度最高的
知识专利
-
双重性:双重性是指知识产权中的独占性与公用性、排他性与共享性、私人性与社会性等多种形式的双重性特征。
-
独占性:是权利人所专有的权利。任何人未经权利人许可,都不得行使其权利(法律另有规定的除外)。
-
地域性:地域性是指知识专利的保护范围通常限于特定的国家或地区。
-
实践性:实践性在这里可以理解为知识技术或专利能够被实际运用或操作的特性。由于知识技术可以同时被多个人使用,这正好体现了其在实际应用中的广泛性和可操作性,即实践性。
风险
-
商业风险:商业风险通常与公司的战略决策、市场环境、竞争对手等有关。如果一个软件不符合公司的战略决策,那么它很可能会对公司的商业目标产生负面影响,导致商业风险。
-
项目风险:项目风险指在软件开发过程中遇到的预算和进度等方面的问题以及这些问题对软件项目的影响。这些风险可能会影响项目计划的实现,如果项目风险变成现实,就有可能影响项目的进度,增加项目的成本,甚至使软件项目不能实现。
-
开发风险:开发风险主要涉及软件开发过程中的技术问题、资源不足、时间延误等。
-
人员风险:人员风险通常与员工的技能、态度、离职率等有关。
模块结构图包括模块、模块之间的调用关系、模块之间的通信和辅助控制符号
数据库的基本表对应概念视图,存储文件对应内部视图,视图对应用户视图。
CPU保护程序计数器的主要目的是为了使CPU在执行完中断服务程序时能返回到被中断程序的断点处
在双核处理器中,双核是指在 一 个 CPU 中集成两个运算核心以提高运算能力
系统总线在CPU之外
CPU执行MOVRI,RO指令,CPU首先要完成的操作是从内存中读取该指令的指令操作码。取该指令的指令操作码,首先要做的就是将程序计数器的内容送到地址寄存器,即PC→AR
两个浮点数相加运算首先进行对阶,阶码小的向阶码大的对齐
在补码中0具有唯一编码。将补码的符号位取反可以得到移码。对于数字0来说移码与补码都是唯一的。
在计算机中,最适合进行数字加减运算的数字编码是补码,最适合表示浮点数阶码的数字编码是移码
定点小数表示中,只有补码能表示 -1
根据补码表示规则,当数符与尾数小数点后第一位相异时为规格化数, 阶码与数符和规格化与否无关。
CRC码的格式为n个数据位之后跟k个校验位
流水线的操作周期应设计为时间最长的步骤的时间
CISC和RISC(精简指令集计算机)
RISC特点
- 指令系统中只包含使用频率较高但不复杂的指令
- 指令长度固定,指令格式少,寻址方式少(绝不出现存储器间接寻址方式)
- 只有存取数指令访问主存,其他指令都在寄存器之间运算
- 大部分指令在一个机器周期内完成,采用流水技术
- 采用很多的通用寄存器(以减少访存次数)
- 硬联逻辑控制(以尽快完成指令译码),不用微程序控制技术
- 采用优化的编译,以有效地支持高级语言
CISC特点:
- 指令可以对主存单元中的数据直接进行处理。
DMA可以使数据在主存(内存)和外设(I/O设备)之间直接传送,在传送的过程中不用CPU的干预,由DMA的控制器控制总线完成数据的传送。
一个DMA传送只需要执行一个总线周期
中断方式与DMA方式都可实现外设与CPU之间的并行工作
SRAM和DRAM
SRAM
- 静止存取功能的内存
- 不需要刷新电路即能保存它内部存储的数据
- SRAM具有较高的性能
- 集成度较低,体积大,功耗大
DRAM
- 动态随机存取存储器,最为常见的系统内存
- 只能将数据保持很短的时间
- DRAM使用电容存储,所以必须隔一段时间刷新一次,如果存储单元没有被刷新,存储的信息就会丢失
闪存(Flash Memory)
- 闪存掉电后信息不丢失
- 闪存以块为单位进行删除操作
- 闪存采用随机访问方式,所以速度很快
- 在嵌入式系统中可以用Flash来代替ROM存储器
词法分析遵循的是构词规则,语法分析遵循的是语法规则,中间代码生成遵循的是语义规则,并且语义规则可以定义一个程序的意义
以编译方式翻译C/C++源程序的过程中,静态检查在(语义分析)阶段处理
Java是即时编译程序
- 传值调用是将实参的值传给被调用函数的形参,因此实参可以是常量、变量、表达式或函数调用
- 传地址调用(或引用调用)的实质是将实参的地址传给被调用函数的形参,因此实参必须具有地址
OSI参考模型表示层的功能有数据解密与加密、压缩、格式转换等
数据链路层在物理线路上提供可靠的数据传输
VLANtag在OSI参考模型的数据链路层实现。
以太网交换机属于网络模型中(数据链路层),管理的是(帧)
FTP协议占用两个标准的端口号:20和21,其中20为数据口(上传文件),21为控制口。
POP3 协议默认端口: 110.默认传输协议: TCP
无线wlan主要采用的是IEEE802.11标准。
SMTP和POP3都是基于TCP的协议,提供可靠的邮件通信
-
常用协议端口号情况如下:
-
POP3:TCP的110端口,邮件收取。
-
SMTP:TCP的25端口,邮件发送。
-
FTP:TCP的20数据端口/21控制端口,文件传输协议。
-
HTTP:TCP的80端口,超文本传输协议,网页传输。
-
DHCP:UDP的67端口,IP地址自动分配。
-
SNMP:UDP的161端口,简单网络管理协议。
-
DNS:UDP的53端口,域名解析协议,记录域名与IP的映射关系。
网站被入侵以后数据库信息泄露了。
-
撞库:使用大量的一个网站的账号密码,去另一个网站尝试登陆。也就是基于用户代码重复度比较高的问题,使用被脱库的密码尝试其它网站。
-
洗库:黑客入侵网站在取得大量的用户数据之后,通过一系列的技术手段和黑色产业链将有价值的用户数据变现。
-
社工库:黑客将获取的各种数据库关联起来,对用户进行全方位画像。
转载于 https://blog.csdn.net/weixin_55085468/article/details/122736447
1、假设顺序表第 1 个元素的内存地址是 100,每个元素占用 2 字节内存空间,则第 5 个元素的内存地址是 ——。 答案:108
分析: 定义顺序表:将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。一维数组在内存中占用的存储空间就是一组连续的存储区域,一般程序设计语言中,使用数组非常合适
计算地址:Loc =Loc0 + (n-m)*b
Loc 为内存地址
Loc0为初始地址
n-m为两个元素相距几个元素
b为字节数
如图,每个元素占2个字节内存空间,即可得到:100+2*(5-1)=108
2、已知二维数组 A 按行优先方式存储,每个元素占用 1 个存储单元。若元素 A[0][0] 的存储地址是 100,A[3][3] 的存储地址是 220,则元素 A[5][5] 的存储地址是:——。 答案:300
首先给出公式:Loc = Loc0 +k* [m *(i) + (j)]
解析:对于数组 A [i][j]
,
Loc 为储存地址
Loc0为初始地址
k为存储单元
i,j为所求元素数组行列,m为二维数组 A[m][n]
的行
注意哦:此时,按行优先方式存储
所以,我们首先要求出该二维数组的列为多少?
根据公式,220 = 100 + 1*(3*m+3) m = 39
则 则元素 A[5][5]
的存储地址是:
100 + 1*(5*39 + 5)= 300
简单选择排序
从左到右, 在数组中找到最小值,和第一位交换位置,然后在剩下的数中再找出最小的值放在剩下数的第一位,重复以上操作,直到只剩下最后一个数,结束. 得到了从小到大的有序数组
如原数组(49,38,65,97,76,13,27,49)
-
第一趟: 找出数组中的最小值为13, 13和第一个数49交换位置,得到第一趟的结果如下
(13,38,65,97,76,49,27,49)
-
对剩下的数(38,65,97,76,49,27,49)进行排序,得到第二趟的结果如下
(13,27,65,97,76,49,38,49)
总结: 经过n趟,则得到了n个有序的数, 假设数组有m个数, 需要经过m-1次趟
24年5月真题:
解析: 题目要求对序列进行简单选择排序,非降序即升序, 两趟后的序列, 由结论快速得知, 两趟后能得到两个最小的有序数, 肉眼看去找到最小的两个数是13和27,秒选A
树
普通树
树是n(n>=0)个结点的有限集合
当n=0时, 集合为空,称为空树
二叉树
二叉树和普通树的区别在于, 二叉树中结点的子树分为左子树和右子树,如下
满二叉树与完全二叉树
如果一个树的层数为K,结点总数为2^k-1个,则它就是满二叉树
在一个深度为h的二叉树中,除第h层(最后一层)外,其他各层都是满的, 并且第h层所有结点都必须从左到右依次放置,不能留空,则它就是完全二叉树
二叉树的性质
- 在二叉树的第i层上最多有**2(i-1) **个结点(i>=1)
- 深度为k的二叉树最多有2k-1个结点
- 任何一个二叉树,如果叶子结点数为n0, 度为2的结点数为n2, 则 n0 = n2+1
- 具有n个结点的完全二叉树的深度为[logn2n] + 1
二叉树的存储
- 二叉树的顺序存储.在采用顺序存储时,完全二叉树与一般二叉树相比节省了空间,这是因为一般二叉树需要添加一些"虚节点"而造成了空间的浪费
图
图的存储
有向图和无向图的邻接矩阵与邻接表
上午题-病毒
蠕虫病毒
- 欢乐时光 (感染服务器/台式机)
- 熊猫烧香(感染服务器/台式机)
- 震网: 利用系统漏洞攻击工业控制系统,危害极大
系统病毒
- CIH(感染服务器/台式机)
智能手机病毒
- X卧底
处理器
双核处理器
一个处理器 两个运算核心,从而提高计算能力
统一过程模型
起始阶段:起始阶段专注于项目的初创活动。
精化阶段:精化阶段在理解了最初的领域范围之后进行需求分析和架构演进。
构建阶段:构建阶段关注系统的构建,产生实现模型。
移交阶段:移交阶段关注于软件提交方面的工作,产生软件增量
安全协议
-
HTTPS
-
SFTP
-
IPsec
汇编语言
- 汇编语言不能直接被计算机执行,需要编译成机器语言才能被计算机执行
多态
在面向对象技术中,不同的对象收到同一消息可以产生完全不同的结果,这一现象叫做多态
- 方法重载是一种静态多态,也称为编译时多态
- 覆盖属于运行时多态
参数多态
应用最广泛的多态,被称为最纯的多态
包含多态
包含多态在许多语言中都存在,最常见的例子就是子类型化,即一个类型是另一个类型的子类型.
过载多态
过载多态是同一个名字在上下午中所代表的含义不同
强制多态
白盒测试
(1)程序模块中的所有独立路径至少执行一次
(2)在所有的逻辑判断中,取“真”和取“假”的两种情况至少都能执行一次
(3)每个循环都应在边界条件和一般条件下各执行一次
(4)测试程序内部数据结构的有效性等
对面向对象软件的测试
(1)算法层:测试类中定义的每个方法。
(2)类层:测试封装在同一个类中的所有方法与属性之间的相互作用。
(3)模板层:测试一组协同工作的类之间的相互作用。
(4)系统层:把各个子系统组装成完整的面向对象软件系统,在组装过程中同时进行测试
常见的端口
POP3服务默认的TCP端口号 110
可寻址的单元数
解析: 128KB= 128 * 2^10 B , 32位 = 32bit/8bit=4B, 128 * 2^10 B/(4B)=2^15个地址
题目要求从0000H开始, 也就是说包括0000H在内,总共数2^15个地址, 即0000H+ (2^15), 由于包括了0000H,所以最终结果= 0000H+ (2^15) -1.
2^15 = 1000 0000 0000 0000 = 8 0 0 0H, 所以结果是 0000H+ 8 0 0 0H -1 = 7FFFH. 16进制每个位置的范围是0-F
解析:
- 存储周期是250ns,表示执行一次需要250ns, 1秒可以执行1s/250ns次 = 1*4/(250*4*10-9) = 109*4/1000 = 4*109/103=4*106
- 16位/8bit=2B
数据传输率 = 2B * 4 * 106 = 8 * 106
上午题 #2
上下文无关文法
上午题 # 数据结构
1 计算机系统
CPU的组成(运算器与控制器)
流程图
+-------------------+
| 开始指令周期 |
+-------------------+
↓
+-------------------+
| 1. 取指阶段 (Fetch) |
| - PC → 内存地址 |
| - 内存读取指令 → IR |
| - PC自动+1或跳转 |
+-------------------+
↓
+-------------------+
| 2. 译码阶段 (Decode)|
| - 解析IR中的指令 |
| - 生成控制信号 |
+-------------------+
↓
+-------------------+
| 3. 执行阶段 (Execute)|
| - ALU执行运算 |
| - 计算内存地址/跳转 |
+-------------------+
↓
+-------------------+
| 是否需要访问内存? | → [是] → 进入访存阶段
| (判断) | → [否] → 跳过访存阶段
+-------------------+
↓
+-------------------+
| 4. 访存阶段 (Memory) | ← 可选分支
| - 读内存:地址→AR |
| - 写内存:数据→DR |
+-------------------+
↓
+-------------------+
| 5. 写回阶段 (Write Back)| ← 可选分支
| - 结果写入寄存器 |
+-------------------+
↓
+-------------------+
| 6. 中断检查 | → [有中断] → 处理中断
| - 检查外部中断信号 | → [无中断] → 继续
+-------------------+
↓
+-------------------+
| 返回取指阶段 |
| (进入下一条指令周期) |
+-------------------+
详细步骤说明
1. 取指阶段 (Fetch)
- 作用:从内存中读取指令。
- 关键操作:
- 程序计数器(PC) 提供当前指令的地址。
- 内存根据地址读取指令,并存入 指令寄存器(IR)。
- PC 更新:自动指向下一条指令地址(PC+1)或根据跳转指令修改。
2. 译码阶段 (Decode)
- 作用:解析指令内容,生成控制信号。
- 关键操作:
- 指令译码器 拆分指令的 操作码(做什么) 和 操作数(对谁做)。
- 控制信号发生器 根据操作码生成控制信号(如选择 ALU 操作类型)。
3. 执行阶段 (Execute)
- 作用:执行指令的核心操作。
- 关键操作:
- 算术逻辑单元(ALU) 执行运算(如加法、逻辑运算)。
- 如果是跳转指令(如
JMP
),计算目标地址并更新 PC。
4. 访存阶段 (Memory Access,可选)
- 作用:读写内存数据(仅
LOAD
/STORE
类指令需要)。 - 关键操作:
- 地址寄存器(AR) 存储内存地址。
- 数据寄存器(DR) 临时保存读写的数据。
5. 写回阶段 (Write Back,可选)
- 作用:将结果写回寄存器(仅需要保存结果的指令需要)。
- 关键操作:将 ALU 结果或内存数据写入目标寄存器。
6. 中断检查
- 作用:响应外部中断请求(非必需步骤)。
- 关键操作:
- 若有中断,保存当前 PC 值,跳转到中断处理程序。
- 若无中断,继续执行下一条指令。
进制计算
1K=1024B(字节Byte)= 2^12B = 1024*8bit(比特,也叫做位)
题型(多练,避免算错)
给一个地址范围,一般都是按照字节编址
2的n次方常用
2^0 = 1
2^1=2
2^3=8
2^4=16
2^5=32
2^6=64
2^7=128
2^8=256
2^9=512
2^10=1024
16进制
A=10
B=11
C=12
D=13
E=14
F=15
解题技巧
- 数F前有多少位。这个很容易出错,容易少数1位。导致选错
- 1 KB= 2^10 B = 2^10 * 8 bit = 4 * 16^4 B
- 末尾+1-开始=(x)B
原码/反码/补码/移码
知识点:
- 最高位是符号位,符号位是0表示正数,符号位是1则表示负数
- 正数的原反补码都一样(不包括0,因为0既不是正数,也不是负数),负数的反码=负数的原码按位求反(符号位不变,其他位按位取反),负数的补码=负数的反码+1
- 对补码在进行1次补码等于原码
- -0=+0,0的原反补码都相同。 特别注意 0 既不是正数也不是负数,代表空量的一个数
浮点数
多看多练
寻址
奇偶校验码/海明码/循环冗余码 (多记概念)
奇偶校验码
只校验,不纠错。 只有奇数个数据位发生错误,才会发现错误
循环冗余校验码
模2运算来构造校验位
海明码
- 码距必须要大于1
- 码距等于2,只能校验错误,不能就错误
- 码距>=3, 校验错误+纠错
RISC和CISC
流水线
存储器
Cache
中断
总线
加密技术与认证技术
加密算法
报文摘要:防止报文被篡改
可靠性公式
攻击
主动攻击
主动攻击的目的是破坏系统完整性、可用性或真实性,攻击者直接对数据或系统进行篡改或干扰。
- 篡改(Tampering)
- 修改传输或存储中的数据。例如:篡改HTTP请求参数以获取未授权数据。
- 伪装(Masquerade)
- 冒充合法用户或实体进行攻击。例如:伪造发件人地址发送钓鱼邮件。
- 重放攻击(Replay Attack)
- 截获合法通信后重复发送,以欺骗系统。例如:重复提交已捕获的登录凭证。
- 拒绝服务攻击(DoS/DDoS)
- 通过大量请求耗尽系统资源,导致服务瘫痪。例如:SYN洪水攻击。
- 中间人攻击(MITM, Man-in-the-Middle)
- 攻击者插入通信链路,窃听或篡改数据。例如:伪造WiFi热点截取用户信息。
- 恶意代码(Malware)
- 植入病毒、蠕虫、木马等破坏系统或窃取数据。
- SQL注入/XSS攻击
- 通过注入恶意代码操纵数据库或劫持用户会话(属于应用层主动攻击)
被动拦截
被动攻击的目的是非法获取信息,但不直接破坏系统或数据。攻击者通常隐蔽进行,难以被发现。
- 窃听(Eavesdropping)
- 通过监听网络流量获取敏感信息(如密码、明文传输的数据)。
- 例如:使用抓包工具(如Wireshark)截取未加密的HTTP通信。
- 流量分析(Traffic Analysis)
- 分析通信模式(如频率、时间、数据量等)推断信息,即使数据已加密。
- 例如:通过分析某服务器的流量峰值,推测其业务活动。
- 信息收集(Information Gathering)
- 收集系统公开信息(如IP地址、端口、软件版本等),为后续攻击做准备。
- 被动攻击防御:加密技术(如HTTPS、VPN)、最小化敏感信息暴露。
- 主动攻击防御:防火墙、入侵检测系统(IDS)、数字签名、输入验证等。
解释 编译
符号表
-
Python是解释型语言
-
除法运算
- // 是整除运算符,返回一个整数,
3//6 == 0
- / 是普通除法运算符,返回一个浮点数,
'3/6=0.5'
- // 是整除运算符,返回一个整数,
-
**
用来操作幂运算>>> 5 ** 2
, 得到的是5 的平方的值 -
Python中没有
char
类型,char = 'A' # 单字符本质是字符串
-
Python区间问题
-
大多数情况都是左闭右开
-
'012'[1:2]
,结果是1 -
list(range(1, 4))
,结果是 [1, 2, 3] -
import random random.randrange(1, 4) #返回1到4的一个数字,只返回1个.不包括4
-
-
个别情况
-
arr = [0,1,2,3] arr.pop(1) # 直接删除下标1,得到arr的值为[0,2,3]
-
-
-
字符串截取
- [:3], 表示从左到右向字符串末尾截取, 从下标0开始,截取3位
"0123"[:3]
得到的结果是'012'
- "0123"[:10] 得到的结果是
'0123'
- [2:], 表示从下标2开始,包括下标2,
"0123"[2:]
, 结果是'23'
"0123"[:]
,完整输出'0123'
- -1表示最后1个字符的下标
"0123"[-3:-1]
,结果是'12'
"0123"[-1:-3]
,结果是空字符串''
- [:3], 表示从左到右向字符串末尾截取, 从下标0开始,截取3位
-
range场景+语法
-
循环遍历固定次数
for i in range(5): #函数定义后的冒号省略会导致报错 print(i) # 输出: 0, 1, 2, 3, 4
-
遍历列表/字符串的索引
s = "hello" for i in range(len(s)): print(s[i]) # 输出: h, e, l, l, o
-
生成等差数列
# 生成 1~10 的偶数 even_numbers = list(range(2, 11, 2)) # [2, 4, 6, 8, 10]
-
反向遍历
for i in range(5, 0, -1): print(i) # 输出: 5, 4, 3, 2, 1
-
快速初始化列表
zeros = [0] * 10 # [0, 0, ..., 0] indices = list(range(10)) # [0, 1, 2, ..., 9]
-
数学计算中的序列生成
[x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25]
-
-
冒号
:
是 Python 语法的一部分,它指示接下来的一段代码属于某个控制结构的代码块(如for
、if
、while
,以及函数定义末尾 等),省略之后程序会抛出 SyntaxError 错误# 片段1 for i in range(5): print(i) # 片段2 def add(a, b): return a + b
-
没有
switch
语句 -
else
可以与for
、while
和try
语句结合使用。对于try
语句,finally
总会执行(无论是否发生异常)。
try:
x = 10 / 0
except ZeroDivisionError:
print("Can't divide by zero")
else:
print("No exception occurred")
finally:
print("This will always execute")
-
Python 支持多重继承
-
不强制类型转换: Python 动态类型语言,无需显式类型转换 / Java 是静态类型语言,需要显式的类型转换
-
元组不可修改: 用圆括号
()
来定义,创建后不能更改其中的元素/ Java可以修改成功my_tuple = (1, 2, 3) # 尝试修改元素会引发错误 # my_tuple[0] = 10 # 会引发 TypeError
-
Python命名是由大小写字母,数字,下划线,汉字等字符组成, 不包括$
-
布尔型True/False,首字母要大写,小写报错
-
str函数
x=5 y=3 z=x+y print(str(z)) #正常执行,不会报错. 输出'8'
数据结构上
图的拓扑排序
邻接矩阵
对称矩阵
稀疏矩阵
三角矩阵
连通图
非连通图
在边的数量不变的情况下,增加1个节点,就变成了非连通图
上午题 #5 知识产权
不受时间限制的著作权:
- 署名权
- 修改权
- 保护作品完整权
专利费(保护费:保护防止白嫖)
职务作品
委托开发
计算机著作权侵权
商业秘密权
专利申请权
商标权
商标注册
计算机软件著作权的行使
- 展览权是原件持有人的特有的权利,著作权人不能以发表权限制其权利(除非有约定)。
- 所有权是所有人依法对自己财产所享有的占有,使用,收益和处分的权利。
上午题 #6 数据库
三级模式
两级映像
注意: 就只有两级。不存在其他,比如外到内
(1)模式/内模式的映像。存在于概念级和内部级之间,实现了概念模式到内模式之间的相互转换。 (2)外模式/模式的映像。存在于外部级和概念级之间,实现了外模式到概念模式之间的相互转换。
关系代数表达式
注意: ^ 是并且的意思. σ2>'7'表示的是第2列的值大于7
连接
经典题型-自然连接
自然连接前的关系是, 进行自然连接后(已经去掉了重复列),从1开始数.最后投影
经典题型-笛卡尔积
SQL控制语句
视图
候选关键字/主属性/非主属性
详细分析
给定关系模式R<U,F>,U={A,B,C,D},F={AB→C,C→B}。关系R有几个候选关键字,且分别有哪些主属性和非主属性?
- 关系模式 R<U, F>:这里 U 是属性的集合 {A, B, C, D},F 是函数依赖的集合 {AB→C, C→B}。
- 候选关键字(Candidate Key):能唯一标识关系中元组的最小属性集合。即,候选关键字的闭包包含所有属性 U,且其任何真子集的闭包都不能包含所有属性。
- 主属性(Prime Attribute):属于任何一个候选关键字的属性。
- 非主属性(Non-Prime Attribute):不属于任何候选关键字的属性。
寻找候选关键字
为了找到所有的候选关键字,我们需要找出所有属性集的最小组合,其闭包能覆盖所有属性 {A, B, C, D}。我们可以从单个属性开始,逐步增加属性,直到找到满足条件的组合。
1. 计算单个属性的闭包
- {A}+:
- 初始:A
- 无法通过 F 中的函数依赖扩展,因为没有以 A 为左侧的依赖。
- {A}+ = {A} ≠ U
- {B}+:
- 初始:B
- 无法通过 F 扩展。
- {B}+ = {B} ≠ U
- {C}+:
- 初始:C
- 使用 C→B:{C, B}
- 无法进一步扩展。
- {C}+ = {B, C} ≠ U
- {D}+:
- 初始:D
- 无法扩展。
- {D}+ = {D} ≠ U
单个属性都无法覆盖所有属性,因此需要尝试多个属性的组合。
2. 尝试两个属性的组合
- {A, B}+:
- 初始:A, B
- 使用 AB→C:{A, B, C}
- 使用 C→B:已经在集合中。
- 无法进一步扩展。
- {A, B}+ = {A, B, C} ≠ U (缺少 D)
- {A, C}+:
- 初始:A, C
- 使用 C→B:{A, B, C}
- 使用 AB→C:已经在集合中。
- 无法进一步扩展。
- {A, C}+ = {A, B, C} ≠ U
- {A, D}+:
- 初始:A, D
- 无法直接应用任何函数依赖。
- {A, D}+ = {A, D} ≠ U
- {B, C}+:
- 初始:B, C
- 使用 C→B:已经在集合中。
- 无法进一步扩展。
- {B, C}+ = {B, C} ≠ U
- {B, D}+:
- 初始:B, D
- 无法应用函数依赖。
- {B, D}+ = {B, D} ≠ U
- {C, D}+:
- 初始:C, D
- 使用 C→B:{B, C, D}
- 无法进一步扩展。
- {C, D}+ = {B, C, D} ≠ U (缺少 A)
两个属性的组合都无法覆盖所有属性,需要尝试三个属性。
3. 尝试三个属性的组合
-
{A, B, D}+:
- 初始:A, B, D
- 使用 AB→C:{A, B, C, D} = U
- 已经覆盖所有属性。
- {A, B, D}+ = {A, B, C, D} = U
这是一个超键,需要检查是否可以去掉某个属性仍能覆盖 U。
- 检查 {A, D}+ = {A, D} ≠ U
- 检查 {B, D}+ = {B, D} ≠ U
- 检查 {A, B}+ = {A, B, C} ≠ U
无法去掉任何属性,因此 {A, B, D} 是一个候选关键字。
-
{A, C, D}+:
- 初始:A, C, D
- 使用 C→B:{A, B, C, D} = U
- {A, C, D}+ = U
检查是否可以去掉某个属性:
- {A, D}+ = {A, D} ≠ U
- {C, D}+ = {B, C, D} ≠ U
- {A, C}+ = {A, B, C} ≠ U
无法去掉任何属性,因此 {A, C, D} 也是一个候选关键字。
-
其他三个属性的组合:
- {A, B, C}+:
- 初始:A, B, C
- 使用 AB→C 和 C→B 已经包含。
- {A, B, C}+ = {A, B, C} ≠ U (缺少 D)
- {B, C, D}+:
- 初始:B, C, D
- 使用 C→B 已经包含。
- {B, C, D}+ = {B, C, D} ≠ U (缺少 A)
这些组合不能覆盖 U。
- {A, B, C}+:
4. 尝试四个属性的组合
- {A, B, C, D}:
- 这是一个超键,但不是最小的,因为已经有更小的组合 {A, B, D} 和 {A, C, D} 可以覆盖 U。
- 因此,{A, B, C, D} 不是候选关键字。
5. 检查是否有其他候选关键字
我们需要确认是否还有其他两个或三个属性的组合可以覆盖 U。
- 我们已经检查了所有两个属性的组合,都无法覆盖 U。
- 对于三个属性,只有 {A, B, D} 和 {A, C, D} 可以覆盖 U,且都是最小的。
因此,候选关键字有两个:{A, B, D} 和 {A, C, D}。
确定主属性和非主属性
- 主属性:出现在至少一个候选关键字中的属性。包括在候选关键字中的属性都是主属性,反之是非主属性
- {A, B, D} 和 {A, C, D} 中的属性有:A, B, C, D。
- A 出现在两个候选关键字中。
- B 出现在 {A, B, D} 中。
- C 出现在 {A, C, D} 中。
- D 出现在两个候选关键字中。
- 因此,所有属性 A, B, C, D 都是主属性。
- {A, B, D} 和 {A, C, D} 中的属性有:A, B, C, D。
- 非主属性:不属于任何候选关键字的属性。
- 这里没有非主属性。
三范式
1NF
特点: 每个属性是原子的, 不可再分的
存在的问题: 存在冗余,存在数据冗余、更新异常,需要分解
2NF
特点: 不存在非主属性对候选码的部分函数依赖.或者说每个非主属性完全依赖主键(主属性)
存在的问题: 插入/删除异常
3NF
消除: 消除传递依赖
存在:
BCNF
4NF
关系分解
无损连接和保持函数依赖
复合属性与多值属性
典型例子及本质区别
多值
多个属性是独立的, 去掉任何一个也是完整的
1个人有多个电话号码
- 同一属性"电话号码",有多个独立的值
- 号码之间是并且关系.无上下级关系
- 每个号码可以单独使用,也可以多选
- 任意号码可以新增/删除/修改.属性仍然保持完整性
1个人有多个电子邮箱
1个人有多个技能
复合
多个属性之间需要组合才能表达完整意义
例子:姓氏("张") + 名字("三")
完整姓名
- 由姓氏和名字组合成完整姓名
- 子属性有明确语义关系
- 组合后才有完整意义
地址
例子:中国+北京市+海淀区+中关村南大街5号
- 由多级行政区划组成
- 子属性有层级关系
- 组合后形成完整地址
身份证号码
例子:110105+19900307+3721+X
- 由地区码、生日码、顺序码、校验码组成
- 各部分有特定编码规则
- 组合后才有唯一标识意义
产品规格
例子:手机=屏幕(6.1")+CPU(A15)+内存(8GB) 分析:
- 由多个技术参数组成
- 子属性共同描述产品
- 缺一不可完整描述
分E-R图冲突有3类
这有这3种,没有其他
属性冲突
属性的类型、取值范围、取值单位等不一致
命名冲突
不同的命名在不同的分E-R图中表达的意思是同一个
结构冲突
同一个实体在不同的E-R图中有不同的属性,同一个对象在某个E-R图中被抽象为实体, 在某个E-R图中又被抽象为属性
关键区分技巧
-
属性冲突: 定义或取值规则不一致(不是名字问题,也不是属性缺失问题)
-
命名冲突:叫法不同,纠结“叫什么名字”(比如该叫职工号还是教师号?)。
-
结构冲突:属性集合定义不同, 纠结“该有哪些属性”(为什么人力部门不记录职称?教学部门不记录性别?)
三者的终极区分技巧
冲突类型 | 问题焦点 | 判断关键词 | 示例 |
---|---|---|---|
属性冲突 | 属性的数据类型或取值规则不一致 | “类型不同”“格式不同” | 职工号:整数 vs 字符串 |
命名冲突 | 属性或实体名称不统一 | “名字不同”“叫法不一致” | 职工号 vs 工号 |
结构冲突 | 同一实体的属性集合不一致 | “缺少属性”“多出属性” | 人力无职称,教学无性别 |
数据库设计阶段与规范化
先问需求定边界,再画E-R概念清; 逻辑转表规范化,物理存得快又稳。
阶段 | 核心任务 | 关键输出 |
---|---|---|
需求分析 | 确定系统边界、收集业务规则和数据需求 | 需求说明文档、数据字典、数据流图 |
概念设计 | 建立抽象模型(如E-R图) | E-R图、概念模型 |
逻辑设计 | 将概念模型转为关系模型,并进行规范化 | 关系模式(表结构)、范式化 |
物理设计 | 优化存储结构(索引、分区等) | 物理存储方案、SQL调优 |
程序文档是开发人员根据设计结果编写代码后的产物。不属于数据库设计阶段
共享锁(S)和排他锁(X)
S锁与S锁兼容
- S锁可以同时被不同的事务加锁成功
- S锁被当前事务添加成功后,此时当前事务对当前数据添加X锁,
- 如果同时没有被其他事务添加S锁,此时S锁升级为X锁, 添加X锁成功
- 如果同时被其他事务添加了S锁,那么添加X锁失败
X锁与其他锁完全冲突
- X锁被某一事务添加成功后, 其他事务无法对当前事务添加任何锁,直到X锁释放
- 同一事务添加X锁成功后, 再次添加X锁,数据库会跳过冲突检查,不会真正重复加锁,但是也不会报错
- 当前数据已经被事务添加了S锁,其他事务请求添加X锁,添加不成功
分布式数据库
Armstrong公理系统
数据库函数格式
上午题 # 8 UML
2025年3月29日12:43:34
UML四种事务
类别 | 核心特点 | 典型例子 | 类比记忆 |
---|---|---|---|
结构事物 | 静态的、基础构建块 | 类、接口、构件、节点 | 公司的「部门架构图」 |
行为事物 | 动态的、动作与流程 | 交互、状态机、活动 | 员工的「工作流程表」 |
分组事物 | 组织管理的容器 | 包(Package) | 文件柜的「分类抽屉」 |
注释事物 | 附加说明的符号 | 注释(Note) | 贴在墙上的「便利贴」 |
UML五种关系
依赖借,关联友,聚合可拆组合死
关系类型 | UML表示 | 代码表现 | 生命周期 | 强度 |
---|---|---|---|---|
依赖 | -----> (虚线) | 局部变量/ 方法参数 | 临时性 | ⭐ |
关联 Association | ──>(实线) | 成员属性 | 独立存在 | ⭐⭐ |
聚合 Aggregation | ◇── (空心菱) | 成员属性 | 部分可独立 | ⭐⭐⭐ 强调对象间的引用关系 |
组合 Composition | ◆── (实心菱) | 成员属性 | 同生共死 | ⭐⭐⭐⭐ 人体与心脏 |
泛化/继承 Generalization | ▲── (空心三角) | extends | 子类继承父类 | 特殊 |
实现 Realization | 虚线空心三角 | 类实现接口 | 子类实现父类 |
关联多重度
UML类图
对象图
用例图
一个用例和多个对象的行为
序列图(顺序图)
以时间顺序组织的对象之间的交互活动
特点
- 有垂直的虚线(生命线)-> 序列图或者通信图(通信图也叫做协作图, 通信图专有的特点是, 消息旁边有箭头)
- 垂直对象排列 + 水平消息箭头 → 序列图独有布局。
- 看是否有交互片段(如
loop
、alt
)→ 锁定序列图
通信图(协作图)
强调参加交互的对象的组织
特点
- 消息有编号
- 消息旁边有箭头表示消息的指向
状态图
展现了一个状态机,它由状态、转换、事件、活动组成. 强调对象行为的时间顺序
特点
- 只描述1个对象的内部的多个状态变化
- 可以没有终点(final,用⦾表示)状态,图仍然是有效的
- 不适用多对象交互(多对象交互是序列图和通信图)
- 复合状态(也叫做超状态,表示包含多个子状态)
- 四条边都是直线,四个角是圆角
- 两个状态之间有转换(迁移), 转换包含的元素有: 事件 + [监护条件] + /效果(动作)
转换(迁移)的组成因素
转换时状态之间的连线.而非状态
转换的三大要素是:事件、条件、效果(动作),而非“状态”
转换连接两个状态
活动图
是一种特殊的状态图. 所以特征里有黑太阳,
展现了从一个活动到另一个活动的流程
特点
- 有两个实心并且瘦长的矩形
- 有并发分岔/汇合分岔. 注意, 状态图也会有
是一种特殊的状态图
构件图(组件图)
构件图是组件之间的组织和依赖
特点
- 英文 component
- 有供/需接口表示, 即圆和半圆
- 两室一厅
部署图
图汇总
上午题 #9 设计模式
总览
- 工厂单例建原型: 创建型模式
- 世代外接享组合: 结构性模式
- 剩下的(其他的)都是行为型模式共11个
创建型模式(5个):
- 工厂方法 (创建型类)
- 抽象工厂方法 (创建型对象)
- 单例模式 (创建型对象)
- 建造者模式 (创建型对象)
- 原型模式 (创建型对象)
结构性模式(7种):
- 装饰器模式 (结构型对象)
- 适配器模式 特殊: 既是结构型对象模式 ,也是结构型类模式
- 代理模式 (结构型对象)
- 外观者模式 (结构型对象)
- 桥接模式 (结构型对象)
- 享元模式 (结构型对象)
- 组合模式 (结构型对象)
行为型模式(11种)
- 策略模式 (行为型对象)
- 模板方法模式 (行为型类模式)
- 观察者模式 (行为型对象)
- 迭代子模式 (行为型对象)
- 责任链模式 (行为型对象)
- 命令模式 (行为型对象)
- 备忘录模式 (行为型对象)
- 状态模式 (行为型对象)
- 访问者模式 (行为型对象)
- 中介者模式 (行为型对象)
- 解释器模式 (行为型类模式)
单例模式 Singleton
意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点
用途
工厂方法模式 Factory
抽象工厂模式 Abstract Factory
特点
- 创建多个产品族
- 多个抽象产品接口
- 1个工厂级产生多个产品
意图:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类
生成器模式(Builder)/建造者模式
特点
Builder模式适用于:
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时
- 当构造过程必须允许被构造的对象有不同的表示时
原型模式
单例模式
适配器模式 Adapter
转换原接口 得到 兼容的接口
桥接模式 Bridge
意图:
将抽象部分与实现部分分离, 使他们可以独立变化
英文单词关键词:OperationImp
Bridge模式适用于:
- 不希望在抽象和它的实现部分之间有一个固定的绑定关系。
- 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。
- 对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不必重新编译。
- 有许多类要生成的类层次结构。
- 想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。
组合模式 Composite
意图
将对象组合成树型结构以表示“部分-整体”的的层次结构。Composite使 得用户对单个对象 和组合对象的使用具有一致性。
适用性
- 想表示对象的部分-整体层次结构。
- 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
分析:
- Component:作为抽象基类,定义了所有部件(包括叶子
Leaf
和组合Composite
)的通用接口(如add()
、remove()
)。 Composite
是Component
的子类,实现有子部件的具体行为。Leaf
是叶子节点,不包含子部件(可能抛出“不支持操作”异常)
装配器模式 Decorator
意图
动态地给对象添加一些职责, 比生成子类更加灵活
其中: Component定义一个对象接口,可以给这些对象动态地添加职责。 ConcreteComponent定义一个对象,可以给这个对象添加一些职责。 Decorator 维持一个指向Component 对象的指针,并定义一个与 Component 接口一致 的接口。 ConcreteDecorator向组件添加职责。
适用性
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
- 处理那些可以撤销的职责。
- 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支 持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,
- 由于类定义被隐藏,或类定义不能用于生成子类。
外观模式 Facade
意图
定义一个高层接口,为子系统中的一组接口提供一个一致的外观,从而简化了该子系统的使用
将一系列对象加以包装以简化接口
结构
- Facade知道哪些子系统类负责处理请求;将客户的请求代理给适当的子系统对象。不要混淆认为代理模式
- Subsystem classes实现子系统的功能;处理有Facade对象指派的任务;没有Facade的 任何相关信息,即没有指向Facade的指针。
享元模式 Flyweight
意图
运用共享技术有效地支持大量细粒度的对象
结构
代理模式 Proxy
意图
通过提供相同的接口,为其他对象提供代理以控制这个对象的访问
结构
责任链模式 Chain Of Reponsibility
意图
使多个对象都有机会处理请求,从而避免发送者和请求者之间的耦合关系.将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止
结构
- Handler定义一个处理请求的接口;(可选)实现后继链。
- ConcreteHandler处理它所负责的请求;可访问它的后继者;如果可处理该请求,就处 理它,否则将该请求转发给后继者。
- Client向链上的具体处理者(ConcreteHandler)对象提交请求。
命令模式 Command
意图
将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作
类图关键英文单词 Command、Execute
适用于:
(1)抽象出待执行的动作以参数化某对象。
(2)在不同的时刻指定、排列和执行请求。
(3)支持取消操作。
(4)支持修改日志。
(5)用构建在原语操作上的高层操作构造一个系统。
结构
- Command 声明执行操作的接口。
- ConcreteCommand 将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实 现Execute。
- Client 创建一个具体命令对象并设定它的接收者。
- Invoker 要求该命令执行这个请求。
- Receiver 知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
解释器模式 Expression
意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来 解释语言中的句子。
结构
迭代器模式 Iterator
意图
提供一种方法顺序访问一个聚合对象中的各个元素,且不能暴漏该对象的内部表示.
结构
- Iterator(迭代器)定义访问和遍历元素的接口。
- ConcreteIterator(具体迭代器)实现迭代器接口;对该聚合遍历时跟踪当前位置。
- Aggregate(聚合)定义创建相应迭代器对象的接口。
- ConcreteAggregate(具体聚合)实现创建相应选代器的接口,该操作返回ConcreteIterator 的一个适当的实例。
中介者模式 Meditor
意图
用一个对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而 使其耦合松散,而且可以独立地改变它们之间的交互。
结构
适用于
备忘录模式 Memento
意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,从而可以在以后将该对象恢复到原先保存的状态
结构
观察者模式 Observer
意图
定义对象间一对多的关系,当一个对象的状态发生变化时,所有依赖它的对象都能得到通知并自动更新
结构
状态模式 state
意图
允许一个对象在其内部状态改变时改变它的行为.对象看起来修改了他的类
结构
适用性
一个对象的行为决定于它的状态,并且时刻根据它的状态改变它的行为
策略模式
意图
定义一系列的算法,并把他们封装起来,使他们可以相互替换.
结构
适用性
模板方法模式 Template Method
意图
定义1个算法中的算法骨架,而将一些步骤延迟到子类.使得子类可以不修改1个算法的结构即可重新定义该算法的某些特定步骤
结构
适用性
访问者模式 Visitor
意图
表示1个作用于某个对象中的各元素操作.它允许在不改变各元素的类的前提下定义作用于这些元素的新操作
结构
适用性
需要对一个对象结构中的对象进行很多不同的并且不相关的操作
10 操作系统
进程的三态模型
进程的五态模型
死锁
进程资源图
判断阻塞的依据
考虑极端/独占的情况, 即资源全都被占用,没有释放的情况
- 先分配, 后申请
- 当所有的资源都分配完毕, 假设所有进程都是耗时操作(即每个进程都没有释放已分配的资源)**,**并且没有空闲资源,此时再去申请资源,则认为是阻塞的;反之,如果能申请到资源,则认为是非阻塞的
判断化简的依据
考虑最好的情况,即有机会共赢
死锁避免
局部性原理
分布存储管理
段页式存储管理
单/双缓存区
磁盘调度算法
旋转调度算法
多级索引结构
位示图
杂题
---
IO系统的层次结构
11 机构化开发
软件工程上
模型
瀑布模型
- 需求明确
- 做过类似项目
- 不会变化的需求. 难以适应变化的需求
增量模型
是瀑布模型的变体,拥有瀑布模型的所有优点,此外还有:
- 第一个可交付版本的成本和时间少
- 开发由增量表示的小系统所承担的风险较小
- 很快发布了第一个版本, 可以减少用户需求的变更
缺点:管理所发生的成本,进度和配置的复杂性可能超出组织的能力
原型模型
适合用户需求不清,经常变化的情况,并且系统规模不大,不复杂的时候
螺旋模型
- 风险评估
- 大规模
喷泉模型
敏捷方法
极限编程 XP
水晶法 Crystal
并列争球法 Scrum
自适应 ASD
敏捷同一过程 AUP
系统设计
概要设计
设计软件系统总体结构
关键字:
- 模块划分
- 体系结构
数据结构及数据库设计
编写概要设计文档
评审
系统测试
集成测试
测试方法
黑盒测试
白盒测试
分支覆盖(判定覆盖)
2020 11月 第31题
软件质量特性
14 信息安全
防火墙类型 | 工作层级 | 关键特性 | 典型场景 |
---|---|---|---|
包过滤 | 网络层/传输层 | 检查IP/TCP头(如端口、IP地址) | 路由器内置防火墙 |
应用级网关 | 应用层 | 深度检查HTTP/FTP等应用数据 | Web应用防护、邮件过滤 |
状态检测防火墙 | 传输层 | 跟踪连接状态(如TCP握手) | 企业网络边界 |
病毒
16 算法
N皇后-回溯法
非递归
// 标准输入输出流
#include <math.h>
#include <stdio.h>
// 定义1个N x N的棋盘
// 这是一个宏定义,属于C语言的预处理指令
// 代码中所有出现 N 的地方都会被替换为 4
// 不可修改,调试的时候,看不到N(替换后符号消失)
// 定义1个标识符, 常量 4. 表示4个皇后
#define N 10
// 定义了一个名为 q 的整型数组
// 由于N=4,所以数组的大小为5
// 存储皇后的列号
int q[N + 1];
// 检查第j个皇后的位置是否合法
// 由于不同的皇后不会放在同一行,所以不用判断行
// 只需要判断两个皇后不在同一列并且不在一条斜线上, 即认为当前皇后的位置合法;反之不合法
// j表示当前正在摆放的第j个皇后
int check(int j) {
// 如果当前皇后和它之前的每一个皇后相比,
// 在同一行或者同一个斜线上,认为位置不合法,否则对比完它之前的所有皇后之后,位置都是合法的, 则认为位置合法
for (int i = 1; i < j; ++i) {
if (q[i] == q[j] || abs(i - j) == abs(q[i] - q[j])) {
// 表示在同一列或者同一个斜线上.位置不合法
return 0;
}
}
return 1;
}
// 求解N皇后的方案
void queue() {
// 从1开始,q[i]表示第i个皇后
for (int i = 1; i <= N; ++i) {
q[i] = 0; // 把每个皇后的列都定义为0,表示全都没有放入棋盘.反之>0,比如q[i] = 1,表示第1个皇后放在了第一行的第一列
}
// 方案数
int answer = 0;
// 表示正在摆放第j个皇后
int j = 1;
// i <=N 表示要摆放N个皇后
while (j >= 1) {
// 表示将第j个皇后,向右移动1个位置.
// 初始的时候,表示将第1个皇后从棋盘外(q[0]移动到第一行的第1列)
q[j]++;
while (q[j] <= N && !check(j)) {
// 这里必须要加上=N,如果不加.就会少一个越界的场景.导致由于越界后需要调整上一个皇后位置的场景丢失.最终导致数据错乱
q[j] = q[j] + 1;
}
if (q[j] <= N) {
if (j == N) { // 找到了N皇后的一组解
answer++;
printf("方案%d: ", answer);
for (int i = 1; i <= N; ++i) {
printf("%d,", q[i]);
}
printf("\n");
} else {
// 继续摆放下一个皇后的位置
j++;
}
} else {
// 越界,回溯
q[j] = 0;
j--;
}
}
}
int main(int argc, char const *argv[]) {
queue();
return 0;
}
递归
#include <math.h>
#include <stdio.h>
#define N 3
int answer = 0;
// 定义1个一维数组
// 假设有4个皇后, 每个皇后占1行,
// j从1开始, 下标j表示第j个皇后,q[j]的值表示皇后的位置列.所以1个皇后的位置可以表示为 j,q[j].
// 即第j个皇后在第j行的第q[j]列
int q[N + 1];
/**
* 检查当前皇后的位置是否合法
* @param j 从1开始,表示当前正在被摆放的皇后的位置列
* @return 1 表示合法;0表示不合法
*/
int check(int j) {
for (int i = 1; i < j; i++) {
// 当前摆放的皇后的列和以往的每一个皇后在同一列,则认为不合法;
// 或者
// 当当前皇后的行号-每一个皇后的行号的绝对值等于两个皇后的列号的绝对值,同样认为不合法
if (q[i] == q[j] || abs(i - j) == abs(q[i] - q[j])) {
return 0;
}
}
return 1;
}
/**
* 求解N皇后问题
*/
void queue(int j) {
q[j] = q[j] +1;
for (int i = 1; i <= N; ++i) {
q[j] = i;
if (check(j)) {
if (j == N ) {
//找到一组N皇后解
answer++;
printf("方案%d: ", answer);
for (int i = 1; i <=N ; ++i) {
printf("%d, ", q[i]);
}
printf("\n");
} else {
queue(j + 1);
}
}
}
}
int main() {
for (int j = 1; j <= N; ++j) {
q[j] = 0;
}
// 一开始将第一个皇后放入到第一行的第一列
queue(1);
return 0;
}
归并排序-分治法
写法1
#include <stdio.h>
void merge(int arr[], int begin, int mid, int end) {
// 变量抽离出来,后续可能复用,并且看代码也清楚明了
int left_len = mid - begin + 1;
int right_len = end - mid;
int left[left_len], right[right_len];
// Copy data to temp arrays
//把指定区间的数据拷贝到 左右两个数组中. 那么arr就可以置换出来了.也就不依赖arr了
//换言之,arr的[begin,end]区间,可以直接覆盖值.少定义1个目标临时数组
for (int i = 0; i < left_len; i++)
left[i] = arr[begin + i];
for (int j = 0; j < right_len; j++)
right[j] = arr[mid + 1 + j];
// Merge the temp arrays back into arr[begin..end]
//定义目标数字从begin位置开始依次放入数据
//这里选择新定义1个变量k,并且把begin赋值给k,避免造成begin污染
//i<做集合的length,同理右边也是.为了防止数组越界
//当这个循环结束后.说明至少有1边的数组已经全部放入到了目标数组.那么只需要将另外1个数组的剩余部分全部依次放入目标数组即可
int i = 0, j = 0, k = begin;
while (i < left_len && j < right_len) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
// Copy remaining elements of left[] if any
while (i < left_len) {
arr[k++] = left[i++];
}
// Copy remaining elements of right[] if any
while (j < right_len) {
arr[k++] = right[j++];
}
}
void mergeSort(int arr[], int begin, int end) {
if (begin < end) {
int mid = begin + (end - begin) / 2; // Avoid potential overflow
mergeSort(arr, begin, mid);
mergeSort(arr, mid + 1, end);
merge(arr, begin, mid, end);
}
}
int main() {
int arr[] = {90, 1, 100, 5, 20};
int n = sizeof(arr) / sizeof(arr[0]);
mergeSort(arr, 0, n - 1);
printf("Sorted array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
<<<<<<< HEAD
0-1背包/最大公共子序列/矩阵连乘-动态规划
=======
写法2 (推荐)
区别, 这种写法, 没有显式定义两个辅助数组
#include <stdio.h>
/**
* 归并排序分为3部分
* 1. 拆分
* 2. 求解
* 3. 合并
* @return
*/
void merge(int arr[], int low, int mid, int high) {
int len = sizeof(arr) / sizeof(arr[0]);
int tmpArr[len];
for (int i = low; i <= high; ++i) {
tmpArr[i] = arr[i];
}
int i = low; //表示左边数组移动的指针(下标)
int j = mid +1; //表示右边数组移动的指针
int k = low; //表示目标数组拜访位置的指针
while (i <= mid && j <= high) {
if(tmpArr[i] <= tmpArr[j]){
arr[k++] = tmpArr[i++];
} else{
arr[k++] = tmpArr[j++];
}
}
while (i <= mid) arr[k++] = tmpArr[i++];
while (j <= high) arr[k++] = tmpArr[j++];
}
void mergeSort(int arr[], int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
mergeSort(arr, low, mid);
mergeSort(arr, mid + 1, high);
merge(arr, low, mid, high);
}
}
int main() {
int arr[5] = {4, 3, 6, 2, 7};
int n = sizeof(arr) / sizeof(arr[0]);
mergeSort(arr,0, n-1);
for (int i = 0; i < n; ++i) {
printf("%d ,", arr[i]);
}
return 0;
}
b82f721409342e41c00d9744011c0390bba8d5d9
错题集整理-上午题
2024-9-25 17:07:29
链表
解析:
A选项,链表每增加一个节点,数据存储空间随着变大,A选项正确
B选项,链表元素由数据域和指针域组成,指针域用于指向直接后继的元素的地址,由于链表元素不一定是连续的,因此整个链表的存取必须从头指针开始,B选项错误
C选项,插入和删除操作不需要移动元素,指向改变指针域的指向即可,C选项正确
D选项,链表不需要连续的存储空间存储,因此无需实现估计存储空间大小,D选项正确
统一过程模型
解析:
谐音记忆: 演进 , 精化
起始阶段:起始阶段专注于项目的初创活动。
精化阶段:精化阶段在理解了最初的领域范围之后进行需求分析和架构演进。
构建阶段:构建阶段关注系统的构建,产生实现模型。
移交阶段:移交阶段关注于软件提交方面的工作,产生软件增量。
面向对象
加密算法
- 典型的对称加密算法:DES,3DES,AEC等
- 典型的非对称加密算法:RSA,ECC等
- 典型的摘要算法:SHA,MD5等
哈夫曼
每个字符一开始都是叶子结点
基于构建的开发
基于构件的开发是指利用预先打包的构件来构造应用系统。构件可以是组织内部开发的构件,也可以是商品化成品软件构件。基于构件的开发模型具有许多螺旋模型的特点,它本质上是演化模型,需要以迭代方式构建软件。其不同之处在于,基于构件的开发模型采用预先打包的软件构件开发应用系统
设计模块
数据库
算法
折半查找
贪心策略
贪心算法是指在对问题求解时,总是 做出 在当前看来是最好的选择。
-
分数背包即部分背包问题,物品可选择部分或全部放进背包,直至装满背包,通过贪心算法求解可将单位价值最大的物品 优先 ** 放入背包,以实现背包物品价值的最大化**
-
0-1背包指物品整体放入或不放入背包,因此不一定能完全装满背包,采用贪心算法可以取得局部最优解,但不一定是全局最优解;
-
旅行商问题是指旅行商要到若干个城市旅行,每访问一个城市后, 都会回到最初开始的城市,用贪心法不一定能求得最优解;
-
最长公共子序列用贪心法也不一定能求得最优解
白盒测试
白盒测试原则如下:
(1)所有独立路径至少执行一次
(2)取“真”和取“假”的两种逻辑判断至少都能执行一次
(3)每个循环都应在边界条件和一般条件下各执行一次
(4)测试程序内部数据结构的有效性等
判定覆盖
使程序中每条分支都至少执行一次
设计2个测试用例执行路径:
①②③④⑦⑧⑨⑩;①②③⑤⑦⑥③
或者
①②③④⑦⑥③;①②③⑤⑦⑧⑨⑩
即可满足判定覆盖。
语句覆盖
路径覆盖
取足够的测试用例,使得程序的每条可能执行到的路径都至少经过一次(如果程序中有环路,则要求每条环路路径至少经过一次)
如图:如图每个判断都需要两个用例,因此需要6个测试用例
黑盒测试
因果图鱼骨图(又名因果图、石川图)
是一种发现问题“根本原因”的分析方法,常用在项目管理中,黑盒测试也可以使用该方法
有效等价类
边界值分析
对输入或输出的边界值进行测试的一种黑盒测试方法
甘特图
重载和重写
浮点数
系统总线
解析
按连接部件不同,总线可分为:片内总线、系统总线、通信总线。
片内总线是芯片内部的总线,如CPU内部的总线。
系统总线是CPU、主存、I/O设备各大部件之间的信息传输线。
通讯总线用于计算机系统之间或与其他系统之间的通信。
OSI参考模型
解析
1.应用层(第7层):直接与用户和应用程序交互,提供网络服务,如HTTP、FTP等。
2.表示层(第6层):负责数据格式的转换、压缩和加密,确保不同系统之间的兼容性。
3.会话层(第5层):管理会话和连接,控制对话的建立、维护和终止。
4.传输层(第4层):提供端到端的通信,确保数据完整性和顺序,如TCP和UDP。
5.网络层(第3层):负责数据包的路由和转发,处理逻辑地址,如IP协议。
6.数据链路层(第2层):管理物理地址和错误检测,确保数据在同一网络内的传输。7.物理层(第1层):处理物理媒介的传输,涉及电气信号、光信号和传输介质
软件著作权
解析
- 署名权不可以继承, 看到所有权利的时候, 需要想到署名权
- 学习和研究, 可以不向软件著作权人支持报酬
- 部分或者全部转让, 这里的“全部”通常指的是经济权利,例如复制权、发行权、改编权等,但不包括署名权。署名权始终属于原作者,不能转让
对于著作人身权,也就是作者的署名权、修改权、保护作品完整权等权力,《中华人民共和国著作权法》规定上述权利的保护期不受限制
敏捷开发
解析
极限编程: 测试先行,计划赶不上变化
水晶法: 项目规模,重要性
并列争球法: 30天作为一个冲刺
自适应ASD: 复杂自适用, 提高组织的自适用能力
敏捷统一过程(AUP)
开发模型
快速原型模型
瀑布模型
喷泉模型
UML
序列图
特征
- 有垂直生命线
- 有水平消息箭头.强调消息传递的时间顺序
用例图
特征
- 椭圆形的用例框
概念
系统在它的周边环境的语境中所提供的外部可见服务
类图
协作图
特征
- 对象之间的链接线,标注消息序号,强调对象关系
概念
状态图
特征
- 圆角矩形
箭头表示状态之间的转移,突出状态变化
概念
活动图
特征
开始和结束用圆形表示,活动用矩形表示,控制流用箭头连接
概念
系统内从一个活动到另一个活动的流程
组件图
特征
概念
部署图
特征
概念
对象图
特征
概念
展示某一时刻一组对象以及它们之间的关系
设计模式
命令模式
将一个请求封装为对象,从而可以用不同的请求对客户进行参数化
观察者模式
当一个对象的状态发生改变时,依赖于它的对象都得到通知并被自动更新
状态模式
允许一个对象在其内部状态改变时改变它的行为
策略模式
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换
举例: 要求能根据季节,节假日等推出不同的旅行定价包,如淡季打折、一口价等
入侵防御系统
认证方式安全性
CA
软件可维护性
虚拟存储
SSL
管道过滤器
Python
- 没有内置的switch...case语句
页式存储
CPI 与 MIPS
加工
项目管理
风险管理
软件设计
软件测试
系统可维护性
系统验收测试
数据库
软件详细设计阶段
- 数据结构设计
- 算法设计
- 数据库的物理设计
- WITH CHECK OPTION
- 主要与数据的完整性和视图的约束相关
- WITH GRANT OPTION
- 主要与权限的传递和管理相关
分布式数据库
- 分片透明
- 指用户或应用程序不需要知道逻辑上访问的表具体是怎么分块存储的
- 复制透明
- 采用复制技术的分布方法,用户不需要知道数据是复制到哪些节点,如何复制的
- 位置透明
- 用户无须知道数据存放的物理位置,逻辑透明,即局部数据模型透明,是指用户或应用程序无须知道局部场地使用的是哪种数据模型
SCRUM MASTER职责
- 商品关系的主键是商品号
- 仓库关系的主键是(仓库号,商品号)
- 显然,仓库关系存在冗余、修改操作的不一致,以及插入异常和删除异常
- 派生属性
- 由其他属性经过运算得到的属性,因而派生属性产生冗余,通常不存储. 如age可以通过birth计算得到
- 多值属性
- 一个属性会同时取多个值, 而且这些值必须存储,如一个人可能有多个手机号码, 一个用户有多个收货地址
软件结构设计阶段
概要设计阶段(全局)
- 软件系统总体结构设计,将系统划分成模块
- 确定每个模块的功能
- 确定模块之间的调用关系
- 确定模块之间的接口,即模块之间传递的信息
- 评价模块结构的质量
- 数据结构及数据库设计
软件详细设计阶段(细节)
- 对模块内的数据结构进行设计
- 对数据库进行物理设计
- 对每个模块进行详细的算法设计
- 代码设计、输入/输出设计、用户界面设计
螺旋模型
螺旋模型强调通过多个迭代来降低项目风险,而不是专门为了快速交付
螺旋模型的核心是风险的评估和缓解
耦合
语法分析、词法分析、语义分析、目标代码生成
- 词法分析阶段处理的错误:非法字符、单词拼写错误等
- 语法分析阶段处理的错误:标点符号错误、表达式中缺少操作数、括号不匹配等有关语言结构上的错误。
- 静态语义分析阶段(即语义分析阶段)处理的错误:运算符与运算对象类型不合法等错误。
- 目标代码生成(执行阶段)处理的错误:动态语义错误,包括陷入死循环、变量取零时做除数、引用数组元素下标越界等错误等
以编译方式翻译C/C++源程序的过程中,类型检查在( )阶段处理。
A 词法分析
B 语义分析 √
C 语法分析
D 目标代码生成
数据库范式
数据库范式
第一范式 (1NF)
描述:确保每个字段都是原子值,不能有重复组或多值属性
正例:
| 学生ID | 学生姓名 | 课程 |
|--------|----------|--------|
| 1 | Alice | 数学 |
| 1 | Alice | 科学 |
反例:
| 学生ID | 学生姓名 | 课程 |
|--------|----------|--------------|
| 1 | Alice | 数学, 科学 |
问题分析
- 问题:
课程
字段包含多个值(数学
和科学
)。 - 原因:在1NF中,每个字段必须是原子值,不能包含重复或多值。
第二范式 (2NF)
-
描述:在满足1NF的基础上,消除部分依赖。所有非主属性必须完全直接依赖于主键(单个主键或者多列复合主键),即使存在间接依赖。
-
正例
| 学生ID | 课程 | 教师 | |--------|--------|-----------| | 1 | 数学 | Mr. Smith | | 1 | 科学 | Ms. Johnson |
-
反例
| 学生ID | 课程 | 教师 | 学生姓名 | |--------|--------|-----------|----------| | 1 | 数学 | Mr. Smith | Alice | | 1 | 科学 | Ms. Johnson | Alice |
问题分析
- 问题:
学生姓名
只依赖于学生ID
,而不是整个主键(学生ID
和课程
的组合)。 - 原因:在2NF中,所有非主属性必须完全依赖于主键,而不是主键的一部分。
第三范式 (3NF)
-
描述:在满足2NF的基础上,消除传递依赖。非主属性不能依赖于其他非主属性。
-
正例
| 学生ID | 课程 | 教师ID | |--------|--------|--------| | 1 | 数学 | 101 | | 1 | 科学 | 102 |
-
反例
| 学生ID | 课程 | 教师 | 教师办公室 | |--------|--------|-----------|------------| | 1 | 数学 | Mr. Smith | A101 | | 1 | 科学 | Ms. Johnson | B202 |
存在两个非主属性,教师和教师办公室, 教师办公室依赖于教师
问题分析
-
问题:
教师办公室
依赖于教师
,而不是直接依赖于主键(学生ID
和课程
的组合)。- 原因:在3NF中,非主属性不能依赖于其他非主属性。
第四范式 (4NF)
-
描述:在满足3NF的基础上,消除多值依赖。一个属性集的值不应影响其他属性集的值。
-
正例
| 学生ID | 课程 | |--------|--------| | 1 | 数学 | | 1 | 科学 | | 学生ID | 俱乐部 | |--------|------------| | 1 | 科学俱乐部 | | 1 | 体育俱乐部 |
-
反例
| 学生ID | 课程 | 俱乐部 | |--------|--------|------------| | 1 | 数学 | 科学俱乐部 | | 1 | 科学 | 体育俱乐部 |
问题分析
- 问题:同一学生的课程和俱乐部信息混在一个表中,造成多值依赖。
- 原因:在4NF中,一个属性集的值不应影响其他属性集的值。
直接依赖和间接依赖
直接依赖:这是我们关注的主要内容。如果所有非主属性直接依赖于主键,就满足2NF
间接依赖:指的是一个非主属性依赖于另一个非主属性,而这个非主属性又依赖于主键。比如薪资依赖于岗位,岗位依赖于教师号
部分依赖: 对于复合主键(由字段A和字段B组成)的关系, 某些属性依赖于A, 某些依赖于A、B
举个例子
- 假设有一个关系模式:
- 主键:
教师号
- 属性:
教师号 → 姓名, 部门号, 岗位
- 间接依赖:
岗位 → 薪资
- 主键:
在这个例子中:
姓名
、部门号
、岗位
完全依赖于教师号
,这是直接依赖。薪资
依赖于岗位
(间接依赖),但这并不妨碍教师号
完全确定其他属性。
结论
若主键能完全推导出所有非主属性,且不存在部分依赖,则满足2NF。间接依赖没关系的,不影响2NF的成立
UML
内容来自哔哩哔哩 【「软件设计师」 上午题 #8 UML】https://www.bilibili.com/video/BV1a44y1K7HH?p=17&vd_source=9b8c66469d7ef16dfa8f33c398331cdb
2024年11月16日22:14
泛化、关联
依赖、关联、聚集(聚合)、组合、泛化、实现
包含关系(include)
- 本质:强制性的依赖关系,表示基础用例必须执行包含的用例,否则功能不完整。
- 箭头方向:从基础用例指向被包含用例(虚线箭头 +
<<include>>
)。 - 示例:
- 基础用例:"网上购物"
- 包含用例:"支付"
- 解释:用户完成购物时,必须执行支付流程,否则订单无法成立。
扩展关系(extend)
关键字
- 如果/假设/若
- 只有
- 本质:条件性的扩展关系,表示基础用例在特定条件下可能执行扩展用例,非必需。
- 箭头方向:从扩展用例指向基础用例(虚线箭头 +
<<extend>>
)。 - 示例:
- 基础用例:"登录"
- 扩展用例:"找回密码"
- 解释:只有当用户忘记密码时,才会触发“找回密码”流程,否则不执行。
泛化关系(generalization)
- 本质:继承关系,子用例继承父用例的行为,并可扩展或覆盖父用例的功能。
- 箭头方向:从子用例指向父用例(实线空心三角箭头)。
- 示例:
- 父用例:"支付"
- 子用例:"支付宝支付"、"信用卡支付"
- 解释:不同支付方式是“支付”的具体实现,继承支付的共性(如输入金额)。
题型题库
综合知识
案例分析
动态规划:
- 0-1背包问题: 时间复杂度和空间复杂度都是O(NW), N是物品数量,W是背包容量
- 最长公共序列
- 矩阵连乘: 时间复杂度是O(n^3), 空间复杂度是O(n^2)
甘特图:
-
并行;
-
任务所需时间分明;
-
不能看出任务之间的依赖关系
-
容易识别出关键的子任务
原型模型: 小规模
螺旋模型: 大规模+风险评估
瀑布模型
归并排序的递归式: T(n) = 2T (n/2) +O(n)
- 工厂单例建原型: 创建型模式, 工厂方法 (创建型类)
- 世代外接享组合: 结构性模式, 适配器模式 特殊: 既是结构型对象模式 ,也是结构型类模式
- 剩下的(其他的)都是行为型模式共11个 . 模板方法模式 (行为型类模式),解释器模式 (行为型类模式)
根据频率构建哈夫曼树,需要先排序
段页式存储,段号最多+页号最大+页内地址(具体,比如8K)组成
主动攻击
- 拒绝服务攻击
- 分布式拒绝服务(DDos)
- 信息篡改
- 资源使用
- 欺骗
- 伪装
- 重放
被动共计
- 流量分析
- 窃听/监听
- 嗅探
- 端口扫描
- 会话拦截/截获
二分查找
- 分支思想
- 时间复杂度 O(nlgn)
- 必须有序
- 查找成功和失败的平均查找长度不一样
风险管理
- 承认风险是客观存在的
- 风险不可能完全消除
- 风险管理应该贯穿整个项目
- 风险计划本身可能带来新的风险
- 不可能同时管理所有风险
- 风险是可以预测的,但是不能完全消除
- 风险是可以控制的
数据流图应该遵循 自上而下, 从抽象到具体. 可以回忆父图和子图的关系
对于n个数, 最坏情况下, 时间复杂度最低的是归并排序,而不是快速排序...
文档撰写:
- 测试分析报告在测试阶段编写
- 测试计划在需求分析阶段编写
- 需求规格书在需求分析阶段编写
- 概要设计说明书是在设计阶段编写
Python中的元组是不可变,有序,可以重复的. 可以理解成Java中的数组
数字证书进行身份认证,数字签名确保消息不可否认
软件详细设计阶段
- 对模块内的数据结构进行设计
- 对数据库进行物理设计
- 对每个模块进行详细的算法设计
- 代码设计、输入/输出设计、用户界面设计
概要设计阶段
软件系统总体结构设计
- 将系统划分为模块
- 确定每个模块的功能
- 确定模块之间的调用关系
- 确定模块之间的接口,即模块之间传递的信息
- 评价模块结构的质量
数据结构及数据库设计
流水线建立时间:第1条指令执行时间。
下午题特别注意
Java
- 特别注意,抽象类中的抽象方法, 千万别忘记abstract修饰词
线性表
顺序表
基于数组的数据结构实现
- 可以访问任意下标元素, 通过下标
- 插入和删除都需要移动元素,O(n)
链表
- 空间与表长成正比
- 插入和删除不需要移动元素, 修改相邻节点的指针即可.O(1)
- 无需预估存储空间的大小
单链表
双链表
循环链表
统一模型的四个阶段
- 起始:初步认识需求的范围,不细化.还没开始开发,相当于需求第一次评审会,留个印象,让大家明白这次需要大概要做个啥东西. 不需要细化
- 精化:核心需求分析,细化需求分析,技术可行性分析,架构演进找到合适的技术架构实现需求
- 构建:进入开发编码阶段,开始落地实现
- 移交:部署,系统测试,用户培训等开发完成后的事情收起
汇编语言
- 汇编程序不能直接被机器执行.计算机只能执行机器语言. 汇编语言也需要编译
- 汇编语言是低级的程序设计语言,使用与机器直接相关的指令集
- 与计算机体系紧密相关
最优解
- 贪心算法: 分数(部分)背包
- 动态规划: 0-1背包/最长公共子序列
- 暴力搜索: 旅行商
PERT ≠ 甘特图
- 能干啥
- 能看出每个任务的开始+结束时间
- 能看出子任务的衔接情况
- 能识别出关键子任务
- 不能干啥
- 不能直接反映项目的实际进度
甘特图
- 是一种项目进度管理工具
- 能看出每个子任务持续的时间
- 能看出项目的实际进度
- 看不出每个任务的衔接关系
系统总线
- 用于连接主存和外设
UML状态图 转换由事件触发,状态由转换改变
事件---触发--->转换---改变--->状态
入侵检测技术包括专家系统、模型检测、简单匹配;漏洞扫描不是入侵检测的内容。
配置管理包括:软件配置标识、变更管理、版本控制、系统建立、配置审核和配置状态报告
结构化开发方法,特别适合于数据处理领域的问题,但是不适合解决大规模的、特别复杂的项目,而且难以适应需求的变化
中间代码有后缀式、三元式、 四元式和树(图)等形式
过载多态是同一个名字在不同的上下文中所代表的含义
包含多态在许多语言中都存在,最常见的例子就是子类泛型化
序列图、通信图、交互概览图和时序图均被称为交互图
UML中有4种事物:
- 结构事物
- 是UML 模型中的名词,它们通常是模型的静态部分,描述概念或物理元素。结构事物包括类 (class)、接口(interface)、协作(collaboration)、主动类(activeclass)、构件(component)、制品(artifact)和结点(node)
- 行为事物
- 是UML模型的动态部分,它们是模型中的动词,描述了跨越时间和空间的行为。行为事物包括:交互(interaction)、 状态机(state machine)和活动(activity)。
- 分组事物是UML模型的组织部分,是一些由模型分解成的“盒子”。在所有的分组事物中最主要的分组事物是包(package)
- 注释事物是UML模型的解释部分。这些注释事物用来描述、说明和标注模型的任何元素。注解(note)是一种主要的注释事物。注解是一个依附于一个元素或者一组元素之上,对它进行约束或解释的简单符号
90H转二进制等于多少, 1位16禁止用4位2进制表示, 9 = 8+1, 9=1001,所以90H = 1001 0000 B,符号位是1,所以这个数表示负数
对于一个二叉树
- 第h层, 最多有2^h-1个节点
- n <= 2^h-1
具有n个结点的二叉树有 (2n)!/( (n+1)! * n! )
吴书记控制外部公共内容
常见的二叉树
进程与资源: 死锁
软件工程的基本要素包括方法、工具和过程
电梯调度算法与单向扫描算法
0.01 = 2^-2
n=3时,表示的最大定点小数=0.11B = (1-0.01)B = (1-2^-(3-1)), -(3-1)次方表示是一个定点小数
得到的教训: 题目可能存在陷进, 选择最符合场景的情况, 不要局限于片面
反复3 易混淆
路径覆盖
Python基础
基础语法
多行语句
反斜杠\用来连接多行代码
>>>str = "Hello" + \
" World"
>>>print(str)
Hello World
注释
-
单行注释, 用#表示
#这是一个单行注释
-
多行注释,用3个单引号或者双引号表示
-
```3个单引号 表示的多行注释 ```
-
"""3个双引号 表示的多行注释 """
-
同一行显示多条语句
>>> x=123;y=z=1
>>> x
123
>>> y
1
多个语句构成代码组
if True: #结尾的冒号不能省略
print('true')
elif 2>1: # 特别注意,是elif,不是elseif
print('2>1')
else :
print('else')
五个标准的数据类型
String(字符串)
str1 = "abc" #,str2 定义多个字符串的时候,第一个字符串后直接跟逗号定义另一个字符串,在Python 3.11.2中,会报错.这里的#表示注释
str1 = str2 = 'abc'
str1 = """3a""";str2 = """3b"""
str = '''3a'''
[头下标:尾下标]
特别注意,包头不包尾
>>> str="""12345"""
>>> str[1:2]
'2'
>>> str[2:4]
'34'
Numbers(数字)
var1=var2=100
List(列表)
>>> list=['a','b','c','d']
>>> list[0] # 输出列表的第一个元素
'a'
>>> list[1:3] # 输出第二个至第三个元素
['b', 'c']
>>> list*2 #输出列表两次
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
>>> arr=[1,2,3]
>>> list+arr # 两个列表拼接在一起行成1个新的列表
['a', 'b', 'c', 'd', 1, 2, 3]
>>> list[2:] #输出从第3个元素开始的所有元素
['c', 'd']
Tuple(元组)
元组类似于列表,但是,元组不能二次赋值,相当于只读表
Dictionary(字典)
常用函数
北派经方学术
我个人是恨死了一位人称:天医星的叶天士, 由于此人是清朝明医, 再加上后来的吴鞠通加了一点油就出现温病派, 写了温病条辨一书, 也因此二人从此误导了中国人研习中医的领域
汉唐中医节选
内容来源于汉唐中医, 以及我的读后感总结行成
AIDS
总结: AIDS症状为阳明热症, 按照中医里论, 阳明无死症
如何保养自己
倪师经典比喻: 如同吃完饭要清洗碗快一样重要, 每天固定勤擦拭, 必然不生病
- 每天早上起床时, 足尚未踏地, 就先服用昨晚睡前准备好的六味地黄丸30粒, 并且使用事先备好的凉开水里面加一点盐
- 六味地黄丸号是相传两千年的丸剂, 但是一般世面上卖的都是用六味药等量来制作, 这是不正确的
- 每天晚睡前服用一些疏肝解毒的中药
- 我们接触的环境已经受到极高的污染
- 食物的种类太多, 很难去分辨其是否有受到污染
- 外面餐厅用膳, 也不知道他们加入多少味精或食物已经储存多久
- 中医认为大肠与肺为表里, 是故大肠有燥矢屯积, 则浊气必然反逆入肺
- 不但造成口臭
- 更且使皮肤变坏且粗造
- 长期服用六味地黄丸或是一些疏肝解毒中药的人是不会便秘的
- 请买些猪肥肉回来, 自己榨取些猪油来做饭菜
- 饥饿与过饱
- 就是时常保持一点点饿的状态远比时常胃肠胀满的状况要健康好多, 而且也不容易变老, 又长寿, 又不生病, 所以如果是上班足应该一天两餐就够了
总结:
- 每天早上吃六味地黄丸, 水中加入少量盐(青盐或者海盐, 盐味咸, 咸味入肾)这是为了养肾;丸药,药缓力专
- 每天晚上吃点疏肝解毒的药品, 帮助肝脏解毒; 现代人生活压力大, 疏肝解郁可以让身体舒适,防止长久肝气郁结导致的疾病
- 少吃沙拉油, 会导致心血管疾病
- 我国吃猪油有上千年的历史验证, 已经造就出许多百岁人瑞. 有条件吃猪油
- 吃饭不要吃过饱,7~8分饱. 给身体减压, 减轻脏腑的负担
药罐子的中国人
- 高血压的药物控制
- 几乎所有降血压的药都是利尿剂, 会让你的肾功能下降, 而中医认为肾主骨, 其华在发, 开窍在耳, 司记忆, 主先天(寿命多长) , 这就是现在人们会得到骨质疏松症, 老人痴呆症, 掉头发, 听力减退, 寿命变短的原因, 性功能同时下降
- 更且因为西药都是属酸性, 而酸性会破坏血管壁组织, 容易造成血管破裂, 也就是说服用高血压药物的病患将更容易得到中风与心脏病, 不吃的病患反而不会得到这类疾病
- 血糖过高的病人
- 所有的西药都伤害肾脏, 因此服用降血糖的药越多就越容易得到心脏病.
- 中医认为只要肝脏好就不会有眼疾, 根本与高血糖无关, 由于服用西药或注射胰岛素会造成肝脏的损坏因此才会得到青光眼
- 血糖根本没有消失, 多余的血糖就开始屯积在你的脚部, 就好像糖积在杯底一样, 其结果就是双足溃烂, 你等着截肢吧
- 中药都是纯碱性, 在纯碱性的环境里是没有细菌与病毒的, 我们根本没有任何中药会让血糖上升的
- 胆固醇过高的人
- 我在临床上只是让病人停止吃零食三星期, 病人的胆固醇就降下200以上
- 三酸甘油脂过高的人
- 此类问题是因为吃油炸食物过多及过胖造成的
- 我开一些清肝的药给病人,三酸甘油脂就下降了, 因为肝是心之母, 一但肝脏代谢毒素功能下降, 自然有不干净的血进入心脏, 对心脏造成威胁, 从而引发心脏病
- 吃西方多种滋补营养药物的人---这类人是最无知而且愚昧的蠢蛋
- 从未有任何证据显示钙片可以帮助增强人体骨骼, 反而是吃多钙片会使骨骼更脆更容易造成骨质疏松症, 而且副作用是造成肾结石,而维他命C片更烂
- 妇女们服用它的目的是想皮肤美白, 但是结果是多服维他命C片会支援乳癌细胞的成长
- 我们应该多食用天然食物, 有机蔬果绝对是正确的
- 要美白多喝自然的橘子汁最好
- 服用阿斯匹林的人
- 有许多证据显示每天一片阿斯匹林你会有超过85%的机会得到胰脏癌, 因为它是一种强酸剂. 酸性对人体破坏最大
- 碱性体质最好, 不但长寿而且完全没有病痛
- 要成为碱性体质非常简单, 立刻停止喝咖啡不吃甜食, 拒绝冰淇淋可乐, 完全断绝糖果饼干类的零食, 多喝茶, 多吃自然有机蔬果
- 请记住在碱的环境里, 是没有病毒与细菌及癌细胞的
- 胃酸过高反逆食道的人
- 人工糖的颗粒极小, 会如同维他命片一样的喂食细菌及滤过性病毒, 它们吃了之后就排出酸性的粪便, 这就是胃酸的来源
- 服用女性贺尔蒙的太太们要注意
- 常被西医告知要服用贺尔蒙替代品, 否则会得到骨质疏松症, 这些胡说八道的话不知吓傻了多少无知的妇女
- 多吃则会得到骨质疏松症及心脏病乳癌等疾病
- 我从未听说有女人因为更年期不适而死的, 但是我却见到许多女人因为吃女性贺尔蒙而死于心脏病或乳癌的
- 乳房稍有硬块就急着做切片的无知妇女
- 喜欢吃止痛药的人要注意
- 目前市面上所有的止痛药都会伤到肝脏肾脏与心脏的
- 只要肝心肾一受伤, 立刻就会便秘睡不好
- 日子久了就开始掉发, 眼睛视力变差, 体力衰退, 容易抽筋
- 西药营养剂维他命吃多了都会掉发伤肝的(维他命A更是头号肝脏杀手) , 更何况止痛药
- 现在最新的医学研究已经证明了吃止痛药会有中风的危险, 许多刚生完小孩的妇女因为吃止痛药而得到中风
- 常服抗生素的人, 妇女必然小便失禁,男人必然性无能及心脏受损
一些Common Sense
- 健康的人,如果不运动,就会生病。由此可之,生病的人不多运动,结果就是死
- 同气相求,病人绝对不可以孤单独处。当病人住到医院时,必然是跟同样类型的病人住在一起,每天都跟许多无助的眼神对看,想想病人怎么会好呢? 如果是跟家人与亲朋好友住在一起,大家**每天都嘻嘻哈哈的过日子**,许多健康的人在一起,其中只有一个生病的人,其开心气氛当然会影响到病人,让病人常常都忘记自己是病人时,病情就已经好转了
- 找一位住在你家附近的有良心的医师。找到一位好心医师,很关心病人的医师最重要,不需要千里迢迢的找名医治疗,因为这位医师住在你家附近,随时可以提供最关心最贴心你的服务,这点很重要
北派传统中医判断身体是否健康
- 一觉到天亮
- 胃口正常
- 每天早上起床第一件事情就是大便上厕所
- 一天五到七次小便,小便的量大, 颜色要淡黄
- 永远都是头面身体冷, 手脚温热
- 男人女人都有, 叫做早上的阳反应, 女人早上起来的时候, 乳房很敏感, 男人阴茎会勃起
所以你们吃了中药以后, 这六个症状都出来了,代表你的病完全好了. 如果你们吃了中药以后, 本来脚是冷的, 后来变成冰的,就中药无效的明证, 那你们不要再吃中药了,赶快另请高明
女孩子月经期间感冒
还有要记得女孩子在月经的时候得到感冒, 所有的处方都不能用,什么麻黄汤, 桂枝汤, 葛根汤都不能用, 只能用一剂药, 叫小柴胡汤. 因为月经来的时候, 月经往下走, 走到子宫的时候, 正好得到感冒, 感冒的病毒从你外表直接进到子宫,根本不停留于肌表, 这时候桂枝麻黄发不到, 只有用和解的方法, 小柴胡汤一剂下去, 感冒的滤过性病毒跟着你的月经小便一起排出去
感冒辩证诊治
小朋友一感冒, 喉咙痛, 葛根汤症
金枪不倒? 厦门男子勃起2周竟是肺癌作祟.
一个罕见的病例,提醒男性朋友要小心。大陆厦门一位32岁的健壮工人,因为阴茎连续勃起两周疼痛不堪而就医,最后发现是肺癌末期,住院40天后就离开人世。(阴茎部位是肝经所络,属于阴,强直就是实症,二者合并在一起,就是所谓阴实,金匮有云:阴实者死。 )
男性朋友要注意啰!阴茎异常勃起持续时间过长,可别沾沾自喜,小心恶性疾病上身。厦门一名32岁的码头工人,因为连续勃起两周,在小诊所找不出病因,最后因疼痛不堪,到大医院挂急诊,一检查才发现原来是肺癌惹祸。(第一: 西医发现又如何呢?只会死得更快而已,第二: 用中医的五行学说做诊断,就可以了解是金克木,金就是肺。也就是说不做检查就可以知道。 )
肺癌判断
- 第一: 病人于寅时必自动醒来,无法安睡
- 第二: 背后第三椎下有压痛点
- 第三: 耳中肺点必有压痛,而且在同侧,等等这些都是经方家用来确诊是否有肺癌的问题
经方家的保健食品
醒世篇
我写此篇的目的, 是希望有缘读到此篇的读者, 一旦在面临生死决择时, 有多一个想法考虑, 如果因为此篇实际临床案例里的经验而救人一命, 也不枉我一番救世之心, 我将我所亲身经历的医案记录下来, 包含我内心的真实看法, 以及我面临病人为做生死决择时的天人交战的心情. 隐瞒病人名字是尊重个人隐私权, 事实上我的这些病人因为曾经都面对过一次死亡, 现在能够存活下来,他们根本已经不在乎任何事了, 他们连命都敢放在我的手中, 我怎么做或公布姓名他们也决不会反对, 但是尊重隐私权不单是法律更是我的医德, 我将隐瞒病人姓名, 使用代名, 希望读者理解 .
任何有志学习中医的青年才俊请记得, 要成为真正优秀中医不难, 必须精研黄帝内经做为诊断学及病理学的基础, 熟谙伤寒论及金匮的方义, 深研难经中的针灸理论, 多看明朝杨继洲的针灸大成, 犹记今年初收到一本中医学杂志来自美国新英格兰中医学校,它的封面就是一支针的针柄上放置艾草燃烧, 这是传统中医的大忌, 读过针灸大成都知道里面有一篇禁针歌诀写到---针而勿灸灸勿针, 针经为此常叮咛, 庸医针灸一起施, 徒施患者炮烙刑. 自古以来针灸并施一直是禁忌, 这杂志的封面却放上此自以为高明又花俏却不知道让明眼的传统中医一看就知此学校误导美国人的研究中医的心意, 这些人自称为传统中医, 实际上是既非正统中医又非正统西医出身, 嘴上又号称是传统中医, 既误了他人子弟又误导中医学入岐途, 这不是害人是什么? 我一定要告诉群众真正传统中医是什么, 以免大众被误导, 综观我国二十四史,文死谏, 武死战, 古代名臣皆敢冒着被皇帝杀头的生命危险, 直言相劝,务必使皇帝改变想法, 其结果都受到皇帝褒扬的, 我不再乎个人荣辱, 我一定要告诉世界上的无辜人民实话, 真正传统优秀的中医, 只用针与灸及中药的丸,散,膏,丹, 绝对没有用什么电针,雷射针灸,注射针灸之类, 有些更恶劣的中医为求达到效果, 还在中药里加入西药的安眠药及类固醇, 这些都是一些看不好病的中医用来蒙蔽世人的骗术, 害了病人还不算, 甚至还在教学时又误人子弟,真是可悲又可叹.
我写此篇的目的是要解开世人对中医的一大疑问, 就是到底正统优质中医可以治病治到什么程度? 我给大家下个定义,真正的正统中医,不但可以掌握一开始从诊断到治疗到自然恢复健康的全部过程, 并且可以知道如何预防同样的病再次发生.你如果是开业中医, 当你读到这篇时, 照理说你应该很兴奋有如此的医术可以救许多本来不用死的病人才对, 我相信你也可以做到而且甚至比我高明, 只是苦无发表机会, 但是你如果感觉是相反的, 变得很生气, 还要想办法打击我, 是没用的, 因为你根本不是人, 是连乌鸦都不如的蠢蛋, 我为什么如此说呢? 请想想世上有多少人受难于病痛中, 他们本来可以不用死的, 但是因为你从中阻扰, 你无法做到我能做到的, 于是病人冤死在你手上, 你可能不心疼, 因为他只是你的客人, 如果他是你的亲人如父母兄弟妻子等, 也因为你妒忌我而不转诊, 结果也冤死在不应该死的病上, 你仍不知悔改, 仍旧气我, 不气你自己不争气, 不好好多读书加强自己的能力, 不怪自己是学到用时方恨少, 连乌鸦都知道反哺之恩,你都不会, 居然会为了你自己的面子着想, 而眼睁睁的看着你的亲人含冤死去, ,你说你还是人吗?可能你是中医学校的教授, 你的口袋中仍然放着西医的降血压药与降血糖药, 而你口中却在说哪些中药可以降血压哪些可以降血糖,你如果以为你的医术不行别人不知道, 你完全错了, 病人吃了你的药心理很清楚的, 只是没有说出来, 他们只是因为不了解中医到底能够做多少, 有一天他们会知道的, 因为我会不断的写案例, 让世人知道, 总有一日大家会了解的.
我时常因为病人来访, 而中断撰写, 请读者见谅, 我实在忙坏了. 最近我加快速度要完成英文版的伤寒论及金匮, 我尽量赶, 只要ㄧ有时间我就会继续写完它的.
总结:
- 必须精研黄帝内经做为诊断学及病理学的基础
- 熟谙伤寒论及金匮的方义
- 深研难经中的针灸理论.多看明朝杨继洲的针灸大成
禽流感与流感(民众不用惊慌.)
本文转载于 汉唐中医-流行性疾病讨论区-禽流感与流感(10/17/2005)
由于感冒是日常最普遍的疾病,所以单独罗列出来,作为参考
第一:桂枝汤症---病人出现有汗,怕风吹,头痛,有点发烧,肌肉有些酸痛时,就可以服用它,如有咳嗽气喘时加些厚朴杏仁就可以了.
第二:麻黄汤症---病人出现极度怕冷,发烧,身体疼痛,完全无汗时,请立刻服用它.
第三:葛根汤症---中医的寒温之争在此,温病派认为伤寒家没有治温病方,所以只有他们的寒凉药物才可以治温病,这是因为他们没有读通伤寒论导致的,而葛根汤就是经方中治疗温病的处方,病人出现项强,头痛,发热,有汗或是无汗都可以,喉咙痛时,就可以立刻服用它,尤其小孩子几乎都是葛根汤症,因为小孩好动成性,在身体出汗发热时得到的感冒,因此就出现病得自温热,这就是葛根汤症了.
第四: 麻杏甘石汤症---病人咳嗽不止,痰出黄粘,胃口尚好时,可以吃此方.
第五:大青龙汤症---病人出现怕冷,无汗,发烧,咳嗽重,咳出黄痰,身体痛,口渴重,喜喝冷水,没有胃口时,就吃大青龙汤,这就是SARS与禽流感的主要症状.
第六: 小青龙汤症---病人有怕冷,无汗,发烧,咳嗽重,出白痰,无渴,身体痛,没有胃口时,就可以用它了.
第七:小柴胡汤症---病人忽冷忽热,加上呕心,胸胁苦满时,请服用此方,还有女子月经期来时正好得到感冒,就喝此药,如有咳嗽气喘时加些厚朴杏仁就可以了.
第八: 大柴胡汤症---如果病人出现便秘,又有忽冷忽热,胸胁苦满,兼有发烧此时请用大柴胡汤.
原文如下:
禽流感与流感(10/17/2005)
这波禽流感已经被西药厂利用来威胁民众的生命,其目的就是想赚大钱,但是使用的手段非常之恶劣,吃像非常难看,我有必要跟民众说清楚讲明白,以解除民众的忧心与疑虑,请大家安心愉快的过日子,我先归类西药厂最惯用的手段给大家看.
首先他们在事前先使用毫无根据的数据,夸大死亡人数,其目的第一是要民众开始害怕,如果卫生署不理会西药厂时,民众就会怪政府,然后政府只好向西药厂屈服,去购买根本没用的疫苗与抗病毒的药,第二是当感染期过了,如果很少人死于流感,他们就说是疫苗有效,是抗病毒药物有效,如果还是死很多人,他们就会说是执行不当或是有别的感染源或是新变种病毒造成疫苗无效的,所以总之与他们是无关,反正好坏都是他们在自导自演中,民众是永远被隐瞒在鼓里,而他们也知道民众在事后是不会关心的,大家只在乎自己没有死,这就是他们最了解的人性弱点,因此他们一直在骗人而无人去揭穿他们.这是个世纪大骗局,目前正在上演中,中医认为百病风之始,感冒当然是问题,但是中医老早在二千前年以前已经将此问题解决了,但是中国人却不知道,居然还听信外国人的骗局,真是祸国殃民的大骗局. 这些专门以威胁手段来欺骗海峡两岸中国人的西药厂,都将名列我的黑名单中,他们将是我第一个要消灭的目标,我看看谁敢威胁我们中国人,非修理他们不可,哪天这些人得到时癌症落到我的手上,他们就知道厉害了,这次简直把我气炸了,赶快吃点中药消消火气去.
亲爱的海峡两岸台湾与大陆民众们,大家不要惊慌,这一波的流行性感冒因为西药厂的利益介入,已经造成民众的恐慌,由于民众是无知与无辜的,所以有必要替民众解决这种疑虑恐慌,我国自古以来就有流感,汉朝医圣张仲景就是因为流感造成整个张氏家族损失三分之二的人口,因而他辞去南阳太守的职务,发奋图强研究医学,于是写下了名垂千古的伤寒杂病论就是经方,我使用经方至今从感冒到癌症,一一好转,尤其是治感冒时常都是一剂就好转,千年以来经方一直都是如此之快,孰知今日出现个西药厂,它们不断的制造疾病,不断的为打击人体抵抗力而不遗余力,因为只有当人体的抵抗力变差后才会生病,才会容易感冒,这样他们才有钱赚,他们希望全世界的人通通都生病,他们才高兴,所以他们一直鼓励西医使用各种抗生素与止痛药,打各种害人的疫苗,建议民众多吃害人的维他命,于是多年以后民众身体就越来越差了,不但很容易得到感冒,因为民众的免疫系统已经被西药破坏尽了,更且会只因为得到小感冒就出人命,这是个天大的笑话,为了全民福祉着想,我誓言一定要终结西药厂,让我们的下一代生活的健康快乐,永远免除来自疾病的威胁,现代人类最严重的癌症是来自西药厂不是来自人体,不清除它,民众将永远没有平安的日子可过,永远生活在这阴影威胁之下的.
现在由汉唐中医为民众解决这问题吧,民众只要记住以下很简单的辨症法,然后依照这法则选用药物,而这些药物都是台湾与中国大陆的国家卫生署自己核准的药物,但是因为他们都是西医所以他们不会用,因此这药是由不懂得使用的人来核准的,现在请大家一起跟我进入经方的世界.
第一:桂枝汤症---病人出现有汗,怕风吹,头痛,有点发烧,肌肉有些酸痛时,就可以服用它,如有咳嗽气喘时加些厚朴杏仁就可以了.
第二:麻黄汤症---病人出现极度怕冷,发烧,身体疼痛,完全无汗时,请立刻服用它.
第三:葛根汤症---中医的寒温之争在此,温病派认为伤寒家没有治温病方,所以只有他们的寒凉药物才可以治温病,这是因为他们没有读通伤寒论导致的,而葛根汤就是经方中治疗温病的处方,病人出现项强,头痛,发热,有汗(更正一点:或是无汗都可以,我忽略掉这一点了),喉咙痛时,就可以立刻服用它,尤其小孩子几乎都是葛根汤症,因为小孩好动成性,在身体出汗发热时得到的感冒,因此就出现病得自温热,这就是葛根汤症了.
第四: 麻杏甘石汤症---病人咳嗽不止,痰出黄粘,胃口尚好时,可以吃此方.
第五:大青龙汤症---病人出现怕冷,无汗,发烧,咳嗽重,咳出黄痰,身体痛,口渴重,喜喝冷水,没有胃口时,就吃大青龙汤,这就是
SARS与禽流感的主要症状.
第六: 小青龙汤症---病人有怕冷,无汗,发烧,咳嗽重,出白痰,无渴,身体痛,没有胃口时,就可以用它了.
第七:小柴胡汤症---病人忽冷忽热,加上呕心,胸胁苦满时,请服用此方,还有女子月经期来时正好得到感冒,就喝此药,如有咳嗽气喘时加些厚朴杏仁就可以了.
第八: 大柴胡汤症---如果病人出现便秘,又有忽冷忽热,胸胁苦满时,兼有发烧此时请用大柴胡汤.
以上八个经方是我国使用近二千年之有效处方治疗感冒,处方至今从未变更过,时常都是一剂知,二剂已的,民众只需按照上面所陈述的症状,就可以自行判定你自己或是亲人需要吃什么药了,保证当天就好了,不需要经过医师处方,反正他们也不会用,你去问他们也是白问,现在只能自求多福了,因为你们的卫生署不知道他们自己已经核准的科学中药如此之好,所以他们不知道如何教导民众,因此只好由我来代劳了,如果民众按照我的指示吃药仍然没好,请传真给我, 1 -321-454-9974 ,我一定替你治疗的,感冒会死人吗??? 真是让人笑掉大牙的事.传真时请说明你的症状,发烧?体痛?胃口?有无口渴?喜欢喝热水还是冷水?有无出汗?怕冷?怕热?有无咳嗽?咳出清痰还是黄痰?有无便秘? 读者只要说明清楚发病症状及病人体格大小等资料,并且请附上回传号码,我将立刻回传处方给你,你们自行去中药行买药就可以了,完全免费服务,我保证将你救回来的,但是你如果是因为笨,因注射疫苗之后才发生的感冒,恕我不治,因为你实在太笨了,少些笨蛋,政府就少些开销的.
如何证明上面的中药绝对有用呢? 很简单,读者请买一些上面我说的药与克流感西药,然后去公园或是养鸡场,将中药与西药洒在地上,读者就会看到这些禽类将选择中药吃,绝对没有一只笨鸡或是笨鸟会去选择西药克流感吃的,这就是Mother Nature,就好像是当你家的猫或狗有病时,它们会去吃草,自己去找寻能够治病的药物,绝对不会去吃西药的,除非动物医师硬注射西药入体内,否则它们绝对不吃西药的,读者也可以将这两种药放在餐桌上过一夜,第二天早上你就会发现你家的蟑螂只吃中药,没有一只笨蟑螂会去吃克流感的,这就是蟑螂可以生存在地球十亿年以上而不被毁灭的真正原因,因为它们比人类聪明太多了,连他们都知道如何做选择.
给疾病管制局的建议,请你们去购买桂枝汤与大青龙汤,将它们分开做两堆,置于户外,当你们看到有鸟类来吃大青龙汤时,这些就是被感染到禽流感的鸟,去吃桂枝汤的鸟就是没有得到禽流感的,此法也可以用在养鸡场,禽类吃了大青龙汤之后会排粪便出来,此时你们就可以去取些样本来化验,就知道我对否? 根本不需要赶尽杀绝的,这是削足适履的行为.
大青龙汤处方如下: 麻黄三钱杏仁五钱石膏八钱炙甘草五钱桂枝五钱生姜二片红枣十二枚打碎(有做过心脏手术的病人不可以用麻黄,请改用荆芥五钱,防风三钱,浮萍三钱来取代麻黄.)
用六碗水大火快煮成二碗,汤成后立刻关火,待温时空腹喝第一碗,如果一小时内汗出烧退咳止,就不须要喝第二碗,如果三小时内无出汗,就再喝第二碗,汗出时就不用再喝了,当身体出汗时须待静室中,等到出汗自然停止后,再出房间,切不可以出汗时吹到风,如此病毒将无法排尽,还会再发的. 成人每次一碗,小孩每次半碗,婴儿每次四分之一碗. 记住一旦汗出,就不用再喝第二碗了,因为已经好转了,再喝恐怕伤到津液. 一般病人在服药后第二天中午时会很饿,胃口大开,这表示正常了.
一般市面上的科学中药成药,大家也可以去买仙丰GMP厂制造的很好用,这点卫生署还做的不错. 如果有民众真正得到了禽流感,西药是肯定失效的,当此生死存亡之时如果医师的态度是宁可眼睁睁的看到病人死去,也不给病人一丝生存机会不让病人服用经方时,你告诉卫生署是没用的,他们官官相护,所以请知道的人写传真给我,我统一集中起来一起骂,并且将他们打入恶质医师的行列,我必将让这些恶质医师遗臭万年,永世不得翻身,反正真正恶医师都知道我是谁,我也不担心他们怎么对付我,因为我比他们还会治病,之所以会如此是因为他们一直在专门研究如何吓病人,这是他们专业所在,而我却是一直在研究如何治疗疾病,而这却是我的专业所在,所以只有我能威胁他们,他们无法威胁我的,他们生病时也只有我知道如何救他们,读者说他们遇到我时该怎么办呢?早就说过了,我是鬼见愁,只有心里有鬼的才会真正愁我,真有佛心之人怎会愁我呢?
此篇论文欢迎大家引用,济世救人是我辈职责所在,请大家告诉大家.但是要注明出处,谢谢.
美国汉唐中医倪海厦撰写于佛州
以下是经典方剂与现代中成药的对应关系:没有经过验证
-
桂枝汤: 现代中成药: 桂枝颗粒、桂枝合剂 功效: 解肌发表,调和营卫,用于外感风寒表虚证。
-
麻黄汤: 现代中成药: 麻黄碱片、感冒通片 功效: 发汗解表,宣肺平喘,用于外感风寒所致的咳嗽、气喘。
-
葛根汤: 现代中成药: 葛根解表颗粒、葛根汤颗粒 功效: 解肌退热,生津,用于外感风寒、项背强痛、无汗等症。
-
麻杏甘石汤: 现代中成药: 麻杏甘石合剂、清肺抑火丸 功效: 宣肺泄热,止咳平喘,用于肺热咳嗽、喘息等症。
-
大青龙汤: 现代中成药: 大青龙颗粒 功效: 发汗解表,清热除烦,用于外感风寒、内有郁热的症状。
-
小青龙汤: 现代中成药: 小青龙颗粒、小青龙口服液 功效: 解表散寒,温肺化饮,用于外感风寒,内有水饮的咳嗽、喘息。
-
小柴胡汤: 现代中成药: 小柴胡颗粒、小柴胡口服液 功效: 和解表里,用于少阳证,如寒热往来、胸胁苦满、心烦喜呕等。
-
大柴胡汤: 现代中成药: 大柴胡颗粒 功效: 和解少阳,内泻热结,用于少阳阳明合病,或肝胆热实,胃肠积滞等。
MySQL服务器常用操作
创建一个数据库
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
创建用户并授权
CREATE USER 'nextcloud_user'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud_user'@'%';
FLUSH PRIVILEGES;
注意事项
- 性能影响
utf8mb4_bin
因为逐字符比较和区分大小写,性能可能略低于utf8mb4_general_ci
。- 选择排序规则时需要在性能和功能之间权衡。
- 文件系统的影响
即使数据库支持大小写敏感排序,文件系统(如
ext4
、NTFS
)可能不区分大小写,这可能导致文件名冲突。
总结
- 默认选择:
utf8mb4_general_ci
,除非明确需要区分大小写。 - 如果需要大小写敏感,使用
utf8mb4_bin
。 - 区分大小写的需求较为少见,但在文件名敏感的场景中可能是必要的。
MySQL-常用语句记录
按照子表的id升序查询出子表字段去重并且逗号隔开
GROUP_CONCAT(DISTINCT column_name ORDER BY column_name SEPARATOR ',')
举例
-
b.xxx 的值不区分大小写 select a.*, GROUP_CONCAT(DISTINCT b.xxx ORDER BY b.id ASC SEPARATOR ',') as bxxx from order a left join detail b a.id= b.o_id group by a.id
-
b.xxx的值区分大小写 select a.*, GROUP_CONCAT(DISTINCT BINARY b.xxx ORDER BY b.id ASC SEPARATOR ',') as bxxx from order a left join detail b a.id= b.o_id group by a.id
count(1) count(*) 和 count(name)的区别
count(1)和count(*)
在 MySQL 中,COUNT(*) 和 COUNT(1) 通常是等价的,因为它们都用来计算表中的行数,并且在大多数情况下,它们的性能和结果是一样的,且性能差异微乎其微
SELECT COUNT(*) FROM table;
SELECT COUNT(1) FROM table;
count(name)
- 功能: 计算 name 列中非 NULL 的行数。如果 name 列包含 NULL 值,则这些 NULL 值不会被计入。
- 性能: 由于需要考虑 name 列的 NULL 值,因此在某些情况下,性能可能会略逊色于 COUNT(*),但差别通常不大。
总结: 在大多数情况下,COUNT() 和 COUNT(1) 在 MySQL 中表现一致,你可以使用它们中的任何一个来计算行数。不过,**COUNT() 通常是更直观和推荐的选择**。
数据同步差异排查
场景: 从A库同步一张表A1到B库的B1, A表总共30001,B表30000条.找出没有同步过去的那一条
方案是查询出A表的所有ID,然后把所有id UNION ALL,在进行两个表的关联
SELECT ids.id
FROM (
SELECT 1 as id
UNION ALL SELECT 43581
UNION ALL SELECT 43583
.... 假设中间还有n条
UNION ALL SELECT 43607
UNION ALL SELECT 43609
) AS ids
left join shop_new ds on ds.id = ids.id
where ds.id is null
;
通过叶子结点找到上级树
返回的结果包含blood_id = 23的数据行
用途是, 通过叶子节点找所有上级,然后封装成链表的形式,代码相对复杂.所以可以换一个思路,先通过以下SQL找到上级树.然后从parent_id集合中排除blood_id集合,得到first_prent_id集合,表示当前节点所在上级树的第一层节点的id集合
然后遍历first_prent_id集合,通过Java查询以下的SQL的结果集中, 父id为**first_prent_id.get(i)**的数据,则取到了当前节点的下一级节点列表.
WITH RECURSIVE ancestors AS (
SELECT id,blood_id,parent_id FROM blood_tree WHERE blood_id = 23
UNION
SELECT p.id,p.blood_id,p.parent_id FROM blood_tree p
JOIN ancestors a ON p.blood_id = a.parent_id
)
select * from ancestors;
解释:
-
CTE 表示递归表达式
-
WITH RECURSIVE ancestors AS (...)
定义了一个名为ancestors(可以自定义)
的递归 CTE -
表达的意思是:
- 以blood_id = 23的数据行row1为参考,查询所有
blood_id=row1.parent_id
的数据行rowM - 然后继续对rowM的每一行数据, 进行递归,查询
blood_id=rowM.parent_id
的所有数据行 - 最后将这些数据UNION在一起.得到关于某个叶子节点的上级树
- 以blood_id = 23的数据行row1为参考,查询所有
完整的Java代码如下:
private List<BloodNodeResVo> getParentBloods(Integer bloodId) {
List<BloodNodeResVo> treeList = new ArrayList<>();
List<PtBloodTree> bloodTreeList = ptBloodTreeService.getParentTreeByBloodId(bloodId);
if (CollectionUtils.isEmpty(bloodTreeList)) {
return treeList;
}
//包括每一层的父节点
Set<Integer> parentIds = bloodTreeList.stream().map(PtBloodTree::getParentId).collect(Collectors.toSet());
//包括每一层的子节点
Set<Integer> bloodIds = bloodTreeList.stream().map(PtBloodTree::getBloodId).collect(Collectors.toSet());
//所有节点.用于后期批量一次性查SQL.
Set<Integer> allBloodIds = new HashSet<>();
allBloodIds.addAll(parentIds);
allBloodIds.addAll(bloodIds);
//父节点中移除所有的叶子节点.因为第一层的节点不再有父节点.所以第一层的节点也就不存在于子节点中
parentIds.removeAll(bloodIds);
List<PtBloodIdx> ptBloodIdxes = listByIds(allBloodIds);
Map<Integer, PtBloodIdx> bloodIdxMap = Optional.ofNullable(ptBloodIdxes).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(PtBloodIdx::getId, Function.identity(), (k1, k2) -> k1));
//遍历第一层的节点
for (Integer parentId : parentIds) {
PtBloodIdx ptBloodIdx = bloodIdxMap.get(parentId);
BloodNodeResVo bloodNodeResVo = new BloodNodeResVo();
bloodNodeResVo.setBloodId(ptBloodIdx.getId());
bloodNodeResVo.setBloodName(ptBloodIdx.getBloodName());
bloodNodeResVo.setNumber(1);
treeList.add(bloodNodeResVo);
//获取子节点
getChild(bloodTreeList, bloodNodeResVo, bloodIdxMap);
}
return treeList;
}
void getChild(List<PtBloodTree> bloodTreeList, BloodNodeResVo parent, Map<Integer, PtBloodIdx> bloodIdxMap) {
bloodTreeList.stream().filter(p -> p.getParentId().equals(parent.getBloodId())).forEach(p -> {
PtBloodIdx bloodIdx = bloodIdxMap.get(p.getBloodId());
BloodNodeResVo child = new BloodNodeResVo();
child.setBloodId(bloodIdx.getId());
child.setBloodName(bloodIdx.getBloodName());
parent.getChilds().add(child);
//递归调用子节点的子节点
getChild(bloodTreeList, child, bloodIdxMap);
});
}
通过父节点找到所有子下级树
返回的结果包含blood_id = 23的数据行
WITH RECURSIVE descendants AS (
SELECT blood_id,parent_id,blood_level FROM blood_tree WHERE blood_id = 23
UNION
SELECT p.blood_id,p.parent_id,p.blood_level FROM blood_tree p
JOIN descendants a ON p.parent_id = a.blood_id
)
select * from descendants;
Java基础-易错点
List.remove
注意有两个重载方法remove(int)和remove(Object), 很容易混淆
案例:
Map<String, Integer> unionMap = new HashMap<>();
for (int i = 0; i < insertList.size(); i++) {
CstGoods cstGoods = insertList.get(i);
String unionKey = String.join("_", cstGoods.getSpCode(), cstGoods.getCostType(), String.valueOf(cstGoods.getCostScene()), cstGoods.getBgDate().toString(), cstGoods.getEdDate().toString());
if (unionMap.containsKey(unionKey)) {
unionMap.put(unionKey, i);
//特别注意这一行
Integer index = unionMap.get(unionKey);
insertList.remove(index);
i--;
} else {
unionMap.put(unionKey, i);
}
}
本意是移除已经存在的列. 但是问题就出在list.remove. 如果remove方法的入参传入的是包装类型,自然就会执行remove(Object), 那么结果肯定是移除不了这个重复对象. 所以需要将Integer index = unionMap.get(unionKey);
改为 int index = unionMap.get(unionKey);
.要不然会导致死循环
修正后的代码
Map<String, Integer> unionMap = new HashMap<>();
for (int i = 0; i < insertList.size(); i++) {
CstGoods cstGoods = insertList.get(i);
String unionKey = String.join("_", cstGoods.getSpCode(), cstGoods.getCostType(), String.valueOf(cstGoods.getCostScene()), cstGoods.getBgDate().toString(), cstGoods.getEdDate().toString());
if (unionMap.containsKey(unionKey)) {
unionMap.put(unionKey, i);
//特别注意这一行
int index = unionMap.get(unionKey);
insertList.remove(index);
i--;
} else {
unionMap.put(unionKey, i);
}
}
Java 8 Stream API 之 removeIf
removeIf简化代码
- 移除所有负数
List<Integer> numbers = Arrays.asList(1, -2, 3, -4, 5);
numbers.removeIf(n -> n < 0);
// 结果: [1, 3, 5]
- 移除过期的订单
List<Order> orders = getOrders(); // 获取订单列表
orders.removeIf(order -> order.getExpiryDate().isBefore(LocalDate.now()));
// 移除所有过期的订单
- 移除名称重复的用户
List<UserDTO> users = getUsers();
if (CollectionUtils.isNotEmpty(users)) {
Set<String> uniqueNames = new HashSet<>();
users.removeIf(u -> !uniqueNames.add(u.getName()));
}
return users;
Java 8 Stream API 之 map
- map简化代码
//简化前
Map<Integer, PtBloodIdx> bloodIdxMap = listByIds(bloodIds).stream().collect(Collectors.toMap(PtBloodIdx::getId, Function.identity(), (k1, k2) -> k1));
for (PtBloodTree ptBloodTree : trees) {
Integer bloodId = ptBloodTree.getBloodId();
PtBloodIdx ptBloodIdx = bloodIdxMap.get(bloodId);
if (ptBloodIdx == null) {
continue;
}
ChildBloodTreeResVo res = new ChildBloodTreeResVo();
res.setId(ptBloodIdx.getId());
res.setBloodCode(ptBloodIdx.getBloodCode());
res.setBloodName(ptBloodIdx.getBloodName());
resList.add(res);
}
retrun resList;
//简化后
return trees.stream()
.map(tree -> bloodIdxMap.get(tree.getBloodId()))
.filter(Objects::nonNull)
.map(ptBloodIdx -> {
Integer bloodId = .getId();
List<BloodNodeResVo> parentBloods = getParentBloods(bloodId);
return ChildBloodTreeResVo.builder().id(bloodId).bloodCode(ptBloodIdx.getBloodCode()).bloodName(ptBloodIdx.getBloodName()).parentBloods(parentBloods).build();
})
.collect(Collectors.toList());
解释:
- 通过第一个.map直接从tree转换成了PtBloodIdx
- filter过滤后,只保留每一个不为null的对象
- 第二个map开始组装最终的结果里的每一个对象
小技巧
文件拆分
将一个文件按照1000行拆分成一个新文件
场景: 一个文件中存在1万个ID,数据库每次in的时候只能查询1000个, 于是需要1000个ID作为一次拆分
打开git bash, 执行以下命令
# 1000表示1千行作为一次拆分, 文件保存在abc目录下, 新文件的前缀是shop_1000_
split -l 1000 shopIds.groovy abc/shop_1000_
每100KB拆分成一个新文件
split -b 100k shopIds.groovy abc/shop_1000_
Git常用操作
还原至master
--mixed和--hard
git reset
右面可选{--mixed, --hard
}, 两者有本质的区别. --mixed
是默认的
操作 | git reset --hard origin/master | git reset --mixed origin/master |
---|---|---|
HEAD | 重置为 origin/master 指向的提交 | 重置为 origin/master 指向的提交 |
暂存区(staging area) | 重置为远程 origin/master 的状态,丢弃所有已暂存的更改 | 重置为远程 origin/master 的状态,丢弃所有已暂存的更改 |
工作目录(working directory) | 恢复为远程 origin/master 的状态,丢弃所有未提交的更改 | 保留本地修改,但将其恢复为“未暂存”状态,不会丢失工作目录中的更改 |
两者的相同点:
- 都是为了把未推送到远程的代码状态还原到和远程状态
- 执行好,新增的文件,会回退到未暂存的状态,不会被删除.
- 删除的话需要执行
git clean -fd
,谨慎操作.执行后,本地未推送到远程的代码将会彻底丢失-f
表示强制删除-d
表示删除未跟踪的目录
- 删除的话需要执行
两者的本质区别:
--mixed
是默认的, 操作比较柔和一点,还原后,项目的提交记录和远程保持一致了.但是本地已修改的代码不会丢弃.未推送到远程的代码代码还在本地,只是提交记录和远程保持一致了--hard
不是默认的,需要指定, 操作很强硬, 执行后, 本地的已修改未推送到远程的代码会彻底丢弃
阿里云-数据服务概述-学习笔记
以下内容,大量引用于 阿里云
DataWorks数据服务模块是一个灵活轻量、安全稳定的数据API构建平台
- API构建平台
- 已有的API注册至平台统一管理
- 注册生成API
相关概念
- API(Application Programming Interface , 应用程序编程接口):API是让应用、软件、系统能够面向数据源进行数据交互的接口,数据服务API支持“读数据”的操作,可以从数据库、数据表中不断地进行数据查询。
- 函数:作为API过滤器,对API的请求参数或返回参数进行加工处理。当使用函数作为API过滤器时,前置过滤器和后置过滤器的函数类型需要保持一致,暂不支持对同一API的前置和后置过滤器选择不同的函数类型。
API分组
API分组是指针对某一个功能或场景的API集合,也是API网关对API的最小管理单元。在阿里云API市场中,一个API分组对应于一个API商品。
一个业务流程下可以有多个API分组
- 您需要确保当前业务流程下,无文件夹、API、函数和服务编排等其它文件,才能够成功删除业务流程。
- 如果业务流程内存在其它文件,请您先删除所有的文件,再删除该业务流程。
数据服务错误代码表
错误代码 | 描述 | 语义 |
---|---|---|
0 | success | 数据查询及返回结果成功。 |
1108110583 | query timeout | 请求查询超时,API在数据服务和数据库中的整体执行时长超过了API环境配置中所设置的超时时间,导致请求超时。 |
1108110519 | param miss | 请求参数缺失,当API设置了必填的请求参数,但实际请求中存在必填参数未传参。 |
1108110584 | api context failed | 依赖第三方获取上下文失败,上下文信息包括:数据源连接信息、数据源AK信息、租户信息等。 |
1108110622 | datasource query error | 查询数据源失败,可能原因包括:SQL语法错误、数据源未在系统内置10s超时上限内返回执行结果、超过数据源连接数限制等。 |
1108110703 | database connection error | 数据源连接失败。 |
1108113002 | rate limit | API调用达到阈值上限,已被系统限流。目前API调用均使用公共服务资源组,公共服务资源组的阈值约为每租户200 QPS,超出该阈值将触发调用流量控制。 |
数据推送
将数据推送至Webhook
- 通过简单配置,实现定期将所需的业务数据推送至多个不同的Webhook
- 支持的推送渠道:钉钉群、飞书群、企业微信群以及Teams
数据推送服务使用限制
- 数据推送功能推送至不同对象时的数据大小限制:
- 推送目标为钉钉,推送数据大小不超过20KB。
- 推送目标为飞书,推送数据大小不超过20KB,图片小于10MB。
- 推送目标为企业微信,每个机器人发送的消息不能超过20条/分钟。
- 推送目标为Teams,推送大小不大于28KB。
功能分类 | 功能点 | 向导模式 | 脚本模式 |
---|---|---|---|
查询对象 | 单数据源、单数据表查询 | 支持 | 支持 |
单数据源、多数据表关联查询 | 不支持 | 支持 | |
查询条件 | 数值型等值查询 | 支持 | 支持 |
数值型范围查询 | 支持 | 支持 | |
字符型精确匹配 | 支持 | 支持 | |
字符型模糊匹配 | 支持 | 支持 | |
查询结果 | 字段值原样返回 | 支持 | 支持 |
字段值进行数学运算 | 不支持 | 支持 | |
字段值进行聚合函数运算 | 不支持 | 支持 | |
返回结果分页 | 支持 | 支持 | |
查询逻辑 | mybatis标签 | 不支持 | 支持 |
API安全
IP白名单
如100.64.0.0/10,11.193.102.0/24
生成API
参数 | 描述 |
---|---|
API模式 | 包括向导模式和脚本模式,此处选择向导模式。 |
API名称 | 支持中文、英文、数字、下划线(_),且只能以英文或中文开头,4~50个字符。 |
API Path | API存放的路径,即相对于服务host,API的请求路径。例如/user。说明支持英文、数字、下划线(_)和连字符(-),且只能以( /) 开头,不得超过200个字符。 |
协议 | 支持HTTP和HTTPS。如果您需要通过HTTPS协议调用API,请您发布API至网关后,在API网关控制台绑定独立域名,并上传SSL证书。详情请参见支持HTTPS。 |
请求方式 | 支持GET和POST。说明当请求方式选择GET时,请求参数位置仅支持选择QUERY。当请求方式选择POST时,请求参数位置支持选择QUERY和BODY。 |
返回类型 | 仅支持JSON返回类型。 |
可见范围 | 包括工作空间和私有:工作空间:该API对本工作空间内的所有成员可见。私有:该API仅对API的负责人可见,且暂不支持授权。说明如果设置可见范围为私有,在目录树中,仅自己可见,工作空间内的其他成员不可见。 |
标签 | 从标签列表中选择相应的标签,详情请参见创建及管理API标签。说明标签名称支持汉字、英文、数字和下划线(_),您最多可以设置5个标签,且每个标签不超过20个字符。 |
描述 | 对API进行简要描述,不得超过2000个字符。 |
目标文件夹 | 存放API的目录,可以在下拉列表选择已创建的业务流程,选定后,会生成API的存放路径。默认格式为:“业务流程/业务流程名称/API”,例如业务流程/ceshi/API。 |
后续会有一堆正则表达式, 建议用枚举管理起来
麻雀虽小,五脏俱全. 建议脏腑分明
配置过滤器
对入参和出参,进行二次加工
设置是否返回结果分页
在高级配置区域,设置是否返回结果分页。
- 如果不开启返回结果分页,则API默认最多返回2000条记录。
- 如果返回结果可能超过2000条,请开启返回结果分页功能,开启后,您可以进入右侧导航栏的服务资源组页面,根据资源组类型设置单页条数上限。
说明
当数据服务的API在编辑页面右侧导航栏的返回参数已经开启了返回结果分页,如果您在该API编辑页面的编写查询SQL区域,使用SQL语句配置了limit
限制(即返回结果的条数限制),则该limit
限制不生效,返回结果的条数限制仍然会以返回结果分页的配置内容为准。
开启返回结果分页后,会自动增加以下公共参数:
-
公共请求参数
- returnTotalNum:用于确定单次请求中是否要返回数据总条数。
- pageNum:当前页号。
- pageSize:页面大小,即每页记录数。
-
公共返回参数
- pageNum:当前页号。
- pageSize:页面大小,即每页记录数。
- totalNum:总记录数。
记录操作日志
什么时间,谁, 做了什么事情
通过条件控制返回结果按照不同的表字段进行排序
这块可以设计页面,按照设置的字段顺序排序. 页面支持切换顺序?????
- 当
var
的值为1时,使用order by col01
对结果进行排序。 - 当
var
的值为2时,使用order by col02
对结果进行排序。 - 当
var
的值为3时,使用order by col01,col02
对结果进行排序。 - 当
var
的值为4时,使用order by col02,col01
对结果进行排序。
注册API
入参
参数 | 描述 |
---|---|
API名称 | 支持中文、英文、数字、下划线(_),且只能以英文或中文开头,4~50个字符。 |
API Path | API存放的路径,例如/user。说明支持英文、数字、下划线(_)和连字符(-),且只能以( /) 开头,不得超过200个字符。 |
协议 | 支持HTTP、HTTPS协议。如果您需要通过HTTPS协议调用API,请您发布API至网关后,在API网关控制台绑定独立域名,并上传SSL证书。详情请参见支持HTTPS。 |
请求方式 | 支持GET、POST、PUT和DELETE。 |
返回类型 | 支持JSON和XML。 |
可见范围 | 包括工作空间和私有:工作空间:该API对本工作空间内的所有成员可见。私有:该API仅对API的负责人可见,且暂不支持授权。说明如果设置可见范围为私有,在目录树中,仅自己可见,工作空间内的其他成员不可见。 |
标签 | 从标签列表中选择相应的标签,详情请参见创建及管理API标签。说明标签名称支持汉字、英文、数字和下划线(_),您最多可以设置5个标签,且每个标签不超过20个字符。 |
描述 | 对API进行简要描述,不得超过2000个字符。 |
目标文件夹 | 存放API的目录。 |
出参
参数 | 描述 |
---|---|
后台服务Host | 待注册API服务的Host,以**http://或https://**开头,并且不包含Path。说明示例:假设您接口服务地址为http://xxx-cn-xxx.alicloudapi.com/user/info ,可取http://xxx-cn-xxx.alicloudapi.com 设为后台服务Host。具体的可根据您接口服务地址实际路径进行配置。 |
后台服务Path | 待注册API服务的Path,Path中支持参数,参数要放在**[]中,如/user/[userid]**。配置Path中的参数后,在注册API向导的第二步API参数配置环节,系统会自动在请求参数列表添加Path位置的参数。说明示例:假设您接口服务地址为http://xxx-cn-xxx.alicloudapi.com/user/info ,可将/user/info 设为后台服务Path。具体的可根据您接口服务地址实际路径进行配置。 |
后端超时 | 设置后端超时时间。 |
需要接口请求链路,查看接口详情
API请求统计: ES
Aviator函数和正则表达式 适用场景对比
场景 | 正则表达式 | Aviator |
---|---|---|
简单的字符串匹配和验证 | ✔️ 非常适合 | ❌ 过于复杂,不推荐使用 |
动态规则修改 | ❌ 不支持 | ✔️ 支持动态加载规则 |
多条件逻辑 | ❌ 难以实现,表达式冗长且复杂 | ✔️ 支持多条件逻辑 |
规则与代码分离 | ❌ 不支持 | ✔️ 规则可以存储在外部配置 |
可读性要求高 | ❌ 正则表达式难以理解 | ✔️ 表达式更易于理解 |
扩展性要求高 | ❌ 仅限于正则的能力 | ✔️ 支持复杂逻辑、动态函数调用 |
大数据与实时分析
Flink_CDC同步MySQL到StarRocks初体验
安装flink
建议搭建初期, 使用官网提供的flink cdc sql在sql-client.sh中测试,根据错误提示添加对应的包
mkdir -p /app
wget https://archive.apache.org/dist/flink/flink-1.19.1/flink-1.19.1-bin-scala_2.12.tgz
tar -zxvf flink-1.19.1-bin-scala_2.12.tgz
cd flink-1.19.1
echo "execution.checkpointing.interval: 3000" >> /app/flink-1.19.1/conf/config.yaml
cd /app/flink-1.19.1/lib
# flink 1.19推荐下载3.3.0 connector包,如果直接使用flink,不使用dinky,完全没问题
# 由于我这边使用的dinky是1.2.3版本,3.3.0 connector包不兼容. 所以使用测试通过的包,如下
wget https://repo1.maven.org/maven2/com/ververica/flink-sql-connector-mysql-cdc/2.1.0/flink-sql-connector-mysql-cdc-2.1.0.jar
chmod +rwxrwxrwx flink-sql-connector-mysql-cdc-2.1.0.jar
wget https://repo1.maven.org/maven2/com/starrocks/flink-connector-starrocks/1.2.10_flink-1.19/flink-connector-starrocks-1.2.10_flink-1.19.jar
chmod +rwxrwxrwx flink-connector-starrocks-1.2.10_flink-1.19.jar
wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.27/mysql-connector-java-8.0.27.jar
chmod +rwxrwxrwx mysql-connector-java-8.0.27.jar
# 至此, 依赖包齐活
# flink默认是localhost访问,如果要允许其他IP访问.
# 需要修改 bind-host: localhost,localhost改为0.0.0.0 多处需要修改
# 需要修改 rest下的address为0.0.0.0
# 启动flink,执行1次增加1个task slot, 可以多次执行
# 每次启动的task slot 可以在config/config.yaml文件中修改numberOfTaskSlots的值
/app/flink-1.19.1/bin/start-cluster.sh
# 至此,flink准备完毕
安装MySQL和starrocks
docker-compose.yml
version: '2.1'
services:
StarRocks:
image: starrocks/allin1-ubuntu:3.2.6
environment:
# 如果没有指定密码,启动后进入容器后,执行ALTER USER 'root' IDENTIFIED BY 'eishees4saez3kaepei3Yi8am2oonguG';进行修改也行
- STARROCKS_ROOT_PASSWORD=eishees4saez3kaepei3Yi8am2oonguG
ports:
- "8080:8080"
- "9030:9030"
MySQL:
image: debezium/example-mysql:1.1
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=fiesug4Oji0be1ohk6oyae3EomaNg8uc
- MYSQL_USER=mysqluser
- MYSQL_PASSWORD=Aix5Airohth1ma3oSh3meHiijei6Usah
安装并启动
docker-compose up -d
安装dinky
经过发现这个版本的镜像,重启后不会报错.相对稳定
docker run -itd --network=nginx_ngu_network \
--name dinky dinkydocker/dinky-standalone-server:1.1.0-flink1.18
dinky配置
docker exec -it dinky bash
cd extends/flink1.19
wget https://repo1.maven.org/maven2/com/starrocks/flink-connector-starrocks/1.2.10_flink-1.19/flink-connector-starrocks-1.2.10_flink-1.19.jar
# 此处用的版本和flink中引用的不一样.但是经过测试,是完全兼容的,可放心食用
wget https://repo1.maven.org/maven2/com/ververica/flink-sql-connector-mysql-cdc/2.4.1/flink-sql-connector-mysql-cdc-2.4.1.jar
# 至此, dinky中的jar包配置完成
# 退出容器
exit
# 重启dinky
docker restart dinky
访问dinky http://localhost:8888
用户名: admin 密码 :dinky123!@#
登录后尽快修改密码
dinky控制台配置单独安装的flink
新建任务并提交即可
任务示例
CREATE TABLE IF NOT EXISTS `orders1_src` (
`order_id` BIGINT NOT NULL,
`dt` DATE NULL,
`user_id` INT NULL,
`good_id` INT NULL,
PRIMARY KEY (`order_id`) NOT ENFORCED
)
with
(
'username' = 'root',
'password' = 'taedohlahsoow7ebiath6Iaf2uokagah',
'database-name' = 'tmp_test',
'table-name' = 'orders1',
'connector' = 'mysql-cdc',
'hostname' = '172.20.0.10',
'port' = '3306',
'server-time-zone' = 'Asia/Shanghai',
'debezium.poll.interval.ms' = '200', -- Binlog轮询间隔(200ms)
'scan.incremental.snapshot.chunk.size' = '1000', -- 减少快照分块大小
'heartbeat.interval' = '1s' -- 心跳间隔(保活连接) .默认为0.如果设为 0,可能因连接闲置被数据库服务器关闭
);
CREATE TABLE IF NOT EXISTS `orders1_sink` (
`order_id` BIGINT NOT NULL,
`dt` DATE NULL,
`user_id` INT NULL,
`good_id` INT NULL,
`good_name` STRING NULL,
PRIMARY KEY (`order_id`) NOT ENFORCED
)
with
(
'sink.max-retries' = '10',
'password' = 'kuutooP2Daeghezi0thieyej5quiFace',
'sink.properties.strip_outer_array' = 'true',
'load-url' = '10.0.0.2:8030',
'database-name' = 'quickstart',
'jdbc-url' = 'jdbc:mysql://10.0.0.2:9030',
'sink.properties.format' = 'json',
'username' = 'root',
'sink.buffer-flush.interval-ms' = '15000',
'connector' = 'starrocks',
'table-name' = 'orders1',
'sink.properties.format' = 'json',
'sink.properties.strip_outer_array' = 'true',
'sink.properties.partial_update' = 'true',
'sink.properties.columns' = 'order_id,dt,user_id,good_id',
-- 关键参数:控制写入频率
'sink.buffer-flush.interval-ms' = '1000', -- 1秒刷写一次
'sink.buffer-flush.max-rows' = '64000', -- 每批次最多64000行
'sink.properties.format' = 'json',
'sink.properties.strip_outer_array' = 'true'
);
insert into
orders1_sink (order_id, dt, user_id, good_id)
select
s.order_id,
s.dt,
s.user_id,
s.good_id
from
orders1_src s;
遇到的问题记录
1. dink提交任务,无异常,也没有执行成功
首选在dinky提交任务,因为直观简单. 如果遇到提交任务后,无异常,也没有执行成功的问题排查.在flink的sql-clent.sh中运行调试,会看到对应的错误日志
2. 如果选用的mysql镜像是mariadb:11.7.2,需要设置时区和binlog
-
设置时区+8
-
设置binlog
-
cd /etc/mysql/mariadb.conf.d cat > 61-binlog.cnf << 'EOF' [mysqld] # 启用二进制日志 log_bin = mysql-bin # 设置二进制日志格式为 ROW binlog_format = ROW # 设置服务器ID(主从复制需要) server_id = 1 EOF
-
退出容器,并且重启即可
docker restart mariadb
-
其他
停止所有的flink, 慎用
jps -l | grep -i flink | awk '{print $1}' | xargs kill -9
MySQL相关
-- 确认 binlog_format 已改为 ROW
SHOW VARIABLES LIKE 'binlog_format';
--是否开启binlog
SHOW VARIABLES LIKE 'log_bin';
-- 查看时区
SELECT @@global.time_zone, @@session.time_zone;
不要直接修改my.cnf , 从容器中在/etc/mysql看到my.cnf来自于my.cnf -> /etc/alternatives/my.cnf
配置在mariadb.conf.d
下新增或修改
Flink-CDC同步多表关联数据优化
场景9张表关联, 主表数据3万不到.其他表多次关联, 其他关联表数据很少. 但是9次关联之后,一次完整同步需要耗时30分钟
环境
StarRocks版本
SHOW VARIABLES LIKE '%version%';
Variable_name | Value | 说明 |
---|---|---|
version | 5.1.0 | 表示当前 StarRocks 的 SQL 语法兼容性 基于 MySQL 5.1.0 协议 |
version_comment | StarRocks version 2.5.10 | StarRocks 实际的数据库版本号 |
flink版本
flink --version
Version: 1.18.1
dinky版本
1.1.0
MySQL版本
|Variable_name|Value|
|-------------|-----|
|innodb_version|5.7.24|
|protocol_version|10|
|slave_type_conversions||
|version|10.2.21-MariaDB-log|
|version_comment|MariaDB Server|
|version_compile_machine|x86_64|
|version_compile_os|Linux|
|version_malloc_library|system|
|version_ssl_library|YaSSL 2.4.4|
|wsrep_patch_version|wsrep_25.23|
docker-compose部署调试环境