Git Product home page Git Product logo

webknowledge's People

Contributors

awestbrookfan avatar chiumungzitalexander avatar huyaocode avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webknowledge's Issues

手写Promise中的then错了

then 将创建一个没有经过回调函数处理的新 Promise 对象,这个新 Promise 只是简单地接受调用这个 then 的原 Promise 的终态作为它的终态。

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  const that = this
  //对传入的两个参数做判断,如果不是函数将其转为函数
  onFulfilled = 
    typeof onFulfilled === 'function'
    ? onFulfilled 
    : v => v  // onFulfilled = v => v
  onRejected = 
    typeof onRejected === 'function'
    ? onRejected
    : r => {
      throw r
    }
  
  if(that.state === PENDING) {
    that.resolvedCallbacks.push(onFulfilled)
    that.rejectedCallbacks.push(onRejected)
  }
  else if(that.state === RESOLVED) {
    onFulfilled(that.value)
  }
  else {
    onRejected(that.value)
  }
}

搞懂闭包

闭包这个概念是前端工程师必须要深刻理解的,但是网上确实有一些文章会让初学者觉得晦涩难懂,而且闭包的文章描述不一。

本文面向初级的程序员,聊一聊我对闭包的理解。当然如果你看到闭包联想不到作用域链垃圾回收也不妨看一眼,希望读了它之后你不再对闭包蒙圈。

先体验一下闭包

这里有个需求,即写一个计数器的函数,每调用一次计数器返回值加一:

counter()	// 1
counter()	// 2
counter()	// 3
......

要想函数每次执行的返回不一样,怎么搞呢? 先简单的写一下:

var index = 1;
function counter() {
	return index ++;
}

这样做的确每次返回一个递增的数。但是,它有以下三个问题:

  1. 这个index放在全局,其他代码可能会对他进行修改
  2. 如果我需要同时用两个计数器,但这种写法只能满足一个使用,另一个还想用的话就要再写个counter2函数,再定义一个index2的全局变量。
  3. 计数器是一个功能,我只希望我的代码里有个 counter函数就好,其他的最好不要出现。这是稍微有点代码洁癖的都会觉得不爽的。

三个痛点,让闭包来一次性优雅解决:

function counterCreator() {
	var index = 1;
	function counter() {
		return index ++;
	}
	return counter;
}

// test
var counterA = counterCreator();
var counterB = counterCreator();
counterA();		// 1
counterA();		// 2
counterB();		// 1
counterB();		// 2

我的counterCreator函数只是把上面的几行代码包起来,然后返回了里面的 counter 函数而已。却能同时解决这么多问题,这就是闭包的魅力! 6不6啊?

666

铺垫知识

铺垫一些知识点,不展开讲。

执行上下文

函数每次执行,都会生成一个会创建一个称为执行上下文的内部对象(AO对象,可理解为函数作用域),这个AO对象会保存这个函数中所有的变量值和该函数内部定义的函数的引用。函数每次执行时对应的执行上下文都是独一无二的,正常情况下函数执行完毕执行上下文就会被销毁

作用域链

在函数定义的时候,他还获得[[scope]]。这个是里面包含该函数的作用域链,初始值为引用着上一层作用域链里面所有的作用域,后面执行的时候还会将AO对象添加进去 。作用域链就是执行上下文对象的集合,这个集合是链条状的。

function a () {
	// (1)创建 a函数的AO对象:{ x: undfind,  b: function(){...}  , 作用域链上层:window的AO对象}
	var x = 1;
	function b () {
		// (3)创建 b函数的AO对象:{ y: undfind , 作用域链上层:a函数AO对象}
		var y = 2;
		// (4)b函数的AO对象:{ y: 3 , 作用域链上层:a函数AO对象}
		console.log(x, y);	// 在 b函数的AO对象中没有找到x, 会到a函数AO对象中查找
	}
	//(2)此时 a函数的AO对象:{ x: 1,  b: function(){...} , 作用域链上层:window的AO对象}
	b();
}
a();

正常情况函数每次执行后AO对象都被销毁,且每次执行时都是生成新的AO对象。我们得出这个结论: 只要是这个函数每次调用的结果不一样,那么这个函数内部一定是使用了函数外部的变量。

垃圾回收

如何确定哪些内存需要回收,哪些内存不需要回收,这依赖于活对象这个概念。我们可以这样假定:一个对象为活对象当且仅当它被一个根对象 或另一个活对象指向。根对象永远是活对象。

function a () {
	var x = 1;
	function b () {
		var y = 2;
		// b函数执行完了,b函数AO被销毁,y 被回收
	}
	b();
	//a 函数执行完了,a函数AO被销毁, x 和 b 都被回收
}
a();
// 这里是在全局下,window中的 a 直到页面关闭才被回收。

分析闭包结构

// 生成闭包的函数
function counterCreator() {

	// 被返回函数所依赖的变量
	var index = 1;

	// 被返回的函数
	 function counter() {
		return index ++;
	}
	return counter;
}

// 被赋值为闭包函数
var counterA = counterCreator();

// 使用
counterA();

闭包的创造函数必定包含两部分:

  1. 一些闭包函数执行时依赖的变量,每次执行闭包函数时都能访问和修改
  2. 返回的函数,这个函数中必定使用到上面所说的那些变量
// 被赋值的闭包函数
var counterA = counterCreator();
var counterB = counterCreator();

而上面这两句代码很重要,它其实是把闭包函数赋值给了一个变量,这个变量是一个活对象,这活对象引用了闭包函数,闭包函数又引用了AO对象,所以这个时候AO对象也是一个活对象。此时闭包函数的作用域链得以保存,不会被垃圾回收机制所回收。

当我们想重新创建一个新的计数器时,只需要重新再调用一次 counterCreator, 他会新生成了一个新的执行期上下文,所以counterBcounterA是互不干扰的。

counterCreator 执行

counterCreator 执行完毕,返回counter

总结

闭包的原理,就是把闭包函数的作用域链保存了下来。

使用闭包

带你手写一个简单的防抖函数,趁热打铁。

第一步,先把闭包的架子搭起来,因为我们已经分析了闭包生成函数内部一定有的两部分内容。

function debunce(func, timeout) {
	// 闭包函数执行时依赖的变量,每次执行闭包函数时都能访问和修改
	return function() {
		// 这个函数最终会被赋值给一个变量
	}
}

第二步: 把闭包第一次执行的情况写出来

function debunce(func, timeout) {
	timeout = timeout || 300;
	return  function(...args)  {
		var _this = this;
		setTimeout(function () {
			func.apply(_this, args);
		}, timeout);
	}
}

第三步: 加上一些判断条件。就像我们最开始写计数器的index一样,不过这一次你不是把变量写在全局下,而是写在闭包生成器的内部。

function debunce(func, timeout) {
	timeout = timeout || 300;
	var timer = null;	// 被闭包函数使用
	return  function(...args)  {
		var _this = this;
		clearTimeout(timer);	// 做一些逻辑让每次执行效果可不一致
		timer  = setTimeout(function () {
			func.apply(_this, args);
		}, timeout);
	}
}

// 测试:
function log(...args) {
	console.log('log: ', args);
}
var d_log = debunce(log, 1000);

d_log(1);	// 预期:不输出
d_log(2);	// 预期:1s后输出

setTimeout( function () {
	d_log(3);	// 预期:不输出
	d_log(4);	// 预期:1s后输出
}, 1500)

闭包运用

闭包用到的真的是太多了,再举几个例子再来巩固一下:

模块化

例NodeJS模块化原理:
NodeJS 会给每个文件包上这样一层函数,引入模块使用require,导出使用exports,而那些文件中定义的变量也将留在这个闭包中,不会污染到其他地方。

(funciton(exports, require, module, __filename, __dirname) {
	/* 自己写的代码  */
})();

高阶函数

一些使用闭包的经典例子:

最后,如果你对闭包有更好的理解或者我文章里写的不好的地方,还请指教。

CSS 创建BFC方式

BFC

  1. html根元素
  2. float 不为none
  3. position: absolute / fixed
  4. display: inline-block / table-cell / table-caption / table / table-row / table-row-group / table-header-group / table - foolter-group / flow-root / flex / inline-flex / grid / inline-grid
  5. overflow 不为 visible
  6. 多列容器 column-count 不为auto
  7. column-span 不为1

关于TCP三步握手那里一些易混淆的地方

“对于 TCP 头部来说,以下几个字段是很重要的:

序列号 (Sequence number),这个序号保证了 TCP 传输的报文都是有序的,对端可以通过序号顺序的拼接报文

确认号 (Acknowledgement Number),这个序号表示数据接收端期望接收的下一个字节的编号是多少,同时也表示上一个序号的数据已经收到

窗口大小 (Window Size),表示还能接收多少字节的数据,用于流量控制……”

这一段包括之后三步握手部分确实把确认号和ACK标识符区分开了,但是在输入URL到页面加载过程分析那一段的三步握手里出现了:

“端口建立 TCP 链接,三次握手如下:
客户端发送一个 TCP 的SYN=1,Seq=X的包到服务器端口
服务器发回SYN=1, ACK=X+1, Seq=Y的响应包
客户端发送ACK=Y+1, Seq=Z”

这部分应该是把ACK标识符和确认号混淆了,应该是ACKbit为1,确认号为X+1,因为确认号就等于下一个client request的序列号,而当前client request序列号为X且request大小只有1bit,所以下一个SN就是X+1。

关于内推你需要知道的事

为什么要内推?

找到熟悉 / 可靠的人去帮你内推,然后与他保持联系。你可以知道更多信息,比如:

  • 查看面试进度信息

    • 简历挂没挂?有没有把你晾在一边不管?你可知道?
    • 内推人可直接帮你查看面试进度信息
  • 填写推荐语

    • 好的推荐语可以让你脱颖而出。
  • 特殊情况紧急联系

    • 有一次我面试,A公司发了offer之后需要在几天内签约,快到期了。但是 B 公司还在面试中,B公司更好。我需要联系B公司为我加速面试流程。那次我还好好不容易联系上了,B给我一天内面了终面并保证了我的结果,最后我签了B的offer,并且可以放心大胆的放弃Aoffer。
  • 处理速度更快

为什么少在牛客网,BOSS直聘等招聘平台或信息平台上面投递简历?

  • 牛客网
    • 牛客的讨论区被各种内推塞的满满的,热门的帖子你敢投吗? 一个部门被很多人投递,你岂不是在自找难度?
    • 有骗简历的风险
    • 投了基本无法联系上,比如我在为什么要找内推里说的那些,你办不到
    • 说海量 HC 可能只是招聘方需要海量备胎。问问内推人简历是不是太多,如果是,换一个部门。
  • BOSS 与 拉钩 等招聘平台
    • 投了难以联系上,而且处理速度比内推慢

到底怎么内推?

  1. 首选熟人内推,保证联系上那种
  2. 你觉得靠谱的人内推

我靠谱不?

我们内推是任务,我当工作来完成,而且内推可以你直接使用我的内推投递链接或者校招码投递,这样我看不到你简历,保护你隐私。而且我尊重你的职位选择,我内推其实主要就是帮你填推荐语。(很多帮内推的都是往自己部门推,导致部门简历过多且可能不是你喜欢的职位)

如何联系我?

我的微信: purple12369
我的邮箱:[email protected]

怎么内推?

  • 校招
    • 直接联系我,使用我的内推码 MHQXH13 在官网投递,投递后我会收到通知,然后你把推荐语给我,我帮你填上。
  • 社招
    • 你选好岗位告诉我,我把对应岗位的内推链接给你,当你投递后我再帮你填写推荐语。也可直接发我简历与推荐语,我帮你填上

揭示 useCallback 的问题和隐患并给出解决方案

官网对 useCallback 的介绍

返回一个 memoized 回调函数。
把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate)的子组件时,它将非常有用。

使用 useCallback 的场景?

  1. 函数被 useEffect 内部所使用,但为了避免频繁 useEffect 的频繁调用,所以我包一下;
  2. 我只是为了解决 hooks lint 的提示报警,所以我包一下;
  3. 因为有一个使用了 useCallback 的函数引用了我这个函数,所以我不得不包一下;
  4. 当这个函数会被传递给子组件,为了避免子组件频繁渲染,使用 useCallback 包裹,保持引用不变;
  5. 需要保存一个函数闭包结果,如配合 debounce、throttle 使用;
  6. 我希望这个useCallback包裹但函数,但某个依赖项变化时,引用了我这个函数的所有 useEffect 都得重新执行一下;

我们做了投票,发现场景 4 是使用的最多的
image

案例

假如这里有个文章组件,我想观察当「文章内容」明确后, 用户对「文章标题」的修改频率如何。这个
具体实现:当「文章内容」的长度大于 0 时编辑「文章标题」就上报埋点,同时带上「文章标题」和「文章内容」的 字符长度。

点击链接,打开 console 看Demo:https://codepen.io/huyao/pen/LYbdomv?editors=0010

小胡写出了下面这一段代码,大家可以细看一下,有哪些地方需要优化?它有哪些地方不规范?

// 新建文章组件
function EditArticle() {
  const [title, setTitle] = useState("");
  const [content, setContent] = useState("");
  const [other, setOther] = useState("");

  // 获取当前「标题」和「内容」的长度
  const getTextLen = () => {
    return [title.length, content.length];
  };

  // 上报当前「标题」和「内容」的长度
  const report = () => {
    const [titleLen, contentLen] = getTextLen();
    if (contentLen > 0) {
      console.log(`埋点 >>> 标题长度 ${titleLen}, 内容长度${contentLen}`);
    }
  };

  /**
   * 副作用
   * 当「标题」长度变化时,上报
   */
  useEffect(() => {
    report();
  }, [title]);

  return (
    <div className="App">
       文章标题   <input value={title} onChange={(e) => setTitle(e.target.value)} />
       
       文章内容  <input value={content} onChange={(e) => setContent(e.target.value)} />
      
       其他不相关状态: <input value={other} onChange={(e) => setOther(e.target.value)} />

      <MemoArticleTypeSetting getTextLen={getTextLen} />
    </div>
  );
}
enum ArticleType {
  WEB = "前端",
  SERVER = "后端",
}

// 子组件,修改文章类型(无需关注,它只是接受了父组件的一个参数而已)
const ArticleTypeSetting: FC<{ getTextLen: () => number[] }> = ({  getTextLen }) => {
  console.log(" --- ArticleTypeSetting 组件重新渲染 --- ");

  const [articleType, setArticleType] = useState<ArticleType>(ArticleType.WEB);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setArticleType(e.target.value as ArticleType);

    console.log(  "埋点 >>> 切换类型,当前「标题」和「内容」长度:", getTextLen()  );
  };

  return (
    <div>
      <div>文章类型组件,当选择类型时上报「标题」和「内容」长度</div>
      <div>
        {[ArticleType.WEB, ArticleType.SERVER].map((type) => (
          <div>  
            <input  type="radio" value={type} checked={articleType === type} onChange={handleChange}  /> 
           {type} 
          </div>
        ))}
      </div>
    </div>
  );
};

const MemoArticleTypeSetting = memo(ArticleTypeSetting);

注:这段代码是我为了模拟 useEffect 和 useCallback 同时使用而构思出来的,大家不用深究。当然有其他写法可以避免问题,我们这里只是借这个 Demo 描述一下这种类型的场景。

CodeReview 与修改

哪些地方需要优化?

子组件 ArticleTypeSetting 是使用 memo 包裹的,这个组件是希望尽可能的减少渲染次数的(假装这个组件有性能问题,一般不用包)。但是,现在每当修改任意一个值(如 other),子组件都会重新渲染,这显然是没有达到优化的预期的。

哪些地方不规范?

image

这里不规范, useEffect 中使用了 report 函数,但是没有将它放到依赖数组中。我认为这是一件比较危险的事情,在 Hooks 中经常有过期状态的问题。插件已经帮你提示了,虽然现在你自测感觉没问题,但你很难保证在经过几轮轮修改之后,虽然你的代码一堆 warning 或 error,但跑起来没问题。

修改代码

小胡于是对代码进行了一些修改:

  1. 将 getTextLen 和 report 使用 useCallback 包裹
  // 获取当前「标题」和「内容」的长度
  const getTextLen = useCallback(() => {
    return [title.length, content.length];
  }, [title, content]);

  // 上报当前「标题」和「内容」的长度
  const report = useCallback(() => {
    const [titleLen, contentLen] = getTextLen();
    if (contentLen > 0) {
      console.log(`埋点 >>> 内容长度 ${titleLen}, 内容长度${contentLen}`);
    }
  }, [getTextLen]);

  /**
   * 副作用
   * 当「标题」长度变化时,上报
   */
  useEffect(() => {
    report();
  }, [title, report]);

还有问题吗?

有,当 「文章内容」修改了之后,会触发 useEffect 继续上报,这个问题比较隐晦,不再回归测试的话难以发现;并且编辑文章内容时子组件也在重新渲染。

为什么出了问题?

我的初衷只是使用 useCallback 避免频繁调用,但当一个 useCallback 的依赖项变化后,这个 useEffect 会被执行,就像上面修改过后的代码一样,「文章内容」修改了之后,也会触发 useEffect 的,这就是「useCallback 带来的隐式依赖问题」。

如何解决?

方式 1(不推荐):将所有状态都挂到 Ref 上,然后每次修改状态之后主动触发渲染

这种做法确实可以解决这个问题,但是代码不宜维护,理由如下:

  1. 一旦一个组件这样写了之后,之后要有什么新的状态也只好放到这里面。
    而在新写组件的时候,你不知道什么时候会碰到这个问题,因为一旦碰到了你只有使用 forceUpdate 来解决,要改相关状态的定义,每次使用的时候还要把 someSate 改为 ref.someState。

  2. 每次想更新视图时都需要 forceUpdate,官网是不推荐这种方式的,链接点我
    image

方式 2:将 函数绑定到 useRef 上来解决

  const getTextLenRef = useRef<() => [number, number]>(() => [0, 0]);

  // 获取当前「标题」和「内容」的长度
  getTextLenRef.current = () => {
    return [title.length, content.length];
  };

  // 上报当前「标题」和「内容」的长度
  const report = () => {
    const [titleLen, contentLen] = getTextLenRef.current();
    if (contentLen > 0) {
      console.log(`埋点 >>> 标题长度 ${titleLen}, 内容长度${contentLen}`);
    }
  };

  /**
   * 副作用
   * 当「标题」长度变化时,上报
   */
  useEffect(() => {
    report();
  }, [title]);

将函数绑定到 Ref上,ref 引用不论怎样都保持不变,而且函数每次 render ref 上又会绑定最新的函数,不会有闭包问题。我在开发一个复杂项目中,大量的使用了这种方式,这让我的开发效率提升。它让我专注于写业务,而不是专注于解决闭包问题。

这种处理方式的灵感来源于 Dan 的博客:使用 React Hooks 声明 setInterval

优化使用 ref 的体验

虽然把函数挂到 ref 上可以很好到解决这个问题,但是我在开发的时候我并不知道一个函数之后会不会碰到这个闭包问题,但我又不想所以函数全部都这样干。

我对这种方式抽象封装了一下,得到这样一个工具函数,它通过将函数挂到 ref 上,保证永远都是拿到最新状态的函数,往外暴露时使用 useCallback 包裹,保证函数引用不更新。

export function useRefCallback<T extends (...args: any[]) => any>(callback: T) {
  const callbackRef = useRef(callback);
  callbackRef.current = callback;
  return useCallback((...args: any[]) => callbackRef.current(...args), []) as T;
}

使用时,简单的把原来有闭包问题的函数包裹一下,不需要传递依赖性,方便简单又好用。

点击链接,打开 console 看Demo:https://codepen.io/huyao/pen/XWNELYr?editors=0010

  // 获取当前「标题」和「内容」的长度
  const getTextLen = useRefCallback(() => {
    return [title.length, content.length];
  });

  // 上报当前「标题」和「内容」的长度
  const report = useRefCallback(() => {
    const [titleLen, contentLen] = getTextLen();
    if (contentLen > 0) {
      console.log(`埋点 >>> 内容长度 ${titleLen}, 内容长度${contentLen}`);
    }
  });

  /**
   * 副作用
   * 当「标题」长度变化时,上报
   */
  useEffect(() => {
    report();
  }, [title, report]);

思考我们最开始使用 useCallback 的理由

我认为其实最开始使用 useCallback 的理由中,只有「需要保存一个函数闭包结果,如配合 debounce、throttle 使用」这个是真正需要使用 useCallback 的,其他的都可能带来风险,比如:

当 useCallback 和 useEffect 组合使用时,由于 useCallback 的依赖项变化也会导致 useEffect 执行,这种隐式依赖会带来BUG或隐患。因为在编程中,函数只是一个工具,但现在一旦某个函数使用了 useCallback ,当这个函数的依赖项变化时所有直接或间接调用这个 useCallback 的都需要回归。所以我说这是成本高、有风险的事情。

而「为了避免子组件频繁渲染,使用 useCallback 包裹,保持引用不变」这种情况下,当 useCallback 的依赖项变化时,函数的引用也在更新,没有完全的避免子组件频繁渲染问题。

而「希望这个useCallback函数的某个依赖项变化时,引用了我这个函数的所有 useEffect 都得重新执行一下」这个理由,我认为它是有风险的,虽有有时候你确实希望这么做,但我认为这样在设计上就不对,副作用怎么调用应该由副作用来决定,不应该由依赖的函数来影响,当你真正碰上这个场景,你应该将所有应该主动的把触发 useEffect 执行的状态都放入依赖数组中。

结论

在绝大多数情况下,开发者想要的仅仅只是避免函数的引用变化而已,而 useCallback 带来的隐式依赖问题会给你带来很大的麻烦,所以推荐使用 useRefCallback,把函数挂到 ref 上,这样代码更不容易留下隐患或带来问题,还可以省去维护 useCallback 依赖项的精力。

而 useRefCallback 本质上就是帮你把函数挂在 ref 上,并方便你使用 ref.current。

export function useRefCallback<T extends (...args: any[]) => any>(callback: T) {
  const callbackRef = useRef(callback);
  callbackRef.current = callback;

  return useCallback((...args: any[]) => callbackRef.current(...args), []) as T;
}

如何选择offer?

凡事都有方法论,但大多数人做选择则是简单的凭感觉。“感觉”这个东西往往是不够准确的,当你的大脑往某些方向多想一下的时候,当旁人说了几句话的时候,你凭拍脑袋得出的结论往往就会发生变化。当几个选择接近时,凭感觉更无法得出结论。

本文是介绍如何做选择,并侧重讲如何选择offer。

租的概念

“白赚”的收入就叫“租”。

假如你现在有两个offer,A offer年薪20W、B offer年薪30W。我们假设这两个offer除了薪资不同,其他都差不多。你肯定会选择年薪30W的B offer,即使Boffer 只有 21 W,你也会选 B ,因为 BA 高啊。 这BA 高的部分,是你”白赚“的,这多出来的部分就叫租。

影响选择的多个因素

应届生选择offer往往会从以下几点考虑:

  • 发展前景,由公司名气与部门核心程度决定(3年后我值多少钱,我的技术是什么水平)
  • 薪资福利(每年能挣多少钱)
  • 地理位置(离家近总是好,特别是离女朋友近就更好了)

参加 TLC前端开发者大会后的感悟

有幸拿到了涛哥的邀请函,免费去听了这场大会,就当涨涨见识。其实大多数我都没有听懂,只是大概知道了有这些东西,有了一些感悟。

听分享前可以做什么?

最近在准备实习,没有对会议内容进行背景的预习。自己没有带着问题听,也没有相关的经验,有的术语也不熟。导致很多听了也就听了,从技术的角度来看其实收益不大。

听分享后可以做什么?

去事件,去输出,去体验。让自己记住以后有碰到类似场景可以超这边靠拢。

氛围

每个人都是求知若渴的,而且他们有很多开发经验。而且感觉很多开发者都很帅气,都在不断的深入学习中

讲师

让听众听懂自己讲的内容才是关键。听众不关心你有多牛批,你这个东西有多牛批,你不是在做答辩,而是做分享,是为了让他人收获知识,增长眼界。有好几次听到讲师在着重去讲一些成果,那个时候心里是抵触的。

感悟

webpack作者可以把生活过的很好,severless讲师超级帅。他们都是活的很优雅的。我认为技术其实就是匠人的一把锤子,是匠人的手艺,匠人会做最好的东西。但匠人不会苦逼的说自己每天面对这些很难受,太多东西要学了什么的。 匠人会沉浸其中,会开心,会充实的。

关于stopPropagation方法的说法有点错误

MDN上关于stopPropagation方法的描述如下:The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.应该是阻止在捕获阶段或冒泡阶段继续传播,而不是阻止冒泡。

js基础的ES6部分,vue3的响应式数据

vu3中,ref 函数被推荐用来声明基础数据类型的响应式,仍然是通过Object.defineProperty实现的,而reactive定义的引用数据类型才是通过Proxy实现的,所以并不是完全替换的关系。

【开源自荐】SolidUI 一句话生成任何图形

本人介绍

本人从事十年年大数据相关工作,做过用户增长,BI,大数据中台,知识图谱,AI中台,擅长大数据AI相关技术栈。在CSDN输出很多专栏,是CSDN博客专家,CSDN大数据领域优质创作者,2018年参与共建WeDataSphere开源社区,社区属性是数据相关综合社区,共建过DataSphereStudio(开发管理集成框架),Exchangis(数据交换工具),Streamis(流式应用开发管理系统),Apache Linkis (计算中间件) 。个人发起SolidUI数据可视化社区。Apache Asia 2022 讲师 ,Hadoop Meetup 2022 讲师,WeDataSphere Meetup 2022讲师。Apache Linkis Committer , EXIN DPO (数据保护官)。

2023年2月开始创业,全职运营SolidUI。

SolidUI介绍

一句话生成任何图形。

随着文本生成图像的语言模型兴起,SolidUI想帮人们快速构建可视化工具,可视化内容包括2D,3D,3D场景,从而快速构三维数据演示场景。SolidUI 是一个创新的项目,旨在将自然语言处理(NLP)与计算机图形学相结合,实现文生图功能。通过构建自研的文生图语言模型,SolidUI 利用 RLHF (Reinforcement Learning Human Feedback) 流程实现从文本描述到图形生成的过程。

SolidUI Gitee https://gitee.com/CloudOrc/SolidUI
SolidUI GitHub https://github.com/CloudOrc/SolidUI
SolidUI 官网地址 https://cloudorc.github.io/SolidUI-Website/
Discord https://discord.gg/NGRNu2mGeQ
SolidUI v0.3.0 发版文章 https://mp.weixin.qq.com/s/KEFseiQJgK87zvpslhAAXw
SolidUI v0.3.0 概念视频 https://www.bilibili.com/video/BV1GV411A7Wn/
SolidUI v0.3.0 教程视频 https://www.bilibili.com/video/BV1xh4y1e7j6/
SolidUI 演示环境 http://www.solidui.top/ admin/admin

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.