React 框架_react框架(1)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

render() { 
    //仅仅是绑定函数,而不是在渲染时就将返回值传过来,因此handleClickleft不加()    
    return (
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
            <button onClick={this.handleClickRight} className="btn btn-success m-2">right</button>          
        </React.Fragment>
}

}


此时,输出的 this 不是 Box 类,而是 undifind。



如何使得方法里的 this 仍属于 Box 类:
// 法一:箭头函数(推荐)
// 法二: bind 函数



handleClickLeft=()=>{ // 法一:箭头函数
console.log(“click left”,this);
}

handleClickRight(){
console.log(“click right”,this);
}

render() {
return (
<React.Fragment>

{this.toString()}

left
right
</React.Fragment> // 法二:bind函数
);
}


#### 3.9、修改 state 里的值



直接 this.state.x-- 不会影响到页面div的显示的x值,
如果想要让 state 里的 x 的修改影响到render函数的话, 必须用 setState() 函数 (通过重新调用 render 修改 div 里 x 值)



class Box extends Component {
state = {
x: 1,
}

handleClickLeft = () => { 
       this.setState({				// setState() 函数
        x: this.state.x - 1
    });
}

handleClickRight = () => {
    this.setState({					// setState() 函数
        x: this.state.x + 1
    });
}

render() {    
    return (
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
            <button onClick={this.handleClickRight} className="btn btn-success m-2">right</button>          
        </React.Fragment>
    );
}

}


#### 3.10、通过按钮修改css属性


将 state 里的值赋值给某一样式的属性,通过按钮修改state 值从而修改 css 样式



class Box extends Component {
state = {
x: 10, // state值
}

handleClickLeft = () => { 
this.setState({
    x: this.state.x - 10			// setState() 修改 state值, 重新调用 render() 函数
});
}

handleClickRight = () => {
    this.setState({
        x: this.state.x + 10		// setState() 修改 state值,重新调用 render() 函数
    });
}

render() { 
    return (
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
            <button onClick={this.handleClickRight} className="btn btn-success m-2">right</button>          
        </React.Fragment>
    );
}

getStyles() {
    let styles = {
        width: "50px",
        height: "50px",
        backgroundColor: "pink", 
        color: "white",
        textAlign: "center",
        lineHeight: "50px",
        borderRadius: "5px",
        margin: '5px',
        marginLeft: this.state.x,              //  state值赋值给 css 属性值
    };

    if (this.state.x === 0){
        styles.backgroundColor = 'orange';
    }
    return styles;
}		

}


#### 3.11、给事件函数添加参数



handleClickRight = (step) => {
this.setState({
x: this.state.x + step
});
}



handleClickRightTmp = () => {
return this.handleClickRight(50);
}



render() {
return (
<React.Fragment>

{this.toString()}

left
right
</React.Fragment>
);
}


将 handleClickRight() 函数写为箭头匿名函数后等价于: 



render() {
// 绑定了一个调用含参 函数 handleClickLeft =(step)=>{ } 的匿名函数
return (
<React.Fragment>

{this.toString()}

<button onClick={()=>this.handleClickLeft(10)} className=“btn btn-primary m-2”>left
<button onClick={()=>this.handleClickRight(10)} className=“btn btn-success m-2”>right
</React.Fragment>
);
}



> 
> **综上,Box组件的构建步骤:**
> 
> 
> 


1、定义 state 变量,并使得数据驱动 style;


2、构造 handleClickLeft =(step)=>{ } 带参函数,利用 setState() 函数改变 state 值;调用setState()能够重新加载 render 函数,才可以对里面的 div 显示进行修改


3、给按钮的单击事件onClick绑定所写函数。这里绑定了一个调用含参函数 handleClickLeft =(step)=>{ } 的匿名函数,()=>this.handleClickRight(10)



class Box extends Component {

// 1. 定义 state,并使得数据驱动style
state = { 
    x: 10,
} 

// 2. 通过 handleClickLeft =(step)=>{ } 带参函数 与 setState()  改变state值
//    并能够重新加载 render 函数来对里面的 div 显示进行操作
handleClickLeft = (step) => { 
    this.setState({
        x: this.state.x - step
    });
}

handleClickRight = (step) => {
    this.setState({
        x: this.state.x + step
    });
}

render() { 
	// 3. 给事件绑定函数:通过 render 函数里,按钮事件绑定函数。
	//    绑定了一个调用含参函数 handleClickLeft =(step)=>{ }  的匿名函数  
    return (
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={()=>this.handleClickLeft(10)} className="btn btn-primary m-2">left</button>
            <button onClick={()=>this.handleClickRight(10)} className="btn btn-success m-2">right</button>          
        </React.Fragment>
    );
}

getStyles() {
    let styles = {
        width: "50px",
        height: "50px",
        backgroundColor: "pink", 
        color: "white",
        textAlign: "center",
        lineHeight: "50px",
        borderRadius: "5px",
        margin: '5px',
        marginLeft: this.state.x,	// 数据驱动 style
    };

    if (this.state.x === 0){
        styles.backgroundColor = 'orange';
    }
    return styles;
}

}


### 4、Component 组件的组合与交互


#### 4.1、**【组合 Component 】组件的构建**



组合多个上述定义的 Box 组件,形成 Boxes 组件,并完成 属性 值的传递。
<注:多个相同子组件时,每个子组件需要有唯一 key 值>


* 建立 `Boxes` 类组件,内含多个 `Box`组件



import React, { Component } from ‘react’;
import Box from ‘./box’;

class Boxes extends Component {
// 1. 设置 state 变量,包括 Box 组件的唯一 key 值与 x 坐标值。
state = {
boxes:[
{id: 1, x: 10},
{id: 2, x: 10},
{id: 3, x: 100},
{id: 4, x: 10},
{id: 5, x: 10},
]
}
// 2. render 函数返回多个 box 组件,通过 map 列表,逐一建立并赋值多个 Box 组件
// 将 box.id 赋值给组件唯一 key,将 box.x 赋值给 Box 组件的 x
render() {
return (
<React.Fragment>
{this.state.boxes.map((box)=>(
<Box
key = {box.id} // id
x = {box.x} // 这里会自动找到 Box 组件里的 x 赋值并存储在 props 中
// 但仅仅是修改了x,并不会改变前端的显示
/>
))}
</React.Fragment>
);
}
}

export default Boxes;


【注】在react组件之间的通信是通过`props`属性来完成的,比如父组件需要将数据传递给子组件,那么组件在渲染子组件的时候,直接将数据作为子组件的属性传参。


* state 值传递:通过 `props` 将`Boxes`定义的属性值返回传递给 `Box`的



class Box extends Component {
state = {
// props类似于state,存储除key以外属于 box 的所有属性
// Boxes 建立的 Box 赋值的 x 存到了 props 里
// 通过 props 传递给了每个 Box
x: this.props.x,
}

handleClickLeft = (step) => { 
    this.setState({
        x: this.state.x - step
    });
}

handleClickRight = (step) => {
    this.setState({
        x: this.state.x + step
    });
}

render() { 
    return (
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={()=>this.handleClickLeft(10)} className="btn btn-primary m-2">left</button>
            <button onClick={()=>this.handleClickRight(10)} className="btn btn-success m-2">right</button>          
        </React.Fragment>
    );
}

getStyles() {
    let styles = {
        width: "50px",
        height: "50px",
        backgroundColor: "pink", 
        color: "white",
        textAlign: "center",
        lineHeight: "50px",
        borderRadius: "5px",
        margin: '5px',
        marginLeft: this.state.x,
    };

    if (this.state.x === 0){
        styles.backgroundColor = 'orange';
    }
    return styles;
}

toString(){
    return `x: ${this.state.x}`;	        
}

}

export default Box;


* 标签传递:通过 `props` 将`Boxes` 增加的`Box.children`子标签,传递给 `Box`



// Boxes.jsx文件
render() {
return (
<React.Fragment>
{this.state.boxes.map((box)=>(

Box :

// 将 Box 的闭合标签写为双标签
{box.id}
// 可在 Box 标签内增加其它标签,属性名为 Box.children
// 并存储到了 props 中
))}
</React.Fragment>
);
}



// Box.jsx 文件
render() {
console.log(this.props);
return (
<React.Fragment>
{this.props.children[0]} // 通过 props 所存储的 children 将增加的标签传递给Box

{this.toString()}

<button onClick={()=>this.handleClickLeft(10)} className=“btn btn-primary m-2”>left
<button onClick={()=>this.handleClickRight(10)} className=“btn btn-success m-2”>right
</React.Fragment>
);
}


* 方法传递1:React 子组件调用父组件的方法。


`Box`子组件调用`Boxes`父组件内的方法,依旧通过`props`。实现在 `Box` 组件中触发 `onClick` 事件后,在`Boxes`组件中删除`key`值对应的`Box`,即在`Box`标签内调用`Boxes`标签的方法



// Boxes.jsx 文件
// 1. Boxes.jsx 文件中写删除的方法
handleDelete = (id) => {
// filter: boxes列表的元素依次判断,若表达式为true则留下,否则删掉
// 即若id不等留下来,相等删除
const newboxes = this.state.boxes.filter(
(x)=>(x.id !== id)
);
this.setState({
boxes: newboxes
})
}

render() {
if(this.state.boxes.length === 0){
return

没有元素可以删除了!!!

}
return (
// 2. 将所写删除方法定义为标签的 onDelete 属性传递给 Box(会存储在 props中)
<React.Fragment>
{this.state.boxes.map((box)=>(

Box :


{box.id}


))}
</React.Fragment>
);
}



// Box.jsx 文件
render() {
return (
<React.Fragment>
{this.props.children[0]}

{this.toString()}

<button onClick={()=>this.handleClickLeft(10)} className=“btn btn-primary m-2”>left
<button onClick={()=>this.handleClickRight(10)} className=“btn btn-success m-2”>right
// 3. Box 调用 Boxes 的删除方法 :
// Box 中的 Button 的 onClick 事件,绑定匿名函数来调用含参的删除方法
<button onClick={()=>this.props.onDelete(this.props.id)} className=‘btn btn-danger m-2’> Delete
</React.Fragment>
);
}


* 方法传递2:React 父组件调用子组件的方法。


仅能调用一个子组件方法,无法调用列表子组件



// 父组件
class Boxes extends Component {

// 1. Boxes 父组件中写入
setChildRef = (ref) => {
    this.ChildRef = ref;
}

// 3. Boxes 父组件中写调用 Box 子组件的方法
handleReset = () =>{
    this.ChildRef.handleRE()
}

render() {     
    return (
        <React.Fragment>

// 4. 将父组件方法绑定onClick单击事件中,即可实现单击调用子组件的方法
Clear
{this.state.boxes.map((box)=>(
// 2. Boxes 父组件的 Box 子组件标签内增加 ref 属性,并将 setChildRef 传递过来

Box :


{box.id}


))}
</React.Fragment>
);
}
}



// 子组件
class Box extends Component {

state = { 
    x: this.props.x,
} 

//  子组件中被调用的方法
handleRE = () =>{
    this.setState({
        x: 0
    });
}


render() { 
    return (
        <React.Fragment>
            ......
        </React.Fragment>
    );
}

}


### 5、组件使用


#### 5.1、组件的生命周期


![](https://img-blog.csdnimg.cn/412662e971e74af58a8548c8dfadfa00.png)


**创建时(挂载阶段)**


* 执行时机:组件创建时(页面加载时)
* 执行顺序:constructor() -> render() -> componentDidMount()


constructor()组件创建的时候,最先执行,主要是初始化数据,为事件处理程序绑定this


render():每次组件渲染触发,主要是渲染UI


componentDidMOunt():组件挂载完成,主要作用DOM操作,发送网络请求


**更新时(更新阶段)**


* 执行时机:1.setState() 2.组件收到props变了 3.forceUpdate()
* 说明:以上3中情况都会触发
* 执行顺序:render() -> componentDidUpdate()


render():每次组件渲染触发,渲染UI


componentDidUpdate():组件 状态更新完毕


**预载时**


* 执行时机:组件从页面消失


####  5.2、动态更新initialValue的值


**[antd: Form.Item] defaultValue will not work on controlled Field. You should use initialValues o  
 原因**:antd禁止在form.item下的组件使用默认属性  
**解决办法**:删除defaultValue,在中使用initialValue={{ parentId: parentId }}代替,如果要动态更新 parentId的值,又会导致下面的问题


**React does not recognize the initialValue prop on a DOM element.**  
 \*\*原因:\*\*不能通过这种方法更新parentId的值,想要更新props中的值,要通过form.setFieldsValue({ parentId: parentId })进行更改,


你不能用控件的 value 或 defaultValue 等属性来设置表单域的值,默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新。


**由上可知,表单中不能设置默认值,要想设置默认值必须通过form中的initial Values进行设置,但是其又不能动态更新,想要达到动态更新的效果必须使用form中的setFieldsValue进行更新,需要检测parentId的变化从而对parentId进行修改,固需要在useEffect中使用setFieldsValue**


如果需要在父组件中得到子组件的form表单中的值,可以通过[函数传参]( )的方式,将子组件的form对象传递给父组件,这样父组件得到子组件的form对象,就可以通过getFieldValue得到表单的值了。



const [form] = Form.useForm()
//将子组件的form传递给父组件,使得父组件可以取到子组件form中的categorieName的值
props.setForm(form)
// 动态更新parentId的值
useEffect(() => {
    form.setFieldsValue({ parentId: parentId })
}, [parentId])


import React, { Fragment, useEffect } from ‘react’
import { Form, Input, Select } from ‘antd’
import { useForm } from ‘antd/lib/form/Form’;

const { Option } = Select;

export default function AddForm(props) {
const { categorys, parentId } = props
const [form] = Form.useForm()
console.log(parentId)
// 动态更新parentId的值
useEffect(() => {
form.setFieldsValue({ parentId: parentId })
}, [parentId])
return (

{/* initialValues不能被动态更新,需要使用form.setFieldsValues进行动态更新,将其放在useEffect中 /}

所属分类
<Form.Item
name=“parentId”
rules={[
{
required: true,
message: ‘Please select category!’,
},
]}
>
{/
表单中不能使用默认属性defaultValue,在form中使用initialValues{{}}代替 */}

一级分类
{
categorys.map(c => {c.name})
}

</Form.Item>
分类名称
<Form.Item
name=“categoryName”
rules={[
{
required: true,
message: ‘Please input your categoryName!’
}
]}
>

</Form.Item>


)
}



// 告警标签
// 动态更新initialValue值
changeMissLevel = () =>{
const{form} = this.props;
form.setFieldsValue(
{
missLevel:‘222’
}
);
}

render(){
<Form.Item>
{getFieldDecorator(‘missLevel’,{
initialValue:this.state.missLevel
})(

a
b

          )
    }
</>

}


#### 5.3、遍历、转换、非空判断、动态设置


* 遍历对象与数组



// 遍历对象
const object = {“a”:“1”,“b”:“2”};
for(let key in object){
console.log(key);
console.log(object[key]);
}

// 遍历数组
const array = [“1”,“2”,“3”];
const array1 = [{“a”:“1”},{“b”:“2”}];

for(let key in array){
console.log(array[key]);
}
for(let key in array1){
console.log(array[key].a);
console.log(array[key].b);
}


* 对象动态值获取或作为键



// 动态值作为键
const obj = {“a”:“1”,“b”:“2”};
let ccc = ‘c’;
obj[ccc] = ‘3’;
// 对象赋值
obj.d = ‘4’;
// 对象获取值
let ddd = obj.d;

// 对象动态值获取
const data = {“a”:“1”,“b”:“2”};
let aaa = ‘a’;
data[aaa+‘’]


* 对象与字符串的转换



// 对象转字符串
const obj = {“a”:“1”}
JSON.String(obj );
// 字符串转对象
String a = “”;
JSON.parse(a);

// join与split
const aa = [“1”,“2”];
const bb = “1,2”;
bb = aa.join(‘,’);
aa = bb.split(“,”);


* 非空判断



// 判断是否不为空
ifNotNull = (value:any) => {
if( value != undefined &&
value != null &&
value != ‘null’ &&
value != ‘NULL’ &&
value != ‘[]’ &&
value != ‘’ &&
value != {} &&
value != [] &&
)
{
return true;
} else {
return false;
}
}

// 判断是否为空
ifNotNull = (value:any) => {
if( value === undefined ||
value === null ||
value === ‘null’ ||
value === ‘NULL’ ||
value === ‘[]’ ||
value === ‘’ ||
value === {} ||
value === [] ||
)
{
return true;
} else {
return false;
}
}


#### 5.4、ant的Search组件,搜索框内容清空



// 清空操作
reset = () => {
this.refs.searchBar.input.state.value=‘’;
}


#### 5.5、资源树结构选中取消



onTreeSelect = (selectKeys:any[], info: { props: {dataRef: any}}}) => {
// 树节点取消触发
if(selectKeys[0] === undefined){
this.setState({
data:[],
total:0
});
return;
}
// 选中
let restypeId = info.node.props.dataRef.restypeId;
}


### 6、Hooks


#### 6.1、useState



import { useState } from ‘react’;


* **使用 useState 的注意事项**


1. useState 向组件引入新的状态,这个状态会被保留在 react 中。
2. useState 只有一个参数,这个参数是初始状态值,它可以是任意类型。
3. useState 可以多次调用,意味着可以为组件传入多个状态。
4. useState 返回值是一个数组,第一个元素就是我们定义的 state,第二个元素就是修改这个 state 的方法。接收 useState 的返回值使用数组结构语法,我们可以随意为 state 起名字。修改 state 的方法必须是 set + 状态名首字母大写构成,不按照约定写就会报错。
5. useState 的参数也可以是一个函数,这个函数的返回值就是我们的初始状态。



function Counter() {
const [count, setCount] = useState(0);
return (


{count}


<button onClick={() => setCount(count + 1)}>+

);
}


定义了一个状态 count,传入的参数为函数 () => 1,则 count 的初始值为函数的返回值1。当点击按钮时,调用修改方法 setCount 将 count 的值自增1,页面上计数器也会同步自增1。



function Counter() {
const [count, setCount] = useState(() => 1);
function handleCount(a) {
setCount(a + 1);
document.title = a;
}
return (


{count}


<button onClick={() => handleCount(count)}>+

);
}


在点击按钮后,计数器显示数字变为了2,但页面的标题还是1。每次点击按钮后,页面的标题都比计数器显示数字少1。因此执行代码先执行了第5行的设置页面标题,才执行第4行的设置 count 值,看过上篇文章就很容易理解。


#### 6.2、useEffect



import { useEffect } from ‘react’;


useEffect 这个 Hook 函数的主要作用就是将副作用代码添加到函数组件内。所谓的副作用代码就是 dom 更改、计时器、数据请求等。


使用场景:


* useEffect(() => {}) 这种写法代表两个生命周期函数 componentDidMount 和 componentDidUpdate。
* useEffect(() => {}, []) 这种写法代表生命周期函数 componentDidMount。
* useEffect(() => () => {}) 这种写法代表组件卸载之前 componentWillUnmount 和 componentDidUpdate 两个生命周期函数。


##### 6.2.1、useEffect(() => {})


useEffect 钩子函数传入一个函数作为参数,代表组件在加载完成后和数据更新时都会调用传入的函数。



function Counter() {
const [count, setCount] = useState(() => 1);
function handleCount(a) {
setCount(a + 1);
document.title = a;
}
useEffect(() => {
console.log(‘success’);
});
return (


{count}


<button onClick={() => handleCount(count)}>+

);
}


在页面加载完成和每次点击按钮让计数器自增后,控制台都会打印 success。即 useEffect Hook 实现了生命周期函数 componentDidMount 和 componentDidUpdate 的功能。 


##### 6.2.2、useEffect(() => {}, [])


useEffect 钩子函数传入一个函数和一个数组作为参数,代表组件在加载完成后会调用传入的函数。



function Counter() {
const [count, setCount] = useState(() => 1);
function handleCount(a) {
setCount(a + 1);
document.title = a;
}
useEffect(() => {
console.log(‘success’);
}, []);
return (


{count}


<button onClick={() => handleCount(count)}>+

);
}


这个案例和上一个案例不同之处在于 useEffect 钩子函数传入了一个空数组作为第2个参数,当页面加载完成时控制台会打印 success,点击按钮更新计数器后不再打印,即实现了生命周期函数 componentDidMount 的功能。 


##### 6.2.3、useEffect(() => () => {})


useEffect 钩子函数传入一个返回函数的函数作为参数,代表组件在数据更新时和卸载时会调用返回的函数。



function Counter(props) {
const [count, setCount] = useState(() => 1);
function handleCount(a) {
setCount(a + 1);
document.title = a;
}
useEffect(() => () => {
console.log(‘success’);
}, []);
return (


{count}


<button onClick={() => handleCount(count)}>+
<button onClick={() => props.root.unmount()}>卸载组件

);
}


这个案例中,点击按钮更新计数器和点击卸载组件时控制台都会打印 success,即实现了生命周期函数 componentWillUnmount 和 componentDidUpdate 的功能。 


##### 6.2.4、useEffect 第二个参数的使用


useEffect 钩子函数的第二个参数,正常添加空数组,代表的生命周期是 componentDidMount。即使我们修改了 state,useEffect 也只会调用一次。


如果我们想让某个 state 发生改变的时候,继续调用 useEffect,就需要把这个状态添加到第二个参数的数组中。  
  



function Counter() {
const [count, setCount] = useState(() => 1);
const [person, setPerson] = useState({ name: ‘ccshen’ });
function handleCount(a) {
setCount(a + 1);
document.title = a;
}
useEffect(() => {
console.log(‘计数器改变’);
}, [count]); // count 一旦发生改变,就会执行 useEffect
return (


{count}


{person.name}


<button onClick={() => handleCount(count)}>+
<button onClick={() => setPerson({ name: ‘lisi’ })}>更改person

);
}


useEffect 第二个参数传递了 count,那么将会在 count 状态更新时才会执行传入的函数。


##### 6.2.5、useEffect 的异步处理



function Counter() {
function asyncFn() {
setTimeout(() => {
console.log(‘success’);
}, 1000);
}
useEffect(() => {
asyncFn();
});
return (



);
}


我们声明了一个异步函数,然后在 useEffect 中调用,预览正常,在页面加载完成1秒后打印 success。 


当我们使用 async/await 时



![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)


最全的Linux教程,Linux从入门到精通

======================

1.  **linux从入门到精通(第2版)**

2.  **Linux系统移植**

3.  **Linux驱动开发入门与实战**

4.  **LINUX 系统移植 第2版**

5.  **Linux开源网络全栈详解 从DPDK到OpenFlow**



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)



第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)



**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**

> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值