Cesium 100K数据加载 支持弹窗 动态更改位置

news2024/12/28 9:00:47
  • 前言:今天总结关于point、label、billboard海量数据加载。后续会研究下大量model加载以及大bim(几百G上T)模型记载

海量点加载

在这里插入图片描述

  • 弹窗

加载点位时,不加载弹窗。点击点位时在加载弹窗,及有效的减少加载量,优化性能。

const handler = new Cesium.ScreenSpaceEventHandler();
handler.setInputAction(function (movement: any) {
    const pickedLabel = viewer.scene.pick(movement.position);
    if (Cesium.defined(pickedLabel)) {
      console.log(pickedLabel)
      staticPoins.some(i => {
        if (i.id === pickedLabel.id.id || i.id === pickedLabel.id) {
          changePopWins(i)
          return true
        }
      })
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  function changePopWins(item: Point) {
  let flag = popWins.value.some(i => {
    if (i.id === item.id) {
      i.visible = !i.visible
      return true
    }
  })
  if (!flag) {
    popWins.value.push({ ...item, visible: true })
  }
}
  • dom-tag组件
<template>
  <div class="cesium-domPoint" ref="element">
    <slot :data="props.data">
    </slot>
  </div>
</template>
<script lang="ts" setup>
import * as Cesium from "cesium";
import { onMounted, onUnmounted, ref, PropType } from "vue";
import type { EalignX, EalignY } from "../typing";
const props = defineProps({
  eventClick: Function,
  data: Object,
  trackPos: {
    type: Object as PropType<Cesium.Cartesian3>,
  },
  trackEntity: {
    type: Object as PropType<Cesium.Entity>,
  },
  alignX: {
    type: String as PropType<EalignX>,
  },
  alignY: {
    type: String as PropType<EalignY>,
  },
  trackCursor: Boolean,
});
const { Viewer } = window;
let element = ref<HTMLDivElement | null>(null),
  mousePos: Cesium.Cartesian2,
  trackCursor = props.trackCursor;
const handler = new Cesium.ScreenSpaceEventHandler();
const onUpdate = () => {
  if (element == null) return;
  let screenPos;
  if (trackCursor) {
    screenPos = mousePos;
  } else if (props.trackEntity) {
    let pos =
      (props.trackEntity.position &&
        props.trackEntity.position.getValue(Cesium.JulianDate.now())) ||
      Cesium.Cartesian3.ZERO;
    screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
      Viewer.scene,
      pos
    );
  } else if (props.trackPos) {
    screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
      Viewer.scene,
      props.trackPos
    );
  }
  if (screenPos) {
    if (element.value) {
      switch (props.alignX) {
        case "left":
          element.value.style.left = screenPos.x + "px";
          break;
        case "center":
          element.value.style.left =
            screenPos.x + element.value.clientWidth * 0.5 + "px";
          break;
        case "right":
        default:
          element.value.style.left =
            screenPos.x - element.value.clientWidth * 0.5 + "px";
      }

      switch (props.alignY) {
        case "top":
          element.value.style.top =
            screenPos.y - element.value.clientHeight + "px";
          break;
        case "bottom":
          element.value.style.top = screenPos.y + "px";
          break;
        case "center":
        default:
          element.value.style.top =
            screenPos.y - element.value.clientHeight * 0.5 + "px";
      }
      if (parseFloat(element.value.style.top) < (-element.value.clientWidth) || parseFloat(element.value.style.left) < (-element.value.clientHeight) || parseFloat(element.value.style.left) > (document.body.clientWidth + element.value.clientWidth) || parseFloat(element.value.style.top) > (document.body.clientHeight + element.value.clientHeight)) {
        element.value.style.display = "none";
      }
      else {
        element.value.style.display = "";
      }
    }
  } else {
    if (element.value) element.value.style.display = "none";
  }
};
onMounted(() => {
  if (trackCursor) {
    handler.setInputAction((event: any) => {
      let offsetToLeftTop = Viewer.container.getBoundingClientRect();
      mousePos = Cesium.Cartesian2.subtract(
        event.endPosition,
        new Cesium.Cartesian2(offsetToLeftTop.left, offsetToLeftTop.top),
        new Cesium.Cartesian2()
      );
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }
  Viewer.scene.preUpdate.addEventListener(onUpdate);
});
onUnmounted(() => {
  if (Viewer && !Viewer.isDestroyed()) {
    Viewer.scene.preUpdate.removeEventListener(onUpdate);
  }
  handler && handler.destroy()
});
</script>
<style lang="less" scoped>
.cesium-domPoint {
  position: absolute;
  z-index: 0;
}
</style>
 <template v-for="item in popWins" :key="item.id">
    <DomTag :trackPos="item.pos" v-if="item.visible">
      <PopWin :point="item" @tooglePopWin="tooglePopWin1" />
    </DomTag>
  </template>
  • 最常用的就是entity

不加载图片以及文字的时候20W的点都没问题,虽然帧数就10左右,但是流畅度还行

for (let i = 0; i < 500; i++) {
     for (let j = 0; j < 400; j++) {
       viewer.entities.add({
         point: {
           pixelSize: 5,
           color: Cesium.Color.BEIGE
         },
         position: Cesium.Cartesian3.fromDegrees(103 + i * 0.1, 30 + j * 0.1)
       })  
     }
   }

在这里插入图片描述

添加文字后(20K),虽然也是10侦左右但是会感到明显的卡顿

for (let i = 0; i < 50; i++) {
  for (let j = 0; j < 400; j++) {
    viewer.entities.add({
      point: {
        pixelSize: 5,
        color: Cesium.Color.BEIGE
      },
      label: {
        text: i+""
      },
      position: Cesium.Cartesian3.fromDegrees(103 + i * 0.1, 30 + j * 0.1)
    })  
  }
}

在这里插入图片描述

  • 添加图片

图片较小只有179个字节。20k的数据流畅度可以,图片越大流畅度越低

 viewer.entities.add({
  point: {
      pixelSize: 5,
      color: Cesium.Color.BEIGE
    },
    billboard: {
      image: 'icons/facility.gif'
    },
    // label: {
    //   text: i+""
    // },
    position: Cesium.Cartesian3.fromDegrees(103 + i * 0.1, 30 + j * 0.1)
  })  

在这里插入图片描述

  • 总结:entity加载,图片越大流畅度越低,点越密集流畅度越低。层级越高流畅度越高(密度下降)。

entity聚合

添加(10k)聚合功能,首次加载时间延长,但是加载成功后流畅度显著提高,并且entity可以同时添加文字和图片
/*
本质上还是利用的是entity加载,还是慢加载时间长
加载完成后性能提升
*/
在这里插入图片描述

  let staticPoins: Point[] = []
  for (let i = 0; i < 500; i++) {
    for (let j = 0; j < 200; j++) {
      let obj = {
        visible: false,
        id: i + '_' + j,
        onlinetime: "2023-02-21 11:32:22",
        accountname: `${i}_${j}`,
        differentialstate: 7,
        curH: 474.59999999999997,
        curB: 30 + i * 0.1,
        curL: 104 + 0.1 * j,
        satellitenumber: 50,
        dopvalue: 0.6000000238418579,
        delay: 0,
        reserver1: "153403.172851563",
        reserver2: "NTRIP GNSSInternetRadio/1.4.5",
        pos: Cesium.Cartesian3.fromDegrees(104.06657490833334, 30.63132543),
      }
      obj.pos = Cesium.Cartesian3.fromDegrees(obj.curL, obj.curB)
      staticPoins.push(obj)
    }
  }
  staticPoins.forEach((i, j) => {
    if (j < 10000)
      dataSource.entities.add({
        id: i.id,
        point: {
          pixelSize: 0
        },
        label: {
          text: i.accountname,
          font: '20px sans-serif',
          showBackground: true,
          // verticalOrigin: Cesium.VerticalOrigin.TOP,
          pixelOffset: new Cesium.Cartesian2(0, -65),
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10e5),//根据Label与相机的距离来获取或设置Label的近和远像素偏移缩放比例属性
          // eyeOffset: new Cesium.Cartesian3(0, 7.2, 0)
          heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
        },
        billboard: {
          image: 'icons/facility.gif',
          scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1, 1.5e7, 0),//根据相机距离缩放(下限、下限的值、上限、上限的值)
          width: 16,
          height: 16,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // //相对于对象的原点(注意是原点的位置)的水平位置
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        },
        position: i.pos
      })
  })
  const dataSourcePromise = viewer.dataSources.add(dataSource);
  dataSourcePromise.then(function (dataSource) {
    const pixelRange = 15;
    const minimumClusterSize = 3;
    const enabled = true;
    dataSource.clustering.enabled = enabled; //是否聚合
    dataSource.clustering.pixelRange = pixelRange;
    dataSource.clustering.minimumClusterSize = minimumClusterSize;
    const pinBuilder = new Cesium.PinBuilder();
    const pin1000 = pinBuilder
      .fromText("1000+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin500 = pinBuilder
      .fromText("100+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin100 = pinBuilder
      .fromText("100+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin50 = pinBuilder
      .fromText("50+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin40 = pinBuilder
      .fromText("40+", Cesium.Color.ORANGE, 48)
      .toDataURL();
    const pin30 = pinBuilder
      .fromText("30+", Cesium.Color.YELLOW, 48)
      .toDataURL();
    const pin20 = pinBuilder
      .fromText("20+", Cesium.Color.GREEN, 48)
      .toDataURL();
    const pin10 = pinBuilder
      .fromText("10+", Cesium.Color.BLUE, 48)
      .toDataURL();
    const singleDigitPins = new Array(8);
    for (let i = 0; i < singleDigitPins.length; ++i) {
      singleDigitPins[i] = pinBuilder
        .fromText(`${i + 2}`, Cesium.Color.VIOLET, 48)
        .toDataURL();
    }
    function customStyle() {
      if (Cesium.defined(removeListener)) {
        removeListener && removeListener();
        removeListener = undefined;
      } else {
        removeListener = dataSource.clustering.clusterEvent.addEventListener(
          function (clusteredEntities, cluster) {
            cluster.label.show = false;
            cluster.billboard.show = true;
            cluster.billboard.id = cluster.label.id;
            cluster.billboard.verticalOrigin =
              Cesium.VerticalOrigin.BOTTOM;

            if (clusteredEntities.length >= 1000) {
              cluster.billboard.image = pin1000;
            } else if (clusteredEntities.length >= 500) {
              cluster.billboard.image = pin500;
            } else if (clusteredEntities.length >= 100) {
              cluster.billboard.image = pin100;
            } else if (clusteredEntities.length >= 50) {
              cluster.billboard.image = pin50;
            } else if (clusteredEntities.length >= 40) {
              cluster.billboard.image = pin40;
            } else if (clusteredEntities.length >= 30) {
              cluster.billboard.image = pin30;
            } else if (clusteredEntities.length >= 20) {
              cluster.billboard.image = pin20;
            } else if (clusteredEntities.length >= 10) {
              cluster.billboard.image = pin10;
            } else {
              cluster.billboard.image =
                singleDigitPins[clusteredEntities.length - 2];
            }
          }
        );
      }
      const pixelRange = dataSource.clustering.pixelRange;
      dataSource.clustering.pixelRange = 0;
      dataSource.clustering.pixelRange = pixelRange;
    }
    customStyle();
  })

dom加载

利用坐标点的变化时候改变dom元素的位置
优点:自由度高
缺点:适合几百以内的数据。

<template v-for="item in points" :key="item.id">
  <DomTag :trackPos="item.pos">
    <Dev :point="item" @tooglePopWin="tooglePopWin" />
  </DomTag>
</template>
  • PointPrimitiveCollection

加载PointPrimitiveCollection点集合,速度快且流畅,也是推荐的方式。
缺点只能加载点

在这里插入图片描述

let pointPrimitives: Cesium.PointPrimitiveCollection;
pointPrimitives = scene.primitives.add(
 new Cesium.PointPrimitiveCollection()
);
for(let i = 0; i < 100000; i++) {
pointPrimitives.add({
 id: i.id,
 pixelSize: 10,
 color: color,
 outlineColor: outlineColor,
 outlineWidth: 0,
 label: {
   text: 222
 },
 distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
   5.5e3
 ),
 position: i.pos,
});
}
  • 点位移动

这个方法,移动十万个点位,很流畅

viewer.scene.preUpdate.addEventListener(animateBillboards);
function animateBillboards() {
  const moveAmount = new Cesium.Cartesian3(100, 0.0, 0.0);
  const positionScratch = new Cesium.Cartesian3();
  // @ts-ignore
  const billboards = pointPrimitives._pointPrimitives;
  const length = billboards.length;
  for (let i = 0; i < length; ++i) {
    const billboard = billboards[i];
    Cesium.Cartesian3.clone(billboard.position, positionScratch);
    Cesium.Cartesian3.add(positionScratch, moveAmount, positionScratch);
    billboard.position = positionScratch;
  }
}
  • billoardPrimitives

同上,只能加载图片。

let billoardPrimitives: Cesium.BillboardCollection
billoardPrimitives = viewer.scene.primitives.add(
    new Cesium.BillboardCollection({
      scene: scene,
    })
  );
for(let i = 0; i < 100000; i++) {
billoardPrimitives.add({
 id: i.id,
 image: 'icons/facility.gif',
 width: 10,
 height: 10,
 position: i.pos
});
}
  • Primitive和聚合搭配着使用

cesium官方未能提供primitive的聚合方法,但是可以用entity的聚合搭配着使用。

  • CommomSiteTookit
import * as Cesium from "cesium";
import { defaultValue } from 'cesium'


type Option = {
    delay?:number;
    enabled?: boolean;
    pixelRange?:number;
    minimumClusterSize?:number;
}
/**
 * @_v 引入外部创建的Viewer实例(new Cesium.Viewer(...))
 * @myPrimitives 原语集合,可以包含页面显示的pointPrimitiveCollection、billboardCollection、labelCollection、primitiveCollection、primitiveCluster
 * @myPrimitiveCluster 自定义原语集群
 * @myBillboardCollection 广告牌集合(站点显示的内容数据)
 *
 * @desc 使用primitiveCollection原语集合与primitiveCluster原语集群,处理地图界面显示广告牌billboard数量 > 10w 级时,界面卡顿,浏览器崩溃等问题
 */
class CommomSiteTookit {
  static _v: Cesium.Viewer;
  myPrimitives: Cesium.PrimitiveCollection | null = null
  myPrimitiveCluster:any = null;
  myBillboardCollection:Cesium.BillboardCollection|null = null;
  constructor() {}

  /**
   * @desc 使用commomSiteTookit实例前,必须先初始化该实例的_v对象
   */
  init(viewer: Cesium.Viewer) {
    CommomSiteTookit._v = viewer;
  }

  /**
   * @param [options] 具有以下属性的对象
   * @param [options.delay=800] 防抖处理定时器的time
   * @param [options.enabled=true] 是否启用集群
   * @param [options.pixelRange=15] 用于扩展屏幕空间包围框的像素范围
   * @param [options.minimumClusterSize=2] 可集群的屏幕空间对象的最小数量
   *
   * @desc 处理原语集合,并实现聚合集群功能方法
   * @return billboardCollection集合,可直接往集合里添加广告牌billboard,呈现在页面上
   */
  load(options:Option = {}) {
    let billboardCollection = new Cesium.BillboardCollection();
    let labelboardCollection = new Cesium.LabelCollection();
    if (Cesium.defined(this.myPrimitives)) {
        CommomSiteTookit._v.scene.primitives.remove(this.myPrimitives);
    }
    this.myPrimitives = CommomSiteTookit._v.scene.primitives.add(
      new Cesium.PrimitiveCollection()
    );
    //@ts-ignore
    const primitiveCluster = new Cesium.PrimitiveCluster();
    this.myPrimitives && this.myPrimitives.add(primitiveCluster);
    primitiveCluster.delay = defaultValue(options.delay, 800);
    primitiveCluster.enabled = defaultValue(options.enabled, true);
    primitiveCluster.pixelRange = defaultValue(options.pixelRange, 15);
    primitiveCluster.minimumClusterSize = defaultValue(
      options.minimumClusterSize,
      2
    );
    primitiveCluster._billboardCollection = billboardCollection;
    primitiveCluster._initialize(CommomSiteTookit._v.scene);

    let removeListener:any;
    let pinBuilder = new Cesium.PinBuilder();
    /* 定义广告牌 fromText(显示文字,颜色,大小) */
    const pin1000 = pinBuilder
      .fromText("1000+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin500 = pinBuilder
      .fromText("500+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin100 = pinBuilder
      .fromText("100+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin50 = pinBuilder
      .fromText("50+", Cesium.Color.RED, 48)
      .toDataURL();
    const pin40 = pinBuilder
      .fromText("40+", Cesium.Color.ORANGE, 48)
      .toDataURL();
    const pin30 = pinBuilder
      .fromText("30+", Cesium.Color.YELLOW, 48)
      .toDataURL();
    const pin20 = pinBuilder
      .fromText("20+", Cesium.Color.GREEN, 48)
      .toDataURL();
    const pin10 = pinBuilder
      .fromText("10+", Cesium.Color.BLUE, 48)
      .toDataURL();
    /* 数量小于十个的聚合广告牌 */
    let singleDigitPins = new Array(8);
    for (let i = 0; i < singleDigitPins.length; ++i) {
      singleDigitPins[i] = pinBuilder
        .fromText("" + (i + 2), Cesium.Color.VIOLET, 40)
        .toDataURL();
    }

    const _ = this;
    function customStyle() {
      if (Cesium.defined(removeListener)) {
        removeListener();
        removeListener = undefined;
      } else {
        removeListener = primitiveCluster.clusterEvent.addEventListener(
          function(clusteredEntities:any, cluster:any) {
            cluster.label.show = false;
            cluster.billboard.show = true;
            cluster.billboard.id = cluster.label.id;
            cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
            /* 根据站点(参数)的数量给予对应的广告牌  */
            if (clusteredEntities.length >= 1000) {
                cluster.billboard.image = pin1000;
              } else if (clusteredEntities.length >= 500) {
                cluster.billboard.image = pin500;
              } else if (clusteredEntities.length >= 100) {
                cluster.billboard.image = pin100;
              } else if (clusteredEntities.length >= 50) {
                cluster.billboard.image = pin50;
              } else if (clusteredEntities.length >= 40) {
                cluster.billboard.image = pin40;
              } else if (clusteredEntities.length >= 30) {
                cluster.billboard.image = pin30;
              } else if (clusteredEntities.length >= 20) {
                cluster.billboard.image = pin20;
              } else if (clusteredEntities.length >= 10) {
                cluster.billboard.image = pin10;
              } else {
                cluster.billboard.image =
                  singleDigitPins[clusteredEntities.length - 2];
              }
          }
        );
      }
      // force a re-cluster with the new styling
      let pixelRange = primitiveCluster.pixelRange;
      primitiveCluster.pixelRange = 0;
      primitiveCluster.pixelRange = pixelRange;
      _.myPrimitiveCluster = primitiveCluster;
    }
    this.myBillboardCollection = billboardCollection;
    // start with custom style
    customStyle();
    return billboardCollection;
  }

  /**
   * @params enable bool值控制开启或关闭集群
   * @desc 控制集群生效与否
   */
  enableCluster(enable:boolean) {
    if (Cesium.defined(this.myPrimitiveCluster)) {
      this.myPrimitiveCluster!.enabled = enable;
    }
  }

  /**
   * @params id 站点ID
   * @return 返回可操作的广告牌[siteBillboard.image = 'xxxx']
   * @desc 根据id在集合中获取指定站点广告牌
   */
  getSiteBillboardById(id: string) {
    if (!Cesium.defined(this.myBillboardCollection)) return undefined;
    const _b = this.myBillboardCollection!;
    const l = _b.length;
    let siteBillboard = undefined;
    for (let i = 0; i < l; i++) {
      if (id == _b.get(i).id) {
        siteBillboard = _b.get(i);
        break;
      }
    }
    return siteBillboard;
  }

  /**
   * @desc 删除所有站点广告牌
   */
  removeAll() {
    if (Cesium.defined(this.myPrimitives)) {
        CommomSiteTookit._v.scene.primitives.remove(this.myPrimitives);
    }
  }

  /**
   * @params show bool值 控制显示或隐藏
   * @desc 隐藏或显示所有站点广告牌
   */
  showStatus(show = true) {
    this.myPrimitives!.show = show;
  }

  /**
   * @desc 根据id删除指定站点广告牌
   */
  remove(id:string) {
    const billboard = this.getSiteBillboardById(id);
    billboard && this.myBillboardCollection!.remove(billboard);
  }

  /**
   * @desc 销毁(目前退出页面时直接viewer销毁)
   */
  destroy() {
    this.myPrimitives = null;
    this.myPrimitiveCluster = null;
    this.myBillboardCollection = null;
    // this._v.scene.primitives.destroy()
  }
}

export default new CommomSiteTookit();

 CommomSiteTookit.init(viewer)
  const data = CommomSiteTookit.load({
    enabled: true,
    delay: 1200,
    pixelRange: 20
  });
 for(let i = 0; i  < 100000; i++) {
	data.add({
        image: 'icons/facility.gif',
        scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1, 1.5e7, 0.2),
        width: 16,
        height: 16,
        position: i.pos,
        id: i.id
      });
}
    ```


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/374443.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA学习之日常工作复位电路

最近一个多月没有写博客了&#xff0c;然后最近工作中也遇到一个复位信号的问题。问题是这样的&#xff0c;关于外部复位信号&#xff0c;之前我们的处理方式都是通过PLL产生的Lock信号作为内部的复位信号。但是由于换到A54上面没有IP核&#xff0c;所以只有不用PLL&#xff0c…

Mybatis持久层框架 | 动态SQL、缓存

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 动态SQL 动态SQL就是指根据不同条件生成不同的sql语句&#xff0c;本质还是SQL语句&#xff0c;知识可以在SQL层面&#xff0c;执行逻辑代码 搭建环境 创建数据库 cre…

Linux搭建SVN服务器,并内网穿透实现公网远程访问

文章目录1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6.2 配置…

HCIA-HarmonyOS Application Developer——题目集2

题目1 1、HarmonyOS的"18N”战略中的"1"指的是什么? A、智慧屏 B、平板电脑 C、手表 D、手机 解析&#xff1a;&#xff08;D&#xff09; HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统&#xff0c;是一个全场景分布式智慧操作系统&#xff0c;覆…

从产品经理的角度如何提升项目的交付质量?

提高交付质量 &#xff0c;对于每个IT公司都是永恒的话题。 交付质量其实包含2重意义&#xff0c; 一是交付的高质量&#xff08;客户角度&#xff09;&#xff0c;即客户的满意度&#xff1b;二是高质量的交付&#xff08;交付团队的角度&#xff09;&#xff0c;这里是指如何…

【笔记】ChatGPT是怎样炼成的(李宏毅2023机器学习课程引入部分)

来源&#xff1a;【授权】李宏毅2023春机器学习课程 ChatGPT太火热了&#xff0c;借此简单了解一下 ChatGPT的newbie之处在哪里&#xff1f; 同一个问题&#xff0c;它的每次回答都不同&#xff1b;处于同一个chat中&#xff0c;我可以追问多个问题&#xff0c;因为它知道上下…

NO.8代码随想录第8天-字符串|●28. 实现 strStr()●459.重复的子字符串●字符串总结

KMP算法的原理&#xff1a; KMP算法&#xff1a;解决字符串匹配的问题。 前缀&#xff1a;包含首字母不包含尾字母的所有子串。 后缀&#xff1a;包含尾字母不包含首字母的所有子串。 最长相等前后缀&#xff1a;以模式串aabaaf为例&#xff0c;这里从a开始到aabaaf&#x…

数据结构入门DAY1

力扣刷题合集&#xff1a;力扣刷题_Sunlightʊə的博客-CSDN博客217.存在重复元素相关题目链接&#xff1a;力扣 - 存在重复元素题目重现给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 &#xff0c;返回 true &#xff1b;如果数组中每个元素互不相同&#xff0c;返…

【Spark分布式内存计算框架——Spark Streaming】5. DStream(上)

3. DStream SparkStreaming模块将流式数据封装的数据结构&#xff1a;DStream&#xff08;Discretized Stream&#xff0c;离散化数据流&#xff0c;连续不断的数据流&#xff09;&#xff0c;代表持续性的数据流和经过各种Spark算子操作后的结果数据流。 3.1 DStream 是什么…

镜像、复制和直线绘制CAD图形

这个CAD图形可以分成两个部分&#xff1a;上面一部分和下面一部分&#xff0c;都是有多个相同的对象&#xff0c;所以只需要绘制出其中一个再使用复制和旋转命令将其它的绘制出就可了&#xff0c;用到的主要CAD命令有CAD直线、CAD旋转、CAD镜像和CAD直线 目标对象 操作步骤 1…

利用递归实现括号匹配

案例引入以下则是各个字符串经过括号处理之后的结果&#xff1a;12((21))(12-->12(21)1232((((2121)212(21)-->32(2121)212(21)ABDF((SA)SA)SA(SA)SA(((-->ABDF((SA)SA)SA(SA)SA算法思路&#xff1a;这个问题的解决方法就是将字符按顺序逐一加入到新的string容器store…

python自学之《21天学通Python》(14)——第17章 Web网站编程

Web编程是程序设计应用之一&#xff0c;随着动态网站不断发展&#xff0c;Web编程已经成为程序设计的重要应用领域。目前Web编程主要有ASP.NET、PHP、Java等编程语言&#xff0c;Python语言也可以像其他语言一样应用于Web服务。 17.1 Web网站编程概述 Web是一个由许多互相链接…

mysql索引分析之二

mysql索引分析之一 mysql索引分析之二 mysql索引分析之二1 mysql的索引类型2 Explain执行计划2.1 执行计划之 id 属性2.1.1 id 的属性相同表示加载表的顺序是从上到下2.1.2 id 值越大&#xff0c;优先级越高2.1.3 id 有相同&#xff0c;也有不同&#xff0c;同时存在2.2 执行计…

浅析 Redis 主从同步与故障转移原理

我们在生产中使用 Redis&#xff0c;如果只部署一个 Redis 实例&#xff0c;当该实例宕机&#xff0c;到恢复之前都不可用&#xff1b;虽说 Redis 一般都用来做缓存&#xff0c;但不可用给业务系统带来的影响也是不小的&#xff0c;流量大时甚至会导致整个服务宕机。所以 Redis…

6.0.4:GrapeCity Documents for Excel GcExcel Crack

在更短的时间内生成 Excel 电子表格&#xff0c;不依赖于 Excel&#xff01; 在任何应用程序中转换、计算、格式化和解析电子表格。 快速高效&#xff1a;其轻巧的尺寸意味着 Documents for Excel 针对快速处理大型 Excel 文档进行了优化 使用适用于 Windows、Linux 和 Mac 的…

Spring Cloud Sentinel实战(一)- Sentinel介绍

Sentinel介绍 什么是Sentinel 分布式系统的流量防卫兵&#xff1a;随着微服务的普及&#xff0c;服务调用的稳定性变得越来越重要。Sentinel以“流量”为切入点&#xff0c;在流量控制、断路、负载保护等多个领域开展工作&#xff0c;保障服务可靠性。 特点&#xff1a; 1. 2…

【尚硅谷MySQL入门到高级-宋红康】数据库概述

1、为什么要使用数据库 数据的持久化 2、数据库与数据库管理系统 2.1 数据库的相关概念 2.2 数据库与数据库管理系统的关系 3、 MySQL介绍 MySQL从5.7版本直接跳跃发布了8.0版本 &#xff0c;可见这是一个令人兴奋的里程碑版本。MySQL 8版本在功能上做了显著的改进与增强&a…

c++提高篇——STL常用算法

STL常用算法一、常用遍历算法一、for_each 遍历容器二、transform 搬运容器到另一个容器中二、常用查找算法一、find二、find_if三、adjacent_find四、binary_search五、count六、count_if三、常用排序算法一、sort二、random_shuffle三、 merage四、reverse四、常用拷贝和替换…

推荐系统遇上深度学习(一四三)-[快手]一致性终身用户行为建模方法TWIN

标题&#xff1a;《TWIN: TWo-stage Interest Network for Lifelong User Behavior Modeling in CTR Prediction at Kuaishou》链接&#xff1a;https://arxiv.org/pdf/2302.02352.pdf今天给大家分享的是快手近期发表的终身行为序列建模上的工作&#xff0c;当前工业界主流的方…

一文打通计算机字符编码

有关编码的基础知识 1. 位 bit 最小的单元 字节 byte 机器语言的单位 1byte8bits 1KB1024byte 1MB1024KB 1GB1024MB 2.进制 二进制 binary 八进制 octal 十进制 decimal 十六进制 hex 3.字符 字符&#xff1a;是各种文字和符号的总称&#x…