…
行内标签:
…
行内块状标签:
…
块标签和行内标签有什么区别:
块状标签: 能独自占据一行,可以对其设置宽度、高度、对齐等属性。它可以容纳行内标签和其他块状标签。但是 p,h1,h2,h3,h4,h5,h6,dt,他们都是文字类块级标签,里面不能放其他块级元素。
行内状标签: 不能独自占据一行,默认在一行中排列,不能对其设置宽度、高度、对齐等属性,仅仅靠自身的字体大小和图像尺寸来支撑结构。行内元素只能容纳文本或其他行内元素。(a特殊: a标签可以放div块级标签,同时a标签里不能再放a标签)
行内块标签: 和相邻行内元素(行内块)在一行上,但是之间会有空白缝隙。默认宽度就是它本身内容的宽度。高度,行高、外边距以及内边距都可以控制。
上述三类标签怎么转换:
(1)display:inline;转换为行内元素
(2)display:block;转换为块状元素
(3)display:inline-block;转换为行内块状元素
display中还有哪些值:
display:none
display:flex
display:table
让元素隐藏,你可以怎么做?display:none和visibility:hidden的区别:
推荐文章:https://www.cnblogs.com/Chen-XiaoJun/p/6213499.html
项目中,你什么时候用到了display:flex:
主要用flex来代替浮动,完成页面的布局
除了这种方式能居中,还有哪些:(在下方)
都有哪些盒子模型:(在下方)
CSS3 相关面试题
面试的时候我们应该怎么回答问题,某位大佬的讲解如下:
比如面试官提问:需要盒子水平垂直居中,你有几种方案?
这种情况下,虽然你心里可能知道有几种方案,但是我们不能一开口就说:一共有五种方案,方案如下:… 这样显得是背下来的。
在回答这一类的问题时,可以这么说:这种需求在我之前的项目中是非常常见的,最开始的时候,我只使用了(xxx,xxx)这些方式…随着之后的不断学习和使用,发现(xxx)这种方式是有(xxx)这样的缺陷的,因此经过查阅资料 / 阅读文档 发现, 从(xxx)方面上来看,这个方式(xxx)是比较好的。之后有一段时间,当我自己去看博客、GitHub时,发现这个方式(xxx)虽然不常用,但也能实现,我觉得还是挺有意思的,所以就记下来了。
对于其他的问题也是同样的答题思路。总结来说,就是:
(1)在之前的学习生涯 / 项目开发 中,遇到过这样的问题 / 曾实现过这样的功能,我当时是(xxx)这么做的。
(2)随着某新型语言的兴起 / 随着之后我不断的学习,发现了一个更好的(xxx)方案,虽然这方案有(xxx)这样的缺陷,但是它实现起来,从目前来看是最好的。
(3)同时,我平常喜欢去看博客(或者其他的xxx),在查阅时突然发现有这样的一个(xxx)方式也能实现,发现也还不错,所以我也记录了下来。
不考虑其他因素,下面哪种的渲染性能比较高:
答案是第二种,因为css的浏览器渲染机制是选择器从右向左查询。
即:第二种方式就只找所有的a,而对于第一种它会先找所有的a,再找box下所有的a,它进行了二次筛选。
盒子模型
推荐文章:https://www.cnblogs.com/yky-iris/p/7719895.html
请你谈一谈盒子模型:
它可以分为标准盒子模型、怪异盒模型(IE盒子模型)、flex弹性伸缩盒模型、columns多列布局盒模型。(当然最基础的还是前两种盒模型,后面两种并不是一定要在回答中提到)
标准盒模型:box-sizing: content-box;
在标准盒模型下,width和height是内容区域即content的width和height。
而盒子总宽度为 width + padding(左右) + border(左右) + margin(左右)
可想而知,如果我们使用标准盒模型设置width和height,调整好了一切参数后,一旦需要我们修改其中的参数,比如调整border,那么盒子模型的位置也就必然出现偏移,即:每次修改border、padding后,你都需要手动修改width和height的值。
在css3中就允许我们使用怪异盒模型,这次我们设置width和height,那么盒子大小就是这个值,不管我们怎么调border、padding,它会通过自动缩放内容,来帮我们保证这个width和height值不变。
因此推荐在项目中使用怪异盒模型。不仅如此,其实各大UI组件、公共样式的源码中,使用的也都是怪异盒模型。
怪异盒模型:box-sizing: border-box;
而IE盒模型或怪异盒模型,width和height除了content区域外,还包含padding和border。
盒子的总宽度为 width + margin(左右)(即width已经包含了padding和border值)
flex盒模型:display: flex;
推荐文章:
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。
主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;
交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
多列布局:(基本上不用)
盒子水平垂直居中的方案
<html lang="en">
<head>
<meta charset="UTF-8">
<title>盒子水平垂直居中title>
<style>
body {
height: 500px;
margin: 0;
padding: 0;
border: 1px solid red;
}
.box {
box-sizing: border-box;
width: 100px;
height: 50px;
line-height: 48px;
text-align: center;
font-size: 16px;
border: 1px solid lightblue;
background: lightcyan;
}
body{
display: flex;
justify-content: center;
align-items: center;
}
style>
head>
<body>
<div class="box" id="box">
zzz
div>
body>
html>
经典布局方案
圣杯布局 、 双飞翼布局 => 左右固定,中间自适应
(但实际上flex和定位更简单,因此我更偏向于使用定位方式,如果不考虑兼容就用flex)
圣杯布局
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圣杯布局title>
<style>
html,
body{
height: 100%;
overflow: hidden;
}
.container{
height: 100%;
padding: 0 200px;
}
.left,
.right{
width: 200px;
min-height: 200px;
background: lightblue;
}
.center{
width: 100%;
min-height: 400px;
background: lightsalmon;
}
.left,
.center,
.right{
float: left;
}
.left{
margin-left: -100%;
position: relative;
left: -200px;
}
.right{
margin-right: -200px;
}
style>
head>
<body>
<div class="container clearfix">
<div class="center">div>
<div class="left">div>
<div class="right">div>
div>
body>
html>
双飞翼布局
<html lang="en">
<head>
<meta charset="UTF-8">
<title>双飞翼布局title>
<style>
html,
body{
height: 100%;
overflow: hidden;
}
.container,
.left,
.right{
float: left;
}
.container{
width: 100%;
}
.container .center{
margin: 0 200px;
min-height: 400px;
background: lightsalmon;
}
.left,
.right{
width: 200px;
min-height: 200px;
background: lightblue;
}
.left{
margin-left: -100%;
}
.right{
margin-left: -200px;
}
style>
head>
<body>
<div class="clearfix">
<div class="container">
<div class="center">div>
div>
<div class="left">div>
<div class="right">div>
div>
body>
html>
flex布局
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex布局title>
<style>
html,
body{
overflow: hidden;
}
.container{
display: flex;
justify-content: space-between;
height: 100%;
}
.left,
.right{
flex: 0 0 200px;
height: 200px;
background: lightblue;
}
.center{
flex: 1;
min-height: 400px;
background: lightsalmon;
}
style>
head>
<body>
<div class="container">
<div class="left">div>
<div class="center">div>
<div class="right">div>
div>
body>
html>
定位方式布局
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定位title>
<style>
html,
body{
height: 100%;
overflow: hidden;
}
.container{
position: relative;
height: 100%;
}
.left,
.right{
position: absolute;
top: 0;
width: 200px;
min-height: 200px;
background: lightblue;
}
.left{
left: 0;
}
.right{
right: 0;
}
.center{
margin: 0 200px;
min-height: 400px;
background: lightsalmon;
}
style>
head>
<body>
<div class="container">
<div class="left">div>
<div class="center">div>
<div class="right">div>
div>
body>
html>
css实现三角形
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#box {
width: 0px;
height: 0px;
border: 100px solid transparent;
border-top-color: deeppink;
border-left-color: deeppink;
}
style>
head>
<body>
<div id="box">div>
body>
html>
JS 相关面试题
8种数据类型及区别
(在我的认知中,从最开始的学习中,也一直以为只有6种数据类型,直到真的有人问到8种数据类型,才傻眼了)
基本数据类型:Number、String、Boolean、Undefined、Null
引用数据类型:Object、Function
ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
(但是对于 bigInt 到底算不算数据类型,暂持观望态度)
推荐文章:https://blog.csdn.net/u013592575/article/details/95087953
关于堆栈内存和闭包作用域的题
堆:存储引用类型值的空间
栈:存储基本类型值和执行代码的环境
let a = {
},
b = '0',
c = 0;
a[b] = '你';
a[c] = '好';
console.log(a[b]);
因此输出结果是:好
数组和对象的区别?
数组:以数字作为索引,这个索引就是它的属性名。即:数组的数据没有”名称”
对象:当然也可以用数字作为索引,这个索引也是它的属性名,但它还可以设置其他的属性名。
且数组表示有序数据的集合,而对象表示无序数据的集合。如果数据的顺序很重要,就用数组,否则就用对象。
let a = {
},
b = Symbol('1'),
c = Symbol('1');
a[b] = '你';
a[c] = '好';
console.log(a[b]);
因为Symbol是创建唯一值的,因此会出现下面的效果:
因此输出结果是:你
let a = {
},
b = {
n: '1'
},
c = {
m: '2'
};
a[b] = '你';
a[c] = '好';
console.log(a[b]);
看下图就会发现,只要在obj中,即将要存放一个对象,无论这个对象里面存放的是什么,存放的效果都会是[object Object]: xxx。(即属性名相同,均为Object)
(这是因为存放的时候调用了toString()方法)
因此输出结果是:好
Object.prototype.toString()的用法?
之前,我们总会看到直接输出一个对象,会得到[object Object]这样的输出结果,为什么会输出这样的结果,其实是因为,输出的是toString()方法的返回值。它默认输出的就会是这样的结果。现在,通过调用Object.prototype.toString,可以为其改变输出结果。
当然也可以直接对 构造函数的实例 修改。
var test = (function (i) {
return function(){
alert(i*=2);
}
})(2);
test(5);
给var test = ? 赋值的步骤是:(1)创建一个变量 (2)准备值 (3)关联
这题的值是执行一个函数得来的,紧接着就把函数执行了,传进来的值就是2。这个叫:立即执行的自定义函数。
这里还涉及到了栈内存,这个过程的标准说法叫:浏览器一加载页面就形成栈内存,这个栈内存是用来执行代码的。每当这个函数被执行一次,都会形成一个全新的执行上下文(Execution Context Stack :执行栈)。页面就会将这个函数压缩到这个栈里去执行。如下图
需要注意,因为alert弹出的结果都会转化为字符串,
因此答案是:‘4’ (字符串4)
闭包形成的条件:
- 函数嵌套
- 内部函数引用外部函数的局部变量
闭包的优点:延长外部函数局部变量的生命周期
闭包的缺点:容易造成内存泄漏
需要注意的是:合理的使用闭包,用完闭包要及时清除(销毁)
var a = 0,
b = 0;
function A(a){
A = function(b){
alert(a + b++);
};
alert(a++);
}
A(1);
A(2);
因此输出结果是:‘1’ 和 ‘4’
你会发现全局的a和b根本就没变,因此可知闭包的作用:保存和保护
作用域
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<script type="text/javascript">
var num1 = 55;
var num2 = 66;
function f1(num, num1) {
num = 100;
num1 = 100;
num2 = 100;
console.log(num);
console.log(num1);
console.log(num2);
}
f1(num1, num2);
console.log(num);
console.log(num1);
console.log(num2);
script>
body>
html>
值类型和引用类型的传递
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<script type="text/javascript">
function Person(name, age, salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
Person.prototype.sayName = function(){
alert("Hello大家好,我是"+this.name);
}
function f1(person) {
person.name = "ls";
person = new Person("aa", 18, 10);
}
var p = new Person("zs", 18, 1000);
p.sayName();
console.log(p.name);
f1(p);
console.log(p.name);
script>
body>
html>
过程:
对象(数组)的深克隆和浅克隆
let obj = {
a: 100,
b: [10,20,30],
c: {
x: 10
},
d: /^\d+$/
};
let obj2 = {
};
for(let key in obj){
if(!obj.hasOwnProperty(key)) break;
obj2[key] = obj[key];
}
console.log(obj, obj2);
let obj2 = {
...obj};
因为obj===obj2,返回的是false,也就证明obj2是被克隆出来的。
但是当你修改obj2.c.x的值:
你会发现,obj.c.x的值也被修改了。按理说obj和obj2应该没有联系了?
这就是因为浅克隆只把第一级克隆了,第二级没克隆,这样一来你操作第二级就也会对第一级造成影响。
在项目中假如用到的数据有很多层,你只是想修改一部分,而不想修改原有的数据结构,因此就肯定需要使用深克隆。
let obj2 = JSON.parse(JSON.stringify(obj));
虽然这种方式经常使用,但是需要说明的是,经过JSON.stringify处理后会变成字符串。但你可以发现,这个过程中,如果存放的有正则、函数就会变成空字符串。对于日期而言,我们想让它变成标准日期格式对象,现在它变成了字符串。这样显然是不好的。因此这种方式是有问题的,但实际上我们很少碰到存放正则、函数、日期的情况,所以暂且只要注意这三个情况就可以了。
最完善的方案:
function deepClone(obj){
if (obj === null) return null;
if (typeof obj !== "object") return obj;
if (obj instanceof RegExp) return new RegExp(obj);
if (obj instanceof Date) return new Date(obj);
let cloneObj = new obj.constructor;
for (let key in obj){
if (obj.hasOwnProperty(key)){
cloneObj[key] = deepClone(obj[key]);
}
}
return cloneObj;
}
let obj2 = deepClone(obj);
console.log(obj, obj2);
console.log(obj === obj2);
console.log(obj.c === obj2.c);
阿里的一道关于面向对象的面试题
function Foo(){
getName = function(){
console.log(1);
};
return this;
}
Foo.getName = function(){
console.log(2);
};
Foo.prototype.getName = function(){
console.log(3);
};
var getName = function(){
console.log(4);
}
function getName(){
console.log(5);
}
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
输出结果为:
所谓变量提升就是:在当前作用域下,所有js代码执行之前,将所有function函数提前声明定义、将所有var变量提前声明。
(即:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部)
在本题中,首先是变量提升,涉及到下面三个部分:
因此Foo函数被提前声明。然后是var getName被提前声明。(此时没有赋值)
最后getName函数被提前声明,但是发现getName已经被声明了,所以它会去给这个getName赋值。所以这一步的结果如下:
(Foo和getName各占据一段堆内存,为了便于看到输出结果,这里忽略堆内存地址号,直接用输出结果替代)
变量提升之后,代码执行:
对于以下部分:
运行Foo.getName,给Foo里getName声明赋值。
然后Foo.prototype.getName,就是给Foo的原型中添加getName。
因为原型也是对象,所以它也占据一段堆内存。
所以在这里会形成这样的结构:
然后是以下代码部分:
因为之前只是声明而没有赋值,所以在这里就又会去找那个getName然后赋值。
因此,输出结果中肯定不会出现5了。
最后分析输出结果:
根据之前的分析,画出图就很好理解了:
对于Foo().getName(),它是两步操作,先把Foo执行,再让它的返回结果执行getName()。需要注意的是,Foo执行时,它里面的getName并不是私有的,因此会去上级作用域寻找,即到了全局中寻找。因此全局下的getName再次发生了变化:
对于普通函数来说,return this的时候,就相当于return了 window 。
所以Foo()的返回结果是window。
因此Foo().getName() => window.getName()。此时getName结果为1。所以:
从以上可以发现,Foo加()和不加()是两个概念。
对于接下来的题,就需要涉及到JS运算符的优先执行顺序。
如下图,不加 () 就叫 无参数new ,加 () 就叫 有参数new。
.
的方式叫成员访问。
那么这三个到底是谁先运行呢?
(因为它可能是先 new Foo 再 getName(),也有可能是先 Foo.getName() 再 new )
查阅文档发现:
(优先级高的优先执行,相同优先级从左到右执行)
因此对于 new Foo.getName(),
先执行Foo.getName(),再new。
Foo.getName()返回的结果就是输出2的那个函数,
对它new还是把它当普通函数执行,输出结果为2.
同理对于 new Foo().getName(),
就是 从左到右,先执行 new Foo() ,再getName()。
new Foo()虽然也是函数执行,但它创建了一个当前函数的实例,实例调getName显然要去原型里面找了(因为最开始构建函数时,没给实例本身添加任何属性)
所以输出结果是3.
最后对于 new new Foo().getName(),有人如果对这个过程还是不了解的话,就可能会说,这优先级不都是19吗,那从左向右执行,怎么还出现new 一个 new 的操作?
实则不然。这其中 new Foo() 执行出来是个实例xxx,那么这里就相当于变成了:
new xxx.getName(),又回到了new Foo.getName()这个形式上。
因此,首先创建了一个当前函数的实例,实例调getName依然去原型里面找,返回的是一个输出3的函数,对它new还是把它当普通函数执行,输出结果为3.
头条的一道关于EventLoop的面试题
推荐文章:
eventloop解析:http://www.ruanyifeng.com/blog/2013/10/event_loop.html
理解async和await:https://segmentfault.com/a/1190000007535316
理解promise中的resolve:https://www.jianshu.com/p/5b0b89bf4664
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2(){
console.log('async2');
}
console.log('script start');
setTimeout(function(){
console.log('setTimeout');
},0)
async1();
new Promise(function(resolve){
console.log('promise1');
resolve();
}).then(function(){
console.log('promise2');
});
console.log('script end');
输出结果:
首先需要说明的是,浏览器是多线程的,而JS是单线程的,也就导致浏览器只给一个线程让它来渲染。
代码一行一行从上至下执行叫“同步”,反之就是“异步”。JS中大部分代码都是同步的。
而本题中就涉及到异步。
浏览器提供了一个:事件队列(EventQueue),里面存放的就是一些延后执行的任务,比如定时器。而在事件队列中,又分为微任务队列和宏任务队列。
整体的执行顺序就是:主线程代码先执行,执行过后,到事件队列中执行。在事件队列中,先去微任务队列中执行,没有微任务再去执行宏任务。等到宏任务都执行完了,浏览器也就空闲下来了。
那么现在回到本题中,从上到下的执行代码也就是主线程:
首先创建函数async1和async2,然后输出’script start’。
接下来碰到了一个定时器,需要说明的是,定时器属于宏任务,因此把这个定时器任务存放到事件队列的宏任务队列中。设置好之后,主线程代码继续执行,碰到了async1(),async1函数执行。因此接下来输出’async1 start’。
输出后,碰到了await async2()。它做的操作是:执行async2,等待返回的结果。
但它本身并不是同步操作,而是异步操作,属于微任务。因此async1函数的执行就停在了这个地方,等待主线程执行结束去执行微任务,返回结果后才会继续执行。
此时async2已经执行,所以输出’async2’。
但是到底返回了一个怎样的结果,可以参考一下上面的推荐文章。
因此接下来执行new Promise部分。
new Promise时,会立即把EC函数执行(即 new的时候 才是同步的)。
因此输出’promise1’。然后碰到了resolve(resolve和reject都属于微任务)。
所以Promise中的执行就停在了这个地方,等待主线程执行结束去执行微任务。
resolve / reject 执行的时候,把then / catch 中的方法执行。
主线程最后输出’script end’。(主栈第一阶段完成)
然后就是去事件队列中寻找了(先微任务后宏任务),找到任务后就拿回到主线程中执行。这个查找、运行、查找、运行…的操作,就叫做EventLoop。
在这里需要说明的是,在从微任务队列中查找任务时,不同的v8引擎会导致结果不同,即不一定是先获取到先存放的任务,所以在这里输出结果有可能不同。
那么假设先查找到了上图的B任务,那么接下来输出’async1 end’。
然后查找到了上图的C任务,那么接下来输出’promise2’。
最后执行到了宏任务,输出’setTimeout’,结束。
具体哪些是宏任务?哪些是微任务?以及它们的细节,感兴趣的大家可以查阅一下官方文档。
宏任务:定时器、事件绑定…
微任务:promise、 async、 await…
数据劫持和拦截
问,a等于什么值,才会console.log(1)?
var a = ?;
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
首先需要说明 ==
和 ===
的差异:
三个等于号不仅要比较值,也要比较数据类型。
两个等于号只比较值,不比较数据类型,但是它到底是如何实现这个比较的?
如果两个等于号左右两侧的数据类型不一样,它的转换规则为:
对象 == 字符串
:会使用 对象.toString() 把对象变成字符串
null == undefined
:相等,但是和其他值比较就不再相等了
NaN == NaN
: 不相等,NaN和任何值都不相等
- 剩下的所有情况比较时,都转换为数字
比如:"1"==true
,等号左右两侧全都会变成数字1
对于对象也是一样会转成数字
当你知道这上面的规则时,第一种方案就出现了:因为对象和数字比较需要先调用toString(),如果我们自己没设置toString()就会去调用原型上的toString(),那我们可以自己设置一个toString()效果,让它满足题目等式要求。
var a = {
i: 0,
toString() {
return ++this.i;
}
};
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
第二种方案:数据劫持和拦截(这也是之后Vue里要涉及到的知识点)
推荐文章:
数据劫持:https://www.jianshu.com/p/87a1ff1d7a3c
数据劫持和拦截的简例:
let obj = {
name: '1'
};
Object.defineProperty(obj, 'name', {
get() {
console.log('获取');
},
set() {
console.log('设置');
}
});
通过Object.defineProperties的设置,当我们获取obj.name时就会触发get,当我们设置obj.name时就会触发set,如下图:
(获取时出现的undefined,是因为get没有返回值)
那么数据劫持和拦截就是:监听某个对象里的某个属性,当它在获取和设置时做一系列操作。
因此根据这个特点,第二种方案为:
var i = 0;
Object.defineProperty(window, 'a', {
get() {
return ++i;
}
});
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
第一种方案toString的另一种实现方式:
var a = [1, 2, 3];
a.toString = a.shift;
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
练习题
function A(){
alert(1);
}
function Fn(){
A=function(){
alert(2);
};
return this;
}
Fn.A=A;
Fn.prototype={
A:()=>{
alert(3);
}
};
A();
Fn.A();
Fn().A();
new Fn.A();
new Fn().A();
new new Fn().A();
看起来和之前的题很像,唯一的区别就是这其中出现了箭头函数。
需要注意 原型对象上的A函数,是个箭头函数,箭头函数不能被new。
因此 new new Fn().A() 会报错。
箭头函数和普通函数的区别:
箭头函数没有自己的执行主体(this),它使用的this都是继承自己上下文的this。
普通函数有它自己的this。
箭头函数之所以不能被new,是因为它没有原型链prototype也就没有constructor构造器函数,所以它不能被new。
推荐文章:
箭头函数和普通函数:https://www.cnblogs.com/biubiuxixiya/p/8610594.html
因此输出结果:1、1、2、1、3、报错
var x = 2;
var y = {
x: 3,
z: (function (x) {
this.x *= x;
x += 2;
return function (n) {
this.x *= n;
x += 3;
console.log(x);
}
})(x)
};
var m = y.z;
m(4);
y.z(5);
console.log(x, y.x);
输出结果为:
var x = 0,
y = 1;
function fn() {
x += 2;
fn = function (y) {
console.log(y + (--x));
};
console.log(x, y);
}
fn(3);
fn(4);
console.log(x, y);
输出结果为:
算法相关面试题
将字符串进行驼峰命名
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<script type="text/javascript">
function toString(foo) {
var arr = foo.split('-');
for(var i = 1; i < arr.length; i++) {
arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substr(1, arr[i].length - 1)
}
return arr.join('');
}
console.log(toString('get-element-by-id'));
script>
body>
html>
冒泡排序
如果有兴趣看其他的排序方式及思路,大家可以去我之前的文章查阅一下:
https://blog.csdn.net/qq_45613931/article/details/104693885
虽然是后台Java语法的,但是整体思路和实现方式没有差异。
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<script type="text/javascript">
var arr = [32,4,67,82,21,11];
for(var i = 0; i<arr.length-1;i++){
for(var j = 0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr);
script>
body>
html>
反转数组
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<script type="text/javascript">
var arr = [1, 2, 3, 4, 5, 6, 7, 8];
for (var i = 0; i < arr.length / 2; i++) {
var temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
console.log(arr);
script>
body>
html>
去掉数组中重复性的数据
推荐文章:
https://blog.csdn.net/weixin_42412046/article/details/81459294
思路1:只用到原数组。遍历原数组,每次都拿原数组的中的一个值,和它后面的所有值比较,一旦出现重复,就把当前值从原数组中去掉,然后遍历到下一个值。
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
for (let i = 0; i < ary.length - 1; i++) {
let item = ary[i],
args = ary.slice(i + 1);
if (args.indexOf(item) > -1) {
ary.splice(i, 1);
i--;
}
}
console.log(ary);
但是对于思路1会出现一些问题:使用splice删除了原数组中的当前重复数据项,后面所有项的索引都要发生改变,一旦原数组中存放的数据很多,在性能方面一定很差。同时因为原数组的改变,一定需要i--
,否则会产生数组塌陷问题。
为了避免对原数组进行操作,因此从思路1的思路继续出发,思路2:我们可以再建一个新数组,一旦判断出当前项不重复,就把当前项放入新数组。
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
let arr = [];
for (let i = 0; i < ary.length - 1; i++) {
let item = ary[i],
args = ary.slice(i + 1);
if (i + 1 == ary.length - 1) {
arr.push(ary[i + 1]);
}
if (args.indexOf(item) > -1) {
} else {
arr.push(item);
}
}
console.log(arr);
对于思路2,需要注意的是,在思路1代码的基础上,一定要把最后一项加入到新数组
当然也有办法,让我们只对原数组进行操作,且避免数组塌陷问题的。
思路3:在遍历时,将重复的元素设为null,遍历结束后,把这些null从原数组中去除。
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
for (let i = 0; i < ary.length - 1; i++) {
let item = ary[i],
args = ary.slice(i + 1);
if (args.indexOf(item) > -1) {
ary[i] = null;
}
}
ary = ary.filter(item => item !== null);
console.log(ary);
但是这么做其实有一个二次处理的过程,性能上也不太好。当然还有其他办法.
思路4:当我们发现重复项,我们不去删除它,而是把数组最后一项赋值到第一项,这样一来也就实现了删除的效果,同时没有数组塌陷问题。然后把最后一项删除。
需要注意的是,我们把最后一项放到了当前项上,所以需要i--
,继续从当前索引位置开始进行判断。
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
for (let i = 0; i < ary.length - 1; i++) {
let item = ary[i],
args = ary.slice(i + 1);
if (args.indexOf(item) > -1) {
ary[i] = ary[ary.length-1];
ary.length--;
i--;
}
}
console.log(ary);
在前面的代码中,都用到了indexOf,但是indexOf有兼容性问题。
那么接下来就不使用indexOf来实现。
思路5:模拟indexOf实现
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
let obj = {
};
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
if (typeof obj[item]!=='undefined') {
ary[i] = ary[ary.length-1];
ary.length--;
i--;
continue;
}
obj[item] = item;
}
console.log(ary);
思路6:
1.创建一个新数组,把原数组中的第一个元素插入到新数组中
2.遍历原数组中的每一个元素分别和新数组中的每一个元素进行比较
3.一旦原数组的某个元素和新数组的值都没有重复,那么就把它加入到新数组中
var arr = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
var t = [];
t[0] = arr[0];
for (var i = 0; i < arr.length; i++) {
for (var k = 0; k < t.length; k++) {
if (t[k] == arr[i]) {
break;
}
if (k == t.length - 1) {
t.push(arr[i]);
}
}
}
console.log(t);
思路7:先排序,再相邻比较
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
ary.sort((a, b) => a - b);
for (let i = 0; i < ary.length; i++) {
if(ary[i] == ary[i+1]){
ary[i] = null;
}
}
ary = ary.filter(item => item !== null);
console.log(ary);
思路8:先排序,再相邻比较(基于正则)
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
ary.sort((a, b) => a - b);
ary = ary.join('@');
console.log(ary);
let reg = /(\d+@)\1*/g,
arr = [];
ary.replace(reg, (n, m) => {
arr.push(Number(m.slice(0, m.length - 1)));
});
console.log(arr);
思路9:利用Set就简单的多了,但是需要注意Set是ES6中才出现的。
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
let arr = [...new Set(ary)];
console.log(arr);
let ary = [8, 11, 20, 5, 20, 8, 0, 2, 4, 0, 8];
let arr = Array.from(new Set(ary));
console.log(arr);
更多方法可以参考推荐文章。
数组扁平化的实现方案
数组扁平化:把多维数组变成一维数组。
方案一:ES6 方法直接实现
let arr = [
[1, 2, 2],
[3, 4, 5, 5],
[6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];
arr = arr.flat(Infinity);
console.log(arr);
方案二:
首先arr.toString,arr就会变成一串数字,并用逗号分隔,而且它不是数组。
那我们就可以用split(',')
让它变成数组,并根据逗号区分出每个元素。
之后会发现,数组中存放的每个数字变成了字符串。
然后用map,把每个元素变成数字,即可。
let arr = [
[1, 2, 2],
[3, 4, 5, 5],
[6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];
arr = arr.toString().split(',').map(item => parseFloat(item));
console.log(arr);
方案三:
let arr = [
[1, 2, 2],
[3, 4, 5, 5],
[6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];
arr = JSON.stringify(arr).replace(/(\[|\])/g,'').split(',').map(item => parseFloat(item));
console.log(arr);
方案四:
let arr = [
[1, 2, 2],
[3, 4, 5, 5],
[6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];
while(arr.some(item => Array.isArray(item))){
arr = [].concat(...arr);
}
console.log(arr);
方案五:
let arr = [
[1, 2, 2],
[3, 4, 5, 5],
[6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];
(function () {
function myFlat() {
let result = [],
_this = this;
let fn = (arr) => {
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
if (Array.isArray(item)) {
fn(item);
continue;
}
result.push(item);
}
};
fn(_this);
return result;
}
Array.prototype.myFlat = myFlat;
})();
arr = arr.myFlat();
console.log(arr);
斐波那契数列
方法一:
function fibonacci(count) {
if (count <= 1) return 1;
let arr = [1, 1];
let i = count + 1 - 2;
while (i > 0) {
let a = arr[arr.length - 2],
b = arr[arr.length - 1];
arr.push(a+b);
i--;
}
return arr[arr.length-1];
}
console.log(fibonacci(5));
方法二:
function fibonacci(count) {
function fn(count,curr=1,next=1){
if(count==0){
return curr;
}else{
return fn(count-1,next,curr+next);
}
};
return fn(count);
}
console.log(fibonacci(5));
React和Vue比较
相同点
- 都有组件化开发和Virtual DOM
- 都支持props进行父子组件间数据通信
- 都支持数据驱动视图, 不直接操作真实DOM, 更新状态数据界面就自动更新
- 都支持服务器端渲染
不同点
- 数据绑定: vue实现了数据的双向绑定,react数据流动是单向的
- 组件写法不一样, React推荐的做法是 JSX , 也就是把HTML和CSS全都写进JavaScript了,即’all in js’; Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,js写在同一个文件
- state对象在react应用中不可变的,需要使用setState方法更新状态;在vue中,state对象不是必须的,数据由data属性在vue对象中管理
- virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制
- React严格上只针对MVC的view层,Vue则是MVVM模式
Vue 相关面试题
(因为我只使用Vue,因此React我也就无法提供相关内容了)
推荐文章:
vue3.0相关内容:https://blog.csdn.net/DevolperFront/article/details/104352036
首先vue3.0版本目前还有很长的路要走,还没有开始正式使用,所以在项目中肯定还是用2.0,但是我们准备面试肯定多多少少理解了一些3.0的特性。因此在回答这一类问题时,可以这么回答:
在Vue2.0中,这个需求在我平常的项目中曾经遇到过,可以这么做: xxxx …
当我Vue2.0使用的熟练了后,我就开始研究它的底层实现原理,这时候才知道原来双向数据绑定的底层实现原理是ES5中新加的Object.defineProperty来进行数据劫持和拦截的(说一些和问题相关的底层原理),它的实现思路是…
虽然3.0还没有投入到实战,但我经常关注博客文章(或者去GitHub下载源码),看了大家对3.0的评价(或者对代码的分析),发现在Vue3.0中,双向数据绑定的底层实现原理是ES6的Proxy(说一些和问题相关的一些特性…),它相对于2.0有…这样的好处。
Vue2.0/3.0双向数据绑定的实现原理
推荐文章:
Vue3.0双向数据绑定原理:https://www.jianshu.com/p/68c3e8f2e785
双向数据绑定就是:当数据改变的时候,让视图重新渲染。
Vue2.0:ES5:Object.defineProperty
<body>
姓名:<span id="spanName">span>
<br>
<input type="text" id="inpName">
<script>
let obj = {
name: ''
};
let newObj = JSON.parse(JSON.stringify(obj));
Object.defineProperty(obj, 'name', {
get() {
return newObj.name;
},
set(val) {
if (val === newObj.name) return;
newObj.name = val;
observe();
}
});
function observe() {
spanName.innerHTML = obj.name;
inpName.value = obj.name;
}
setTimeout(() => {
obj.name = "你好";
}, 1000);
inpName.oninput = function () {
obj.name = this.value;
};
script>
body>
可以发现,defineProperty方式会有以下问题:
首先遇到defineProperty就一定要克隆原始数据,避免发生死循环,
因为如果是直接对原数据劫持和拦截get() {return obj.name;}
,
当运行到return obj.name
时,就相当于又去obj中获取name,又会去执行get…
这样就不断执行get,从而陷入死循环。
其次,get和set里,我们只能一个一个地给每个属性赋新值,
即:需要分别给对象中每个属性设置监听。
同时正因如此,如果在运行过程中,给对象添加了新的属性,(显然在最开始没有给它设置监听),就算是$set,将新属性添加其中,也会因为最开始没给它设置监听,从而实现不出效果。
因为2.0的实现方式会有上述问题,所以在Vue3.0,就对它进行了改进,使用了ES6的Proxy。首先先来看看Proxy的简单用法和实现效果:
let obj = {
};
obj = new Proxy(obj, {
get(target, prop){
console.log('A');
return target[prop];
},
set(target, prop, value){
console.log('B');
target[prop] = value;
}
});
通过输出结果就可以看到:Proxy方式不用克隆原始数据,而且可以实时向对象中添加属性,还能为它设置监听,从而完美解决了问题。
因此现在来看一看到底如何去做:
Vue3.0:ES6:Proxy
<body>
姓名:<span id="spanName">span>
<br>
<input type="text" id="inpName">
<script>
let obj = {
};
obj = new Proxy(obj, {
get(target, prop){
return target[prop];
},
set(target, prop, value){
target[prop] = value;
observe();
}
});
function observe() {
spanName.innerHTML = obj.name;
inpName.value = obj.name;
}
setTimeout(() => {
obj.name = "你好";
}, 1000);
inpName.oninput = function () {
obj.name = this.value;
};
script>
body>
MVC和MVVM的区别
React:MVC,Vue:MVVM。
推荐文章:
MVC和MVVM区别:https://zhuanlan.zhihu.com/p/64257809
MVVM:
首先有一个监听,会监听这个输入框内容,当输入框中的内容发生了改变,监听器就触发。这个监听器的回调函数就会把输入框的内容保存到data里,同时将这个数据输出到页面里去显示。而这个过程就会用到DOM监听和数据绑定。实现原理已经在上面说过了。
MVVM:
model:模型,数据对象(data)
view:视图,模板页面
viewModel:视图模型(Vue的实例)
在代码中的体现:
因为我对React不熟,所以对于MVC没有去太深的理解。
简单来说,
MVC少了一个视图更改数据,因此它叫单向数据更改。即单向指的是:数据的更改控制视图。而MVVM不仅实现了数据的更改控制视图,也实现了视图的更改控制数据。
在编码方面上来说,Vue中,通过原理,我们可以发现,Vue帮我们做好了oninput和onchange事件,而React没有实现它们,需要我们自己去实现,但是实现方式还是很简单的。
跨域问题
推荐文章:
跨域问题:http://www.imooc.com/article/36861
跨域问题的产生及其价值意义
当我们基于ajax向服务器发送请求,在浏览器处理的时候,它有一个特点:
只要协议、域名、端口有任何一个不同,都被当作是不同的域,而服务器是不允许跨域访问的。
比如:
(http默认端口号80,https默认端口号443,ftp默认端口号21)
在前后端没分离的时候,肯定就不会遇到这样的问题,因为当时后台程序和客户端程序都会部署在同一台服务器上,同一个域下,同一个端口号上。
随后在前后端分离的初期,也是部署在同一台服务器上的。
但之后随着前后端的不断发展,也就发现,前后端貌似没必要一定在一个服务器上。
因此区分出了 数据服务器和Web服务器。
这么做的好处在于:
数据服务器专门用于处理 业务逻辑和数据接口,而Web服务器主要用来 请求一些资源文件。这样一来做服务器集群部署的时候,就可以把Web服务器在全国各地建立站点,然后当你访问服务器的时候,就可以总是访问最近的服务器。
(从成本等方面上来看,肯定不能把数据服务器也部署到全国各地)
这样之后,从Web服务器上拿接口,就不在一个服务器上了,所以跨域问题就出现了
解决方案
(因为我对这部分也只是简单认识,也许有的地方说的不对,详细的部分大家可以百度查找,写下这部分也是因为听闻有些公司的前端需要仔细研究跨域问题)
阶段一:JSONP跨域解决方案:
最开始的跨域解决方案都是使用JSONP。JSONP利用了一个特点:ajax发请求会存在域的限制,但有一些东西发请求不需要限制,
比如
标签、
标签、
标签。
平常在项目中,我们就经常这么用:
script请求资源一定是get请求,它不存在域的限制。
原理:
即:动态创建一个script标签,把要向服务器发送请求的地址,赋值给script里的src。然后是怎么做的呢?
首先通过问号传参的方式,我们传一个函数func给服务器(这个方法是我们自己写的)(这种方式只能是Get请求)
当服务器拿到这个请求之后,就会去准备数据,然后把数据返回到客户端。
那么服务器如何把数据传回来呢?服务器会拿到函数func,并把它拼成字符串:
"func({...})"
(把我们想要的数据拼接成这样的结果)
然后客户端就相当于拿到了"func({...})"
,里面有我们想要的数据。(浏览器会帮我们执行这个函数)
但是Get会有一系列问题:不安全、有缓存、传递的信息有大小限制…
同时服务器还得能帮我们把数据进行一系列拼接,来帮我们实现功能。
因此目前JSONP已经很少用了。
阶段二:基于iframe的跨域解决方案
(详情可见推荐文章,这也是前几年的解决方案了)
阶段三:CORS跨域资源共享
以前不能发请求,是因为服务器不允许,所以现在的做法就是让服务器允许这么做。
客户端:
import axios from 'axios';
import qs from 'qs';
axios.defaults.baseURL = "http://127.0.0.1:3000";
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.transfromRequest = data =>qs.stringify(data);
axios.interceptors.request.use(config => {
let token = localStorage.getItem('token');
token && (config.headers.Authorization = token);
return config;
}, error =>{
return Promise.reject(error);
});
axios.interceptors.response.use(response =>{
return response.data;
}, error =>{
});
export default axios;
服务器端:
除此以外还有 基于http proxy实现跨域请求、nginx反向代理…感兴趣的可以查阅百度
Vue组件间通信方式
(面试基本必问,然后回答到vuex方式时,面试官就会问vuex的工作原理)
通信方式相关内容,可以参考我之前的文章:
https://blog.csdn.net/qq_45613931/article/details/105812344
通信种类
- 父组件向子组件通信
- 子组件向父组件通信
- 隔代组件间通信
- 兄弟组件间通信
方式1: props(属性传递)
组件之间联系需要import,想要映射组件标签需要components。最基本的传递就可以通过这个组件标签直接传递
(xxx:组件标签名,yyy:传递的对象属性或者方法)
如:
传递过去后,接收的组件用props就可以接收到传递过来的数据。
props一共有三种使用方式:
props:{ //指定属性名和属性值的类型
comment: Object
}
props:{
addComment:{ //最完整写法:指定属性名/属性值的类型/必要性
type:Function,
required: true
}
}
props: ['comments']
方式1:只能父向子通信,不能子向父通信。隔代组件和兄弟组件间通信比较麻烦。
方式2: vue自定义事件($on / $emit)
绑定事件监听:
@delete_todo="deleteTodo"
this.$refs.xxx.$on('delete_todo', function (todo) {
this.deleteTodo(todo)
})
触发事件:
this.$emit(eventName, data)
比如:(方式一)
<template>
<div>
<header>
....
header>
<div class="container">
<Add @addComment="addComment"/>
div>
div>
template>
<script>
import Add from './components/Add.vue'
export default {
data(){
return{
comments:[
{
name: 'BoB',
content: 'Vue 还不错'
},
{
name: 'Cat',
content: 'Vue so Easy'
}
]
}
},
methods:{
addComment(comment){
this.comments.unshift(comment)
}
},
components: {
Add
}
}
script>
<style>
style>
(方式二)
<template>
<div>
<header class="site-header jumbotron">
...
header>
<div class="container">
<Add ref="add"/>
div>
div>
template>
<script>
import Add from './components/Add.vue'
export default {
data(){
return{
comments:[
{
name: 'BoB',
content: 'Vue 还不错'
},
{
name: 'Cat',
content: 'Vue so Easy'
}
]
}
},
mounted(){
this.$refs.add.$on('addComment',this.addComment)
},
methods:{
addComment(comment){
this.comments.unshift(comment)
}
},
components: {
Add
}
}
script>
<style>
style>
Add.vue
<template>
<div class="col-md-4">
...
div>
template>
<script>
export default {
data(){
return{
name:'',
content:''
}
},
methods:{
add(){
const name = this.name.trim()
const content = this.content.trim()
if(!name || !content){
alert('姓名或内容不能空')
return
}
const comment = {
name,
content
}
this.$emit('addComment',comment)
this.name = ''
this.content = ''
}
}
}
script>
<style>
style>
方式2: 只适合于子向父通信。隔代组件或兄弟组件间通信此种方式不合适。
方式3: 消息订阅与发布
想使用这种方式,需要安装:
npm i --save pubsub-js
订阅消息
PubSub.subscribe('msg', function(msg, data){})
发布消息
PubSub.publish('msg', data)
比如:
<template>
<div>
<header class="site-header jumbotron">
...
header>
<div class="container">
<Add/>
div>
div>
template>
<script>
import PubSub from 'pubsub-js'
import Add from './components/Add.vue'
export default {
data(){
return{
comments:[
{
name: 'BoB',
content: 'Vue 还不错'
},
{
name: 'Cat',
content: 'Vue so Easy'
}
]
}
},
mounted(){
PubSub.subscribe('addComment',(msg,comment) => {
this.addComment(comment)
})
},
methods:{
addComment(comment){
this.comments.unshift(comment)
}
},
components: {
Add
}
}
script>
<style>
style>
Add.vue
<template>
<div class="col-md-4">
...
div>
template>
<script>
import PubSub from 'pubsub-js'
export default {
data(){
return{
name:'',
content:''
}
},
methods:{
add(){
const name = this.name.trim()
const content = this.content.trim()
if(!name || !content){
alert('姓名或内容不能空')
return
}
const comment = {
name,
content
}
PubSub.publish('addComment',comment)
this.name = ''
this.content = ''
}
}
}
script>
<style>
style>
方式3: 此方式可实现任意关系组件间通信(数据)
方式4: vuex
vuex是vue官方提供的集中式管理vue多组件共享状态数据的vue插件
优点: 对组件间关系没有限制, 且相比于pubsub库管理更集中, 更方便
方式5: slot(插槽)
子组件: Child.vue
<template>
<div>
<slot name="xxx">不确定的标签结构 1slot>
<div>组件确定的标签结构div>
<slot name="yyy">不确定的标签结构 2slot>
div>
template>
父组件: Parent.vue
<child>
<div slot="xxx">xxx 对应的标签结构div>
<div slot="yyy">yyyy 对应的标签结构div>
child>
方式5: 专门用来实现父向子传递带数据的标签
(注意: 通信的标签模板是在父组件中解析好后再传递给子组件的)
用了这种方式以后,就相当于子组件用到的所有属性或方法全都需要从子组件移动到父组件中,除了样式。平常肯定不推荐这么使用,它用在什么地方呢?这样设计之后,比如可能会多次用到这个子组件(即:很多类似的组件,就没必要建好多个了,直接用这种模板就行了,只要在父组件中设置好slot,就能使用了),这样一来就能满足重用性。
vuex管理状态的机制
详细vuex可以参考我之前的文章:
https://blog.csdn.net/qq_45613931/article/details/105903799
对Vuex基本理解
- 是什么: Vuex 是一个专为 Vue.js 应用程序开发的状态管理的vue插件
- 作用: 集中式管理vue多个组件共享的状态和从后台获取的数据
工作原理
你可能感兴趣的:(前端内容,css,html,javascript,vue)
- element实现动态路由+面包屑
软件技术NINI
vue案例vue.js前端
el-breadcrumb是ElementUI组件库中的一个面包屑导航组件,它用于显示当前页面的路径,帮助用户快速理解和导航到应用的各个部分。在Vue.js项目中,如果你已经安装了ElementUI,就可以很方便地使用el-breadcrumb组件。以下是一个基本的使用示例:安装ElementUI(如果你还没有安装的话):你可以通过npm或yarn来安装ElementUI。bash复制代码npmi
- Long类型前后端数据不一致
igotyback
前端
响应给前端的数据浏览器控制台中response中看到的Long类型的数据是正常的到前端数据不一致前后端数据类型不匹配是一个常见问题,尤其是当后端使用Java的Long类型(64位)与前端JavaScript的Number类型(最大安全整数为2^53-1,即16位)进行数据交互时,很容易出现精度丢失的问题。这是因为JavaScript中的Number类型无法安全地表示超过16位的整数。为了解决这个问
- swagger访问路径
igotyback
swagger
Swagger2.x版本访问地址:http://{ip}:{port}/{context-path}/swagger-ui.html{ip}是你的服务器IP地址。{port}是你的应用服务端口,通常为8080。{context-path}是你的应用上下文路径,如果应用部署在根路径下,则为空。Swagger3.x版本对于Swagger3.x版本(也称为OpenAPI3)访问地址:http://{ip
- html 中如何使用 uniapp 的部分方法
某公司摸鱼前端
htmluni-app前端
示例代码:Documentconsole.log(window);效果展示:好了,现在就可以uni.使用相关的方法了
- 第四天旅游线路预览——从换乘中心到喀纳斯湖
陟彼高冈yu
基于Googleearthstudio的旅游规划和预览旅游
第四天:从贾登峪到喀纳斯风景区入口,晚上住宿贾登峪;换乘中心有4路车,喀纳斯①号车,去喀纳斯湖,路程时长约5分钟;将上面的的行程安排进行动态展示,具体步骤见”Googleearthstudio进行动态轨迹显示制作过程“、“Googleearthstudio入门教程”和“Googleearthstudio进阶教程“相关内容,得到行程如下所示:Day4-2-480p
- 下载github patch到本地
小米人er
我的博客gitpatch
以下是几种从GitHub上下载以.patch结尾的补丁文件的方法:通过浏览器直接下载打开包含该.patch文件的GitHub仓库。在仓库的文件列表中找到对应的.patch文件。点击该文件,浏览器会显示文件的内容,在页面的右上角通常会有一个“Raw”按钮,点击它可以获取原始文件内容。然后在浏览器中使用快捷键(如Ctrl+S或者Command+S)将原始文件保存到本地,选择保存的文件名并确保后缀为.p
- SQL Server_查询某一数据库中的所有表的内容
qq_42772833
SQLServer数据库sqlserver
1.查看所有表的表名要列出CrabFarmDB数据库中的所有表(名),可以使用以下SQL语句:USECrabFarmDB;--切换到目标数据库GOSELECTTABLE_NAMEFROMINFORMATION_SCHEMA.TABLESWHERETABLE_TYPE='BASETABLE';对这段SQL脚本的解释:SELECTTABLE_NAME:这个语句的作用是从查询结果中选择TABLE_NAM
- 四章-32-点要素的聚合
彩云飘过
本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters.
- DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理
STU学生网页设计
网页设计期末网页作业html静态网页html5期末大作业网页设计web大作业
️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程
- 少了生活气息
我爱大草莓
最近啊,总觉得自己日更的内容缺了点什么。我仔细地想,大概是少了些生活气息。这两三个月减少了许多与别人相处的时间,独自生活,偶尔只是出去买菜,总觉得生活好像变空了许多。买菜的时候会跟档口的阿姨聊一两句话,让自己感觉在真实地生活着。幸好我也不是一宅到底,偶尔周末也会约着跟好朋友见面,面对面交流跟隔着屏幕交流,效果还是不一样的,至少有更为真实的生活感。写作不仅需要有阅读量,有文笔,生活阅历也是非常重要的
- 【加密社】Solidity 中的事件机制及其应用
加密社
闲侃区块链智能合约区块链
加密社引言在Solidity合约开发过程中,事件(Events)是一种非常重要的机制。它们不仅能够让开发者记录智能合约的重要状态变更,还能够让外部系统(如前端应用)监听这些状态的变化。本文将详细介绍Solidity中的事件机制以及如何利用不同的手段来触发、监听和获取这些事件。事件存储的地方当我们在Solidity合约中使用emit关键字触发事件时,该事件会被记录在区块链的交易收据中。具体而言,事件
- 使用Apify加载Twitter消息以进行微调的完整指南
nseejrukjhad
twittereasyui前端python
#使用Apify加载Twitter消息以进行微调的完整指南##引言在自然语言处理领域,微调模型以适应特定任务是提升模型性能的常见方法。本文将介绍如何使用Apify从Twitter导出聊天信息,以便进一步进行微调。##主要内容###使用Apify导出推文首先,我们需要从Twitter导出推文。Apify可以帮助我们做到这一点。通过Apify的强大功能,我们可以批量抓取和导出数据,适用于各类应用场景。
- 如何部分格式化提示模板:LangChain中的高级技巧
nseejrukjhad
langchainjava服务器python
标题:如何部分格式化提示模板:LangChain中的高级技巧内容:如何部分格式化提示模板:LangChain中的高级技巧引言在使用大型语言模型(LLM)时,提示工程是一个关键环节。LangChain提供了强大的提示模板功能,让我们能更灵活地构建和管理提示。本文将介绍LangChain中一个高级特性-部分格式化提示模板,这个技巧可以让你的提示管理更加高效和灵活。什么是部分格式化提示模板?部分格式化提
- 关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript
二挡起步
web前端期末大作业javascripthtmlcss旅游风景
⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip
- HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动
二挡起步
web前端期末大作业web设计网页规划与设计htmlcssjavascriptdreamweaver前端
Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线
- Python快速入门 —— 第三节:类与对象
孤华暗香
Python快速入门python开发语言
第三节:类与对象目标:了解面向对象编程的基础概念,并学会如何定义类和创建对象。内容:类与对象:定义类:class关键字。类的构造函数:__init__()。类的属性和方法。对象的创建与使用。示例:classStudent:def__init__(self,name,age,major):self.name
- webpack图片等资源的处理
dmengmeng
需要的loaderfile-loader(让我们可以引入这些资源文件)url-loader(其实是file-loader的二次封装)img-loader(处理图片所需要的)在没有使用任何处理图片的loader之前,比如说css中用到了背景图片,那么最后打包会报错的,因为他没办法处理图片。其实你只想能够使用图片的话。只加一个file-loader就可以,打开网页能准确看到图片。{test:/\.(p
- ARM中断处理过程
落汤老狗
嵌入式linux
一、前言本文主要以ARM体系结构下的中断处理为例,讲述整个中断处理过程中的硬件行为和软件动作。具体整个处理过程分成三个步骤来描述:1、第二章描述了中断处理的准备过程2、第三章描述了当发生中的时候,ARM硬件的行为3、第四章描述了ARM的中断进入过程4、第五章描述了ARM的中断退出过程本文涉及的代码来自3.14内核。另外,本文注意描述ARM指令集的内容,有些sourcecode为了简短一些,删除了T
- node.js学习
小猿L
node.jsnode.js学习vim
node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行
- 如何成为段子手
欣雅阅读
我是一个尬聊大师,与朋友聊天经常把话题聊死,留我一个人在群里,望着自己打下的最后一句话无语凝噎。看到风趣幽默的朋友与人聊天,很是艳羡,觉得自己何时才能成为这样的段子手呢?一、段子是什么?“段子”一词在百度百科上的解释:本是相声中的一个艺术术语,指的是相声作品中一节或一段艺术内容。我的理解:段子就是一些搞笑的故事或者笑话。二、为什么要会说段子?不知道大家有没有这样的朋友,本来很无趣的聚会,只要有他参
- Python爬虫解析工具之xpath使用详解
eqa11
python爬虫开发语言
文章目录Python爬虫解析工具之xpath使用详解一、引言二、环境准备1、插件安装2、依赖库安装三、xpath语法详解1、路径表达式2、通配符3、谓语4、常用函数四、xpath在Python代码中的使用1、文档树的创建2、使用xpath表达式3、获取元素内容和属性五、总结Python爬虫解析工具之xpath使用详解一、引言在Python爬虫开发中,数据提取是一个至关重要的环节。xpath作为一门
- 01-Git初识
Meereen
Gitgit
01-Git初识概念:一个免费开源,分布式的代码版本控制系统,帮助开发团队维护代码作用:记录代码内容。切换代码版本,多人开发时高效合并代码内容如何学:个人本机使用:Git基础命令和概念多人共享使用:团队开发同一个项目的代码版本管理Git配置用户信息配置:用户名和邮箱,应用在每次提交代码版本时表明自己的身份命令:查看git版本号git-v配置用户名gitconfig--globaluser.name
- ARM驱动学习之基础小知识
JT灬新一
ARM嵌入式arm开发学习
ARM驱动学习之基础小知识•sch原理图工程师工作内容–方案–元器件选型–采购(能不能买到,价格)–原理图(涉及到稳定性)•layout画板工程师–layout(封装、布局,布线,log)(涉及到稳定性)–焊接的一部分工作(调试阶段板子的焊接)•驱动工程师–驱动,原理图,layout三部分的交集容易发生矛盾•PCB研发流程介绍–方案,原理图(网表)–layout工程师(gerber文件)–PCB板
- Xinference如何注册自定义模型
玩人工智能的辣条哥
人工智能AI大模型Xinference
环境:Xinference问题描述:Xinference如何注册自定义模型解决方案:1.写个model_config.json,内容如下{"version":1,"context_length":2048,"model_name":"custom-llama-3","model_lang":["en","ch"],"model_ability":["generate","chat"],"model
- ExpRe[25] bash外的其它shell:zsh和fish
tritone
ExpRebashlinuxubuntushell
文章目录zsh基础配置实用特性插件`autojump`语法高亮自动补全fish优点缺点时效性本篇撰写时间为2021.12.15,由于计算机技术日新月异,博客中所有内容都有时效和版本限制,具体做法不一定总行得通,链接可能改动失效,各种软件的用法可能有修改。但是其中透露的思想往往是值得学习的。本篇前置:ExpRe[10]Ubuntu[2]准备神秘软件、备份恢复软件https://www.cnblogs
- 母亲节如何做小红书营销
美橙传媒
小红书的一举一动引起了外界的高度关注。通过爆款笔记和流行话题,我们可以看到“干货”类型的内容在小红书中偏向实用的生活经验共享和生活指南非常受欢迎。根据运营社的分析,这种现象是由小红书用户心智和内容社区背后机制共同决定的。首先,小红书将使用“强搜索”逻辑为用户提供特定的“搜索场景”。在“我必须这样生活”中,大量使用了满足小红书站用户喜好和需求的内容。内容社区自制的高质量内容也吸引了寻找营销新途径的品
- 【从浅识到熟知Linux】Linux发展史
Jammingpro
从浅学到熟知Linuxlinux运维服务器
归属专栏:从浅学到熟知Linux个人主页:Jammingpro每日努力一点点,技术变化看得见文章前言:本篇文章记录Linux发展的历史,因在介绍Linux过程中涉及的其他操作系统及人物,本文对相关内容也有所介绍。文章目录Unix发展史Linux发展史开源Linux官网企业应用情况发行版本在学习Linux前,我们可能都会问Linux从哪里来?它是如何发展的。但在介绍Linux之前,需要先介绍一下Un
- Linux sh命令
fengyehongWorld
Linuxlinux
目录一.基本语法二.选项2.1-c字符串中读取内容,并执行2.1.1基本用法2.1.2获取当前目录下失效的超链接2.2-x每个命令执行之前,将其打印出来2.3结合Here文档使用一.基本语法⏹Linux和Unix系统中用于执行shell脚本或运行命令的命令。sh[选项][脚本文件][参数...]⏹选项-c:从字符串中读取内容,并执行。-x:在每个命令执行之前,将其打印出来。-s:从标准流中读取内容
- Linux vi常用命令
fengyehongWorld
Linuxlinux
参考资料viコマンド(vimコマンド)リファレンス目录一.保存系命令二.删除系命令三.移动系命令四.复制粘贴系命令一.保存系命令⏹保存并退出:wq⏹强制保存并退出:wq!⏹退出(文件未编辑):q⏹强制退出(忽略已编辑内容):q!⏹另存为:w新文件名二.删除系命令⏹删除当前行dd⏹清空整个文档gg:移动到文档顶部dG:删除到最后一行ggdG三.移动系命令⏹移动到文档顶部gg⏹移动到文档底部#方式1G
- 《吹牛大王历险记》读书随笔
赵炳森
这本书的作者是埃·拉斯伯戈·毕尔格。(没查到相关内容,好像他只写过《吹牛大王历险记》。)最让人百思不得其解的是他居然能自己拉自己的辫子出泥潭?!我觉得自己拉自己的辫子只会把自己的辫子拉断,而不会飞出泥潭。(问:图片中底下的屁股为什么插了一根钢针?)屁股底下居然有根钢针?在泥潭应该是滑滑的吧,可是他怎么能夹紧马肚呢?马肚子应该是在马的下方。还有如果能从泥潭里把连人带马都给拽出来的话,他力气肯定很大,
- JAVA中的Enum
周凡杨
javaenum枚举
Enum是计算机编程语言中的一种数据类型---枚举类型。 在实际问题中,有些变量的取值被限定在一个有限的范围内。 例如,一个星期内只有七天 我们通常这样实现上面的定义:
public String monday;
public String tuesday;
public String wensday;
public String thursday
- 赶集网mysql开发36条军规
Bill_chen
mysql业务架构设计mysql调优mysql性能优化
(一)核心军规 (1)不在数据库做运算 cpu计算务必移至业务层; (2)控制单表数据量 int型不超过1000w,含char则不超过500w; 合理分表; 限制单库表数量在300以内; (3)控制列数量 字段少而精,字段数建议在20以内
- Shell test命令
daizj
shell字符串test数字文件比较
Shell test命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。 数值测试 参数 说明 -eq 等于则为真 -ne 不等于则为真 -gt 大于则为真 -ge 大于等于则为真 -lt 小于则为真 -le 小于等于则为真
实例演示:
num1=100
num2=100if test $[num1]
- XFire框架实现WebService(二)
周凡杨
javawebservice
有了XFire框架实现WebService(一),就可以继续开发WebService的简单应用。
Webservice的服务端(WEB工程):
两个java bean类:
Course.java
package cn.com.bean;
public class Course {
private
- 重绘之画图板
朱辉辉33
画图板
上次博客讲的五子棋重绘比较简单,因为只要在重写系统重绘方法paint()时加入棋盘和棋子的绘制。这次我想说说画图板的重绘。
画图板重绘难在需要重绘的类型很多,比如说里面有矩形,园,直线之类的,所以我们要想办法将里面的图形加入一个队列中,这样在重绘时就
- Java的IO流
西蜀石兰
java
刚学Java的IO流时,被各种inputStream流弄的很迷糊,看老罗视频时说想象成插在文件上的一根管道,当初听时觉得自己很明白,可到自己用时,有不知道怎么代码了。。。
每当遇到这种问题时,我习惯性的从头开始理逻辑,会问自己一些很简单的问题,把这些简单的问题想明白了,再看代码时才不会迷糊。
IO流作用是什么?
答:实现对文件的读写,这里的文件是广义的;
Java如何实现程序到文件
- No matching PlatformTransactionManager bean found for qualifier 'add' - neither
林鹤霄
java.lang.IllegalStateException: No matching PlatformTransactionManager bean found for qualifier 'add' - neither qualifier match nor bean name match!
网上找了好多的资料没能解决,后来发现:项目中使用的是xml配置的方式配置事务,但是
- Row size too large (> 8126). Changing some columns to TEXT or BLOB
aigo
column
原文:http://stackoverflow.com/questions/15585602/change-limit-for-mysql-row-size-too-large
异常信息:
Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAM
- JS 格式化时间
alxw4616
JavaScript
/**
* 格式化时间 2013/6/13 by 半仙 alxw4616@msn.com
* 需要 pad 函数
* 接收可用的时间值.
* 返回替换时间占位符后的字符串
*
* 时间占位符:年 Y 月 M 日 D 小时 h 分 m 秒 s 重复次数表示占位数
* 如 YYYY 4占4位 YY 占2位<p></p>
* MM DD hh mm
- 队列中数据的移除问题
百合不是茶
队列移除
队列的移除一般都是使用的remov();都可以移除的,但是在昨天做线程移除的时候出现了点问题,没有将遍历出来的全部移除, 代码如下;
//
package com.Thread0715.com;
import java.util.ArrayList;
public class Threa
- Runnable接口使用实例
bijian1013
javathreadRunnablejava多线程
Runnable接口
a. 该接口只有一个方法:public void run();
b. 实现该接口的类必须覆盖该run方法
c. 实现了Runnable接口的类并不具有任何天
- oracle里的extend详解
bijian1013
oracle数据库extend
扩展已知的数组空间,例:
DECLARE
TYPE CourseList IS TABLE OF VARCHAR2(10);
courses CourseList;
BEGIN
-- 初始化数组元素,大小为3
courses := CourseList('Biol 4412 ', 'Psyc 3112 ', 'Anth 3001 ');
--
- 【httpclient】httpclient发送表单POST请求
bit1129
httpclient
浏览器Form Post请求
浏览器可以通过提交表单的方式向服务器发起POST请求,这种形式的POST请求不同于一般的POST请求
1. 一般的POST请求,将请求数据放置于请求体中,服务器端以二进制流的方式读取数据,HttpServletRequest.getInputStream()。这种方式的请求可以处理任意数据形式的POST请求,比如请求数据是字符串或者是二进制数据
2. Form
- 【Hive十三】Hive读写Avro格式的数据
bit1129
hive
1. 原始数据
hive> select * from word;
OK
1 MSN
10 QQ
100 Gtalk
1000 Skype
2. 创建avro格式的数据表
hive> CREATE TABLE avro_table(age INT, name STRING)STORE
- nginx+lua+redis自动识别封解禁频繁访问IP
ronin47
在站点遇到攻击且无明显攻击特征,造成站点访问慢,nginx不断返回502等错误时,可利用nginx+lua+redis实现在指定的时间段 内,若单IP的请求量达到指定的数量后对该IP进行封禁,nginx返回403禁止访问。利用redis的expire命令设置封禁IP的过期时间达到在 指定的封禁时间后实行自动解封的目的。
一、安装环境:
CentOS x64 release 6.4(Fin
- java-二叉树的遍历-先序、中序、后序(递归和非递归)、层次遍历
bylijinnan
java
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class BinTreeTraverse {
//private int[] array={ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
private int[] array={ 10,6,
- Spring源码学习-XML 配置方式的IoC容器启动过程分析
bylijinnan
javaspringIOC
以FileSystemXmlApplicationContext为例,把Spring IoC容器的初始化流程走一遍:
ApplicationContext context = new FileSystemXmlApplicationContext
("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml&q
- [科研与项目]民营企业请慎重参与军事科技工程
comsci
企业
军事科研工程和项目 并非要用最先进,最时髦的技术,而是要做到“万无一失”
而民营科技企业在搞科技创新工程的时候,往往考虑的是技术的先进性,而对先进技术带来的风险考虑得不够,在今天提倡军民融合发展的大环境下,这种“万无一失”和“时髦性”的矛盾会日益凸显。。。。。。所以请大家在参与任何重大的军事和政府项目之前,对
- spring 定时器-两种方式
cuityang
springquartz定时器
方式一:
间隔一定时间 运行
<bean id="updateSessionIdTask" class="com.yang.iprms.common.UpdateSessionTask" autowire="byName" />
<bean id="updateSessionIdSchedule
- 简述一下关于BroadView站点的相关设计
damoqiongqiu
view
终于弄上线了,累趴,戳这里http://www.broadview.com.cn
简述一下相关的技术点
前端:jQuery+BootStrap3.2+HandleBars,全站Ajax(貌似对SEO的影响很大啊!怎么破?),用Grunt对全部JS做了压缩处理,对部分JS和CSS做了合并(模块间存在很多依赖,全部合并比较繁琐,待完善)。
后端:U
- 运维 PHP问题汇总
dcj3sjt126com
windows2003
1、Dede(织梦)发表文章时,内容自动添加关键字显示空白页
解决方法:
后台>系统>系统基本参数>核心设置>关键字替换(是/否),这里选择“是”。
后台>系统>系统基本参数>其他选项>自动提取关键字,这里选择“是”。
2、解决PHP168超级管理员上传图片提示你的空间不足
网站是用PHP168做的,反映使用管理员在后台无法
- mac 下 安装php扩展 - mcrypt
dcj3sjt126com
PHP
MCrypt是一个功能强大的加密算法扩展库,它包括有22种算法,phpMyAdmin依赖这个PHP扩展,具体如下:
下载并解压libmcrypt-2.5.8.tar.gz。
在终端执行如下命令: tar zxvf libmcrypt-2.5.8.tar.gz cd libmcrypt-2.5.8/ ./configure --disable-posix-threads --
- MongoDB更新文档 [四]
eksliang
mongodbMongodb更新文档
MongoDB更新文档
转载请出自出处:http://eksliang.iteye.com/blog/2174104
MongoDB对文档的CURD,前面的博客简单介绍了,但是对文档更新篇幅比较大,所以这里单独拿出来。
语法结构如下:
db.collection.update( criteria, objNew, upsert, multi)
参数含义 参数  
- Linux下的解压,移除,复制,查看tomcat命令
y806839048
tomcat
重复myeclipse生成webservice有问题删除以前的,干净
1、先切换到:cd usr/local/tomcat5/logs
2、tail -f catalina.out
3、这样运行时就可以实时查看运行日志了
Ctrl+c 是退出tail命令。
有问题不明的先注掉
cp /opt/tomcat-6.0.44/webapps/g
- Spring之使用事务缘由(3-XML实现)
ihuning
spring
用事务通知声明式地管理事务
事务管理是一种横切关注点。为了在 Spring 2.x 中启用声明式事务管理,可以通过 tx Schema 中定义的 <tx:advice> 元素声明事务通知,为此必须事先将这个 Schema 定义添加到 <beans> 根元素中去。声明了事务通知后,就需要将它与切入点关联起来。由于事务通知是在 <aop:
- GCD使用经验与技巧浅谈
啸笑天
GC
前言
GCD(Grand Central Dispatch)可以说是Mac、iOS开发中的一大“利器”,本文就总结一些有关使用GCD的经验与技巧。
dispatch_once_t必须是全局或static变量
这一条算是“老生常谈”了,但我认为还是有必要强调一次,毕竟非全局或非static的dispatch_once_t变量在使用时会导致非常不好排查的bug,正确的如下: 1
- linux(Ubuntu)下常用命令备忘录1
macroli
linux工作ubuntu
在使用下面的命令是可以通过--help来获取更多的信息1,查询当前目录文件列表:ls
ls命令默认状态下将按首字母升序列出你当前文件夹下面的所有内容,但这样直接运行所得到的信息也是比较少的,通常它可以结合以下这些参数运行以查询更多的信息:
ls / 显示/.下的所有文件和目录
ls -l 给出文件或者文件夹的详细信息
ls -a 显示所有文件,包括隐藏文
- nodejs同步操作mysql
qiaolevip
学习永无止境每天进步一点点mysqlnodejs
// db-util.js
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 10,
host: 'localhost',
user: 'root',
password: '',
database: 'test',
port: 3306
});
- 一起学Hive系列文章
superlxw1234
hiveHive入门
[一起学Hive]系列文章 目录贴,入门Hive,持续更新中。
[一起学Hive]之一—Hive概述,Hive是什么
[一起学Hive]之二—Hive函数大全-完整版
[一起学Hive]之三—Hive中的数据库(Database)和表(Table)
[一起学Hive]之四-Hive的安装配置
[一起学Hive]之五-Hive的视图和分区
[一起学Hive
- Spring开发利器:Spring Tool Suite 3.7.0 发布
wiselyman
spring
Spring Tool Suite(简称STS)是基于Eclipse,专门针对Spring开发者提供大量的便捷功能的优秀开发工具。
在3.7.0版本主要做了如下的更新:
将eclipse版本更新至Eclipse Mars 4.5 GA
Spring Boot(JavaEE开发的颠覆者集大成者,推荐大家学习)的配置语言YAML编辑器的支持(包含自动提示,