什么是线程安全

线程安全是指在多线程环境下,程序能够正确地执行,并且能够保证数据的正确性和一致性。当多个线程同时访问同一块内存区域或共享资源时,如果没有适当的同步机制,就会出现数据竞争(Data Race)的问题,导致程序出现不可预期的错误。因此,线程安全是多线程编程中非常重要的一个概念。

在保证线程安全的前提下,多线程程序应该能够正确地处理并发访问共享资源的情况,避免出现死锁、活锁、饥饿等并发问题,同时还要保证程序的性能和可伸缩性。

为了实现线程安全,一般采用以下几种方式:

  1. 使用同步机制,如 synchronized 关键字、Lock 接口等,保证对共享资源的互斥访问。
  2. 使用并发集合,如 ConcurrentHashMap、ConcurrentLinkedQueue 等,保证对共享资源的并发访问。
  3. 避免使用共享资源,尽可能将状态封装到对象内部,使其成为线程独立的。
  4. 使用不可变对象,即对象一旦被创建就不能被修改,从而避免线程安全问题。

总之,线程安全是多线程编程中最基本的要求,需要在程序设计和实现中始终考虑和保证。

docker-compose 的 networks

Docker Compose 中的 networks 是用于定义 Docker 容器间通信的网络。在 Docker Compose 中,您可以创建一个或多个 networks,然后将服务(services)映射到这些 networks 中,从而使它们能够相互通信。

您可以使用 Docker Compose 中的 networks 来创建不同类型的网络,如 bridge、host、overlay 等等。Bridge 网络是默认的网络类型,可以用于在单个主机上的容器之间进行通信。Host 网络可以让容器直接使用主机网络,而不是在 Docker 引擎内部进行网络隔离。Overlay 网络则可以用于跨多个 Docker 主机进行通信。

在 Docker Compose 文件中定义 networks 的语法如下所示:

networks:
  <network-name>:
    [driver: <driver-name>]
    [external: true|false]
    [name: <network-name>]
    [attachable: true|false]
    [driver_opts: {}]
    [internal: true|false]

其中,<network-name> 为网络名称,driver 为网络驱动程序名称,external 用于指定网络是否应该由 Docker Compose 创建,name 用于指定网络名称,attachable 用于指定网络是否可以附加到已运行的容器,driver_opts 用于指定网络驱动程序的特定选项,internal 用于指定是否应将网络标记为仅供容器内部使用。

怎么将一个视频逐帧分解为图片格式输出

有时候我们会在网站中见到这种网页滚动效果

怎么将一个视频逐帧分解为图片格式输出插图
https://www.insta360.com/cn/product/insta360-oners

实现方法主要原理就是将原本的视频分解为图片,然后监听滚动事件根据滚动距离逐个替换img标签的src属性,以实现动态播放的效果,这其实也是电影和动画的本质。

但是怎么将视频分解为图片呢?

继续阅读“怎么将一个视频逐帧分解为图片格式输出”

Pinia 简单入门

首先我们需要知道什么是pinia

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。

pinia有什么优点

  • dev-tools 支持
    • 跟踪动作、突变的时间线
    • Store 出现在使用它们的组件中
    • time travel 和 更容易的调试
  • 热模块更换
    • 在不重新加载页面的情况下修改您的 Store
    • 在开发时保持任何现有状态
  • 插件:使用插件扩展 Pinia 功能
  • 为 JS 用户提供适当的 TypeScript 支持或 autocompletion
  • 服务器端渲染支持
继续阅读“Pinia 简单入门”

利用css属性clip-path来绘制图片遮罩

MDN

利用css属性clip-path来绘制图片遮罩插图

<template>
  <img ref="img" class="img active" src="./assets/pic.jpg" alt="">
</template>

<style>
:root {
  box-sizing: border-box;
}

html,
body {
  all: unset
}

.app {
  background-color: var(--color);

}

.img {
  object-fit: cover;
  width: 500px;
  height: 500px;
  clip-path: circle(0% at 0% 50%);
  transition: 1s;
}

.img.active {
  clip-path: circle(50% at 50% 50%);
}
</style>
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
const img = ref(null)
const timer = onMounted(() => {
  setInterval(() => {
    img.value.classList.toggle('active')
  }, 1500);
})
onUnmounted(() => {
  clearInterval(timer)
})
</script>

Vue Directive 自定义属性

<template>
  <div class="box" v-animation>
    BOX
  </div>
</template>

<style>
@keyframes move {
  0% {
    transform: translateX(0px);
  }

  50% {
    transform: translateX(100px);
  }

  1000% {
    transform: translateX(0px);
  }
}

.box {
  box-sizing: border-box;
  width: 100px;
  height: 100px;
  background-color: aquamarine;
  display: flex;
  justify-content: center;
  align-items: center;
}

.animation {
  transition: 1s ease;
  animation: move 1s infinite;
}
</style>
<script setup>
const vAnimation = {
  mounted: (el) => {
    el.classList.add('animation')
  }
}
</script>
Vue Directive 自定义属性插图

初始化之后,Box开始左右摇摆。

利用 TypeScript 联合类型以及类型保护机制来正确推断类型

假设有两个接口 A 和 B

假设有个对象 Obj 在程序运行过程中,有可能为 A 类型也有可能为 B 类型,

这时候就可以利用联合类型 Obj: A | B,多个类型用 | 分隔

利用 TypeScript 联合类型以及类型保护机制来正确推断类型插图
举个栗子

但是需要注意的是,这时候 TypeScript 只能推断 A 和 B 的共有属性

继续阅读“利用 TypeScript 联合类型以及类型保护机制来正确推断类型”