0%

文章字数:149,阅读全文大约需要1分钟

现象

使用dhtmlxgrid组件时发现进行刷新操作之后浏览器的Network疯狂增加条目,即一直在请求后端。

排查

  1. 通过请求定位到那个功能有问题
  2. 后端打断点,发现返回的数据数量和total的值不一致。
  3. 原因是我在后台做了数据过滤,但是没有重新给total赋值
  4. 组件发现数据不完整,于是重新请求。
  5. 因为后端代码的原因,再次请求也是不完整的。于是无限循环

文章字数:844,阅读全文大约需要3分钟

构建过程

  1. 编写dockerfile
1
2
FROM nginx
RUN echo 'hello world' > /usr/share/nginx/html/index.html
  • FROM基于那个镜像做的定制
  • RUN执行后面的命令,执行一次会生成一层镜像,避免镜像膨胀过大,多个命令可以用&&连接,而不是多个RUN

指令

  1. COPY
1
2
COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
  • [--chown=<user>:<group>]: 可选,更改复制到容器内文件的拥有者和所属组
  • <源路径>可以是文件或目录,也可以是通配符。需要满足gofilepath.Match规则
  • <目标路径>容器内的路径,不存在会自动创建
  1. ADD
  • 使用同COPY
  • 在源文件是tar压缩文件时使用,可以自动解压到目标目录
  • gzip,bzip2,xz压缩格式
  1. RUN
  • 两种使用格式

    1
    2
    RUN <命令行命令>
    RUN ["可执行文件", "参数1", "参数2"]
  • 多个命令一起执行

1
2
RUN <命令行命令> \
&& <命令行命令>
  1. CMD
  • 使用同RUN
  • 作用是指定容器启动后执行的cmd命令,可被启动时传入的cmd覆盖。作用即设置默认cmd命令
  • 多条cmd只有最后一条有用
  1. ENTRYPOINT
  • 多条只有最后一个有效
  • 可以使用--entrypoint覆盖
  • CMD一样,容器启动后的默认执行的,一般搭配CMD一起使用,组合成一条命令
1
2
3
4
FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参

这样运行时会执行

1
nginx -c /etc/nginx/nginx.conf

然后可以通过修改cmd达到参数变化的效果

1
docker run  nginx:test -c /etc/nginx/new.conf
  1. ENV
  • 定义环境变量
1
2
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
1
2
3
ENV NODE_VERSION 7.2.0
# 在命令中使用变量
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz"
  1. ARG
  • 效果和ENV类似,只是作用域不同。ARG设置的智能在dockerfile里有效果
  • 可以使用--build-arg <参数名>=<值>覆盖
  1. VOLUME
  • 用于定义默认挂载路径
  • 可以被-v覆盖
1
2
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
  1. EXPOSE
1
EXPOSE <端口1> [<端口2>...]
  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
  1. WORKDIR
  • 切换目录,切换之后命令会在新的目录下执行
  • 需要是存在的目录
  1. USER
  • 指定后续执行命令的用户和用户组(切换用户)
    1
    USER <用户名>[:<用户组>]
  1. HEALTHCHECK
1
2
3
4
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
  1. ONBUILD
  • 本次构建时不会执行,其他dockerfile使用FROM调用次dockerfile时会执行
1
ONBUILD <其它指令>
  1. LABEL
  • 添加元数据metadata
1
2
3
LABEL <key>=<value> <key>=<value> <key>=<value> ...
# 例如添加作者
LABEL org.opencontainers.image.authors="runoob"

文章字数:1482,阅读全文大约需要5分钟

基本概念

  1. 镜像Image: 相当于一个root文件系统。
  2. 容器Container: 是镜像在运行中的实例,和镜像的关系类似于类和实例。
  3. 仓库Repository: 用于保存镜像Docker Hub 提供了大量镜像集合供使用。
  4. 注册中心Registry: 包含多个仓库,每个仓库有多个标签Tag。通常用<仓库名>:<标签>指定镜像,标签为镜像版本号,不写默认为latest
  5. 客户端client: 用户可以通过客户端,利用命令行或其他工具和docker的守护进程通讯
  6. 主机host: 物理或虚拟机器,用于执行Docker守护进程和容器

基础环境

  1. 前期准备
  • 卸载旧版本(docker、docker.io、docker-engine)

    1
    sudo apt-get remove docker docker-engine docker.io containerd runc
  • 当前为Docker Engine-Community 软件包 docker-ce

  • 更新仓库索引

    1
    sudo apt-get update
  • 安装https依赖包

    1
    2
    3
    4
    5
    6
    sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
  1. 自动安装
1
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

或者

1
curl -sSL https://get.daocloud.io/docker | sh

基本使用

  1. hello world
1
docker run ubuntu:15.10 /bin/echo "hello world"
  • run命令代表运行容器
  • ubuntu:15.10指定ubuntu镜像15.10标签的镜像实例。如果不存在此镜像,Docker会从镜像仓库Docker Hub中下载公共镜像
  • /bin/echo "hello world"在容器启动后执行的命令
  1. 交互
1
docker run -i -t ubuntu:15.10 /bin/bash
  • -i允许容器内的标准输入STDIN进行交互
  • -t在新容器内指定一个伪终端或终端
  • 使用exit命令或者CTRL+D可以退出容器
  1. 容器后台启动
1
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
  • -d后台执行
  • -c启动后执行命令
  1. 查看容器状态
1
2
3
docker ps
CONTAINER ID IMAGE COMMAND ...
5917eac21c36 ubuntu:15.10 "/bin/sh -c 'while t…" ...
  1. 查看后台容器的日志
1
docker logs 5917eac21c36
  1. 停止容器
1
docker stop 5917eac21c36
  1. 容器别名
1
2
3
4
5
docker run --name=myName ...
# 之后就可以
docker logs myName
# 以及
docker stop myName
  1. 容器信息对照表
标题 含义
CONTAINER ID 容器 ID
IMAGE 使用的镜像
COMMAND 启动容器时运行的命令
CREATED 容器的创建时间
PORTS 容器的端口信息和使用的连接类型(tcp\udp)
NAMES 自动分配的容器名称
STATUS 容器状态
  1. 容器状态对照表
状态 含义
created 已创建
restarting 重启中
running/up 运行中
removing 迁移中
paused 暂停
exited 停止
dead 死亡

容器使用

  1. 查看所有的命令
1
docker command --help
  1. 获取镜像
1
docker pull ubuntu
  1. 启动容器
1
docker run -it ubuntu /bin/bash
  • -it-i -t,开启交互,打开终端
  • /bin/bash镜像名后面跟的是命令,当前命令是希望开启容器后打开交互式的shell
  1. 退出
  • 命令行模式
    1
    exit
  1. 后台启动
1
docker run -itd --name ubuntu-test ubuntu /bin/bash
  • -d即不进入容器
  • -it是打开输入,并开启终端
  1. 进入后台开启的容器
1
docker exec ubuntu-test
  • exec命令进入后exit不会停止容器
  • attach命令进入后exit会停止容器,不建议使用
  • docker exec --help查看更多参数
  1. 本地容器导出
1
docker export 1e560fca3906 > ubuntu.tar
  1. 导入镜像
1
cat docker/ubuntu.tar | docker import - test/ubuntu:v1

也可以导入路径或是网络地址

1
docker import http://example.com/exampleimage.tgz example/imagerepo
  1. 删除容器
1
docker rm -f xxxxxxx
  1. 清除所有终止状态的容器
1
docker container prune
  1. web应用端口映射
1
docker run -d -p imageName
  • -d后台运行
  • -p容器内部网络端口映射到外部主机
  • -p 80:8098可以指定容器内部的80端口映射到外部主机的8098端口上
  • -p 127.0.0.1:80:8098端口映射的同时绑定容器的ip
  • docker port xxxxx可以查看具体容器的端口映射情况
  1. 挂载宿主机的目录
1
docker run -v /home/dock:usr/docker ubuntu64
  • -v 宿主机目录:镜像目录
  • 默认读写权限,-v 宿主机目录:镜像目录:ro指定只读
  1. 挂载其他的容器,作为数据存储
1
docker run -it --volumes-from xxxxx ubuntu64 /bin/bash
  • --volumes-from挂载数据卷,一般是一个容器挂载宿主目录,然后其他容器再将这个容器当做数据卷挂载。

镜像的使用

  1. 列出本机镜像列表
1
docker images
  1. 查找镜像
1
docker search httpd
列名 含义
NAME 镜像仓库名称
DESCRIPTION 镜像描述
OFFICIAL 是否是官方发布
STARS 点赞数
AUTOMATED 是否是自动构建
  1. 拉取镜像
1
docker pull httpd
  1. 删除镜像
1
docker rmi httpd
  1. 修改并创建新镜像
  • 如果当前镜像不满足要求,可以直接对镜像的实例进行修改,然后保存快照形成镜像

  • 运行一个实例,并修改内容

    1
    2
    docker run -t -i ubuntu:15.10 /bin/bash
    root@e218edb10161:/# apt-get update
  • 保存为快照

    1
    docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
  • -m提交描述

  • -a镜像的作者

  • e218edb10161容器id,提交那个容器

  • runoob/ubuntu:v2创建的镜像名

  1. 构建镜像
1
docker build -t runoob/centos:6.7 ./dockerFile
  • -t指定创建的镜像名
  • ./dockerFiledockerFile地址

仓库管理

  1. 登录仓库,登录docker hub
1
docker login
  1. 退出
1
docker logout
  1. 搜索仓库
1
docker search ubuntu
  1. 拉取镜像
1
docker pull ubuntu
  1. 推送镜像
1
2
3
4
5
6
# 标记镜像
docker tag ubuntu:18.04 username/ubuntu:18.04
# 列出本机所有镜像
docker image ls
# 推送镜像到仓库
docker push username/ubuntu:18.04

docker容器互联

  1. 创建网络
    1
    docker nerwork create -d bridge test-net
  • -d指定网络类型,有bridgeoverlay
  1. 创建两个容器并设置网络
1
2
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
  1. 测试网络连接
1
2
ping test1
ping test2

配置DNS

  1. 全局DNS
  • 宿主机/etc/docker/daemon.json
1
2
3
4
5
6
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
  1. 查看容器DNS
1
docker run -it --rm  ubuntu  cat etc/resolv.conf
  1. 启动时手动指定DNS
    1
    docker run -it --rm -h host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu
  • -rm退出时自动清理内部文件系统
  • -h HOSTNAME 设置主机名,会被写到/etc/hostname/etc/hosts
  • --dns--search=test.com设置搜索域,当搜索名为host的主机时,还会多搜索一个host.test.com
  • -dns指定dns

文章字数:398,阅读全文大约需要1分钟

SPI机制

本质是策略模式,一个接口,多个实现。根据不同策略选择,进行不同的策略。

  1. java spi例子
1
2
3
4
5
6
7
8
9
public static void main(String[] args) throws Exception {
// 使用spi加载接口的具体实现类
ServiceLoader<TestService> spiLoader = ServiceLoader.load(TestService.class);
Iterator<SpiService> iteratorSpi = spiLoader.iterator();
while(iteratorSpi.hasNext()) {
// 遍历出每个指定的实现类
TestService testService = spiLoader,next();
}
}

META-INF.services文件夹内创建com.test.service.testService文件,即接口名称命名的文件

其中指定了此接口指定的实现类,可用spi获取

1
2
3
com.test.service.impl.testServiceImpl1
com.test.service.impl.testServiceImpl2
com.test.service.impl.testServiceImpl3
  1. dubbo spi
    • @SPI注释标记的接口都可以使用dubbo spi进行拓展
1
2
3
4
5
6
7
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.7</version>
<!-- 设置成编译期间使用,否则放入dubbo项目后会jar冲突 -->
<scope>provided</scope>
</dependency>
  • LoadBalance负载均衡
1
2
3
4
5
6
7
8
9
public class MyLoadBalance implements LoadBalance {
// 自定义负载均衡策略
// invokers 是所有provider的实现,此方法主要是通过自定义策略选择返回一个provider的实现
@Override
public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
// 返回其中一个
return invokers.get(0);
}
}
  • ``META-INF.dubbo中创建接口全名的文件com.alibaba.dubbo.rpc.cluster.LoadBalance`
  • java自带的spi稍微不同,需要指定一个名称
1
myLoad=com.test.service.impl.MyLoadBalance
  • 使用此负载均衡
1
<dubbo:reference id="TestService" interface="com.test.service.TestService" loadbalance="myLoad"/>
  1. spi原理
    • 为所有接口生产一个加载器
    • 使用加载器生成接口代理对象
    • 使用代理对象执行方法时,根据参数判断使用那个实现类

文章字数:177,阅读全文大约需要1分钟

服务提供者

  • org.apache.dubbo.config.annotation.Service

服务消费者

  • org.apache.dubbo.config.annotation.Reference

常用属性

  • timeout: 超时时间(毫秒)
  • version服务版本,需要与服务提供在设置的一致
  • group服务分组,一个接口有多个实现时,可以使用分组区分,需要与服务提供者设置的一致
  • retires重试次数,默认0
  • loadbalance负载均衡策略:random(随机), roundrobin(轮询), leastactive(最少活跃调用)
  • url可以直连服务提供着,当注册中心宕机时,可以使用这个参数直连
  • registry注册中心服务列表,多个注册中心用逗号隔开
  • actives每个服务消费者最大并发调用数
  • protocol指定服务提供方协议

文章字数:430,阅读全文大约需要1分钟

RPC 服务暴露与引入

服务方

  1. 中转对象,用于中转代理对象的网络请求,参数、返回结果(Protocol.export创建)。

消费方

  1. 动态代理,为接口创建动态代理类,做请求发送功能。
  2. 使用Protocol.referInvoker,用于发送网络请求

Spring Rmi

服务提供者

1
2
3
4
5
6
7
8
9
10
11
12
13
// Spring rmi 中转对象
@Bean
public RmiServiceExporter serviceExporter() {
RmiServiceExporter res = new RmiServiceExporter();
// 代理接口的路径名称
res.setServiceName(TestService.class.getName());
// 端口
res.setRegistryPort(port);
// 暴露给外部访问的接口
res.setServiceInterface(TestService.class);
// 实际使用对象
res.setService(new TestServiceImpl())
}

SPI机制

本质是策略模式,一个接口,多个实现。根据不同策略选择,进行不同的策略。

  1. java spi例子
1
2
3
4
5
6
7
8
9
public static void main(String[] args) throws Exception {
// 使用spi加载接口的具体实现类
ServiceLoader<TestService> spiLoader = ServiceLoader.load(TestService.class);
Iterator<SpiService> iteratorSpi = spiLoader.iterator();
while(iteratorSpi.hasNext()) {
// 遍历出每个指定的实现类
TestService testService = spiLoader,next();
}
}

META-INF.services文件夹内创建com.test.service.testService文件,即接口名称命名的文件

其中指定了此接口指定的实现类,可用spi获取

1
2
3
com.test.service.impl.testServiceImpl1
com.test.service.impl.testServiceImpl2
com.test.service.impl.testServiceImpl3
  1. dubbo spi
    • @SPI注释标记的接口都可以使用dubbo spi进行拓展
1
2
3
4
5
6
7
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.7</version>
<!-- 设置成编译期间使用,否则放入dubbo项目后会jar冲突 -->
<scope>provided</scope>
</dependency>
  • LoadBalance负载均衡
1
2
3
4
5
6
7
8
9
public class MyLoadBalance implements LoadBalance {
// 自定义负载均衡策略
// invokers 是所有provider的实现,此方法主要是通过自定义策略选择返回一个provider的实现
@Override
public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
// 返回其中一个
return invokers.get(0);
}
}
  • ``META-INF.dubbo中创建接口全名的文件com.alibaba.dubbo.rpc.cluster.LoadBalance`
  • java自带的spi稍微不同,需要指定一个名称
1
myLoad=com.test.service.impl.MyLoadBalance
  • 使用此负载均衡
1
<dubbo:reference id="TestService" interface="com.test.service.TestService" loadbalance="myLoad"/>
  1. spi原理
    • 为所有接口生产一个加载器
    • 使用加载器生成接口代理对象
    • 使用代理对象执行方法时,根据参数判断使用那个实现类

文章字数:866,阅读全文大约需要3分钟

ECharts是百度开源的前端可视化工具,纯js图标库

基本图类

echart-gl还提供了3D的图表,这里只列举2D图表

  1. 柱状图(Bar)
  2. 折线图(Line)
  3. 散点图(Scatter)
  4. K线图(K)
  5. 饼图(Pie)
  6. 仪表盘(Gauge)
  7. 漏斗图(Funnel)
  8. 地图(Map)
  9. 雷达图(Radar)
  10. 和弦图(Chord)
  11. 力导布局图(Force)
  12. 孤岛图(Island)

以下图可以混搭使用
折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、 饼图(环形图)、雷达图、地图、和弦图、力导布局图

组件

  1. 坐标轴(Axis)
  2. 网格(Grid)
  3. 极坐标(Polar)
  4. 标题(Title)
  5. 提示(Tooltip)
  6. 图例(Legend)
  7. 数据区域缩放(DataZoom)
  8. 值域漫游(DataRange)
  9. 工具箱(Toolbox)
  10. 时间轴(Timeline)

特性

名称 描述
拖拽重计算 可以通过拖拽的方式提取、整合当前图表的数据;多表之间交换数据
数据视图 将图表数据输出成文本,并可以直接编辑
动态类型切换 折线图、柱状图自由切换
图例开关 通过点击图例,可以隐藏/显示部分数据
数据区域选择 通过拖动滑块,选择展示的数据区域
多图联动connect 多张图之间事件共享,保存图片时自动拼接。多张图公用一个区域选择以及详细信息查看等,用于展示相关数据的不同视角。
值域漫游 基于坐标的图标(地图、散点图)是通过颜色表明数组大小的,此功能可以只显示某个区域的数值
炫光特效 可以在地图上展示好看的光电以及标线
大规模散点图 900 x 400的区域就可以显示36W组,上百万的散点数据也能轻松展示
数据动态加载 每次setOption之后echart会自动获取不同的地方,并进行平滑转换
标线辅助 k线图可以画辅助标线
多维度堆积 多组数据叠加
子区域地图 通过主地图类型拓展出子区域地图
GeoJson地图扩展 压缩的地图拓展
事件交互 获取用户与图标的交互数据

文章字数:274,阅读全文大约需要1分钟

记录几个ffmpeg的命令,其中有推hls流的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
hls:
点播:ffmpeg -re -i source.mp4 -codec:v libx264 -codec:a libfaac -map 0 -f hls -hls_list_size 6 -hls_wrap 10 -hls_time 10 playlist.m3u8
//ffmpeg -re -f dshow -i video="BisonCam, NB Pro" -codec:v libx264 -codec:a libfaac -map 0 -f hls -hls_list_size 6 -hls_wrap 10 -hls_time 10 playlist.m3u8
ffmpeg -re -f dshow -video_size 1280x720 -rtbufsize 702000k -framerate 60 -i video="BisonCam, NB Pro" -codec:v libx264 -codec:a libfaac -map 0 -f hls -hls_list_size 6 -hls_wrap 10 -hls_time 10 playlist.m3u8

rmtp:
桌面:ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -acodec libfaac -f flv rtmp://localhost:1935/rtmplive/home
桌面+麦克风:ffmpeg -f avfoundation -i "1:0" -vcodec libx264 -preset ultrafast -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/rtmplive/home
桌面麦克风摄像头在下:ffmpeg -f avfoundation -framerate 30 -i "1:0" \-f avfoundation -framerate 30 -video_size 640x480 -i "0" \-c:v libx264 -preset ultrafast \-filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10' -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/rtmplive/home
摄像头:
获取摄像头列表:ffmpeg -list_devices true -f dshow -i dummy
ffmpeg -f dshow -i video="BisonCam, NB Pro" out.mp4
录制摄像头:ffmpeg -f dshow -i video="Integrated Camera" out.mp4
查看摄像头详细信息:ffmpeg -f dshow -list_options true -i video="BisonCam, NB Pro"
指定分辨率1280x720帧数15:ffmpeg -f dshow -s 1280x720 -r 15 -vcodec mjpeg -i video="Integrated Camera" out.avi

文章字数:589,阅读全文大约需要2分钟

一、Flex布局是什么

  1. Flex即弹性布局,设置容器内部空间如何布局
  2. 任何容器都能设置display: flex
  3. 行内元素也可以设置display: inline-flex
  4. 设置flex之后,子元素floatclearvertical-align都会失效

二、基本概念

  1. flex容器即flex container
  2. 子元素自动成为容器成员,即flex item
  • flex container

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       cross start  ^ 
    |
    cross axis
    |
    |
    main start | main end
    <---main axis------------------>
    |
    |
    |
    |
    cross end v
  • flex item

1
2
3
4
5
6
7
8
9
10
11
        ^
|
|
cross size
|
|
<----------main size--->
|
|
|
V

三、容器属性

属性名 作用 属性值 含义
flex-direction 主轴方向 row 从左向右,默认
- - row-reverse 从右向左
- - column 从上到下
- - column-reverse 从下到上
flex-wrap 主轴换行模式 nowrap 不换行,默认
- - wrap 换行,多余的在下
- - wrap-reverse 换行,多余在上
flex-flow 主轴方向及换行 flex-flow: 主轴方向 换行
justify-content 主轴对齐方式 flex-start 向主轴开端对齐,默认
- - flex-end 向主轴末尾对齐
- - center 居中
- - space-between 两端对齐,项目间间隔相等
- - space-around 每个项目两侧间隔都相等
align-items 交叉轴对齐方式 flex-start 交叉轴开端对齐
- - flex-end 交叉轴末尾对
- - center 居中对齐
- - baseline 项目的第一行文字基线对齐
- - stretch 如果未设置高度,或者auto,占满整个容器
align-content 换行之后各行对齐方式 flex-start 对齐交叉轴起点
- - flex-end 对齐交叉轴终点
- - center 居中
- - space-between 交叉轴两端对齐
- - space-around 交叉轴间间隔相等
- - stretch 占满整个交叉轴,默认

四、项目属性

属性名 作用 属性值 含义
order 项目排列顺序 int 小的靠前
flex-grow 项目放大比例 int 默认0,不放大
flex-shrink 项目缩小比例 int 默认1,空间不足按比例缩小
flex-basis 主轴再分配多余空间前,项目占用的空间 px 默认auto,及项目本身大小
flex 放大、缩小比例、空间分配三个合并 none,flex-grow flex-shrink flex-basis 默认 0 1 auto
align-self 元素交叉轴对齐方式 auto 继承父元素align-items,默认
- - flex-start 交叉轴起点对齐
- - flex-end 交叉轴终点对齐
- - center 中心对齐
- - baseline 项目第一行文字对齐
- - stretch 占满容器(未设置高度)

文章字数:71,阅读全文大约需要1分钟

起因

遇到需要将for循环的计数器i用在循环之外的情况,发现比判断条件多加了1

解决

for循环在判断之后还会执行一下最后的++操作

1
2
3
int j;
for (j = 1; j <= 10; j++) {}
System.out.println("j = " + j);

输出

1
j = 11