热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Polygon

1.引言Polygon早期名为Matic。Polygon为一组sidechain侧链,为公链扩容方案,其基于PlasmaMoreVP框架——采用的为

1. 引言

Polygon早期名为Matic。

Polygon为一组sidechain 侧链,为公链扩容方案,其基于 Plasma MoreVP 框架——采用的为account模型,而不是UTXO模型。Polygon支持现有所有的以太坊工具,并具有更快、更便宜的交易。Polygon上的gas费约为以太坊主网上的1/1001/1001/100

以太坊主网的资产,如Dapps/Tokens/Protocols都可迁移至Polygon side chain(s)上,同时也可根据需要将资产取回主链上。
Polygon支持DEX(如0x)、Liquidity pools(如Kyber Network)、借款协议(如Dharma Protocol)等。

具体的代码实现参见:


  • https://github.com/maticnetwork/bor:其fork自Go Ethereum,并兼容EVM。
  • https://github.com/maticnetwork/heimdall:其fork自Tendermint。

Polygon一般可分为四层:
在这里插入图片描述


  • Ethereum层:可使用以太坊来host and execute any mission-critical component of their logic。该层由以太坊智能合约来实现,主要功能类似有:

    • Finality/checkpointing
    • Staking
    • Dispute resolving
    • Message relaying
  • 安全层:为可选层,非强制需要。用于管理一组validators,validators会周期性地检查任何Polygon chain的可用性,并收取一定的费用。安全层是完全抽象的,可由不同的主体实现不同的特征。改成可直接实现在以太坊上,此时,以太坊的矿工承担了validation的工作。该层可 以平行于以太坊的meta-blockchain方式运行,负责的主要功能有:

    • Validator management(注册/反注册、激励、shuffuling等)
    • Polygon chains validation
  • Polygon networks层:为一群主权区块链网络。这个网络可利用Polygon协议来相互连接并交换任意消息。每个区块链网络服务于其各自的社区,维护一下功能:

    • 整理交易
    • 本地共识
    • 产生区块
  • 执行层:该层可解析并运行 已在Polygon网络中达成共识的交易,主要分为2个子层:

    • 执行环境(实现可插拔的虚拟机)
    • 执行逻辑(某一特定Polygon网络的状态转换函数,通常写成以太坊智能合约)

Polygon(matic)总体架构为:
在这里插入图片描述
Polygon PoS为a Layer2 commit chain to 以太坊网络。
PoS中实际内容又可划分为3个子层:


  • 对于以太坊主网层:部署了一组智能合约。
  • 对于Heimdall层:为平行于以太坊运行的一组proof-of-stake Heimdall节点,并会监控以太坊网络中的合约。Heimdall fork自 Tenedermint。
  • 对于Bor层:Heimdall节点会shuffle a set of block-producing Bor nodes。Bor fork自Go Ethereum。Bor节点或Block Producer实现本质就是sidechain operator。sidechain VM是以太坊兼容的。当前,其是:基础的Geth实现+对共识算法的自定义调整。未来,将从头开始实现,使其更轻量、更专注。产块者从Validator set中产生,并使用历史Ethereum block hashes来进行shuffle。未来将使用randomness来选举出产块者。

在以太坊主网上的合约中进行质押,Heimdall节点会监听以太坊网络上合约中质押的token,并选择相应的Bor节点来产块。Bor节点会基于Heimdall节点选择的spans轮流产块。spans与以太坊上的质押量大小相关。

Checkpoint有2个作用:


  • 1)Provide finality on the Root Chain:以太坊主链根据提交过来的checkpoint来决定侧链上块的最终性。
  • 2)Provide proof of burn in withdrawal of assets:在用户提现资产到主链上时,提交燃烧证明。

1.1 Polygon VS Plasma

Polygon与Plasma主要有2处不同:


  • Polygon实现的Plasma是基于EVM运行的state-based sidechains。而其它Plasma实现主要基于UTXO——仅支持特定的支付。Polygon具有state-based sidechains,使得Polygon可提供通用的智能合约扩容性。
  • Polygon采用的public checkpointing layer,会定期发布checkpoints——不像Plasma Cash在每个区块之后都要发布checkpoints。通过支持checkpoints的批量发布,可支持侧链以更快的速度运行。checkpoints+fraud proofs 机制,可保证Polygon侧链的安全性,同时,任何欺诈行为都可由以太坊主网发现,并通过罚没质押的token来惩罚作弊者。该主链安全性是对侧链PoS协议安全性的补充。

1.2 Polygon VS Loom

Polygon致力于去中心化扩容。Polygon采用了Plasma架构中周期性的checkpoints和fraud proofs。当用户需要取回资产时:


  • 使用checkpoints来证明其在侧链上的资产。
  • 使用fraud proofs来挑战fraud or any bad behavior and slash tokens。

Loom也提供L2扩容方案,其提出的Zombiechain与Polygon类似,但有2点不同:


  • 关注点不同。Loom主要关注游戏和社交APP,其对去中心化的诉求相对没那么高。而Polygon关注金融交易、游戏等Dapp。同时计划提供全面的金融服务,如借贷Dapp(token swaps,margin trade等等)。
  • Loom未来可能会使用的Plasma Cash,由于其需要将侧链的每个区块都推送到主链上,具有的block times要大于以太坊的block times。而Polygon使用的checkpoints for 1-second block times (with PoS layer)。
    Plasma Cash+NFT,特别适合用于表示游戏卡和社交状态转换。但是对于普通的token transfers,其需要在plasma cash上进行token swap,用户体验不够好。

1.3 Polygon VS POA/Go-Chain

POA项目的产块者由Goverment公证确认,Go-Chain则依赖于多个国家的组织。这样的public block producers将有很大概率会受powerful external agencies and self-interest影响。同时侧链的交易仅由侧链的共识来保证,其共识参与者仅由3~25个。
而Polygon中,所有侧链交易的安全性将由侧链以及主链等多重机制保证。

在侧链端,Block producer layer中的任何交易都将通过高度去中心化的checkpointing layer verified and checkpointed to 主链。侧链端的任何欺诈交易都可通过checkpoiting layer来探测和处理。极端情况下,即使block producer layer和checkpoiting layer串通作弊,主链端还有fraud proofs,任何人都可公开来挑战其认为在侧链端是作弊的任何交易,如果挑战成功,colluding parties的质押将slash从而造成巨大的经济惩罚。同时,公开挑战者可获得the slashed stakes of the fraudulent sidechain actors。
此外, Polygon sidechains的容量和TPS要远远高于POA和Go-chain。Polygon tps可达数千,而POA和Go-chain仅有小一两千。理论上,“a single Polygon side chain”的tps可达(216)(2^{16})(216),即约6.5万+。Polygon支持多条侧链。


1.4 Polygon VS Celer Network

Polygon 和 Celer Network 是对同一问题的不同解决方案,即解决当前区块链的低tps问题。二者都采用链下扩容技术,最终都依赖主链来提供final security。二者的目标都是generalized state transitions off-chain。
但是,二者本质有所不同:


  • Polygon基于的是a set of Plasma sidechain(s) + PoS共识。Celer Network基于的是状态通道解决方案。
  • Polygon致力于构建DApp开发者生态,因为其使用的是account-based Plasma sidechain,且其Polygon VM为兼容EVM的runtime,可以很容易的将以太坊DApp迁移至Polygon。从开发者角度来看,这与Celer Network有所不同。

2. Polygon的主要特征

在这里插入图片描述


3. Ethereum↔Polygon PoS Bridge

Polygon支持3种接入方式:


  • Polygon PoS chain
  • Ethereum + Polygon with PoS bridge
  • Ethereum + Polygon with Plasma bridge

其中PoS Bridge和Plasma Bridge对比如下:


PoS Bridge(Recommended)Plasma Bridge
Short DescriptionDApp Developer’s looking for flexibility and faster withdrawals with POS system securityDApp Developer’s looking for increased security guarantees with Plasma exit mechanism.
StructureHighly flexibleRigid, Less Flexible
Deposit(Ethereum → Polygon)3-5 mins3-5 mins
Withdrawal(Polygon → Ethereum)1 checkpoint = ~ 20 mins to 3 hours10080 mins or 7 days (Challenge Period)
SecurityProof-of-Stake system, secured by a robust set of external validators.Polygon’s Plasma contracts piggybacks on Ethereum’s security with 7 days challenge period.
Support StandardsETH, ERC20, ERC721, ERC1155 and OthersOnly ETH, ERC20, ERC721

Polygon采用双共识机制:PoS+Plasma。

bridge本质上为一组合约,用于帮助将资产由root chain移动到child chain。

使用PoS Bridge的详细流程为:


  • 1)将Root token和Child token映射在PoS bridge。具体映射申请页面为:https://mapper.matic.today/。
  • 2)可直接使用matic.js SDK来直接与合约进行交互。
  • 3)为了将资产由以太坊转移到Polygon,再取回到以太坊中,具体的操作为:
    • 3.1)部署在以太坊网络的Predicate合约可lock 待存入的token数额。Owner of asset (ERC20/ERC721/ERC115) token需授权Predicate合约来spend要传输的token数额。
    • 3.2)一旦完成授权,接下来了存入资产。需调用RootChainManager合约,继而触发部署在Polygon chain上的ChildChainManager合约。
    • 3.3)采用state sync机制,部署在Polygon chain上的ChildChainManager内部会调用相应child token合约的deposit函数,然后相应的数额的token资产会mint到相应的用户账号中。注意,仅有ChildChainManager合约可调用child token合约的deposit函数。
    • 3.4)一旦Polygon上的用户收到token,其可在Polygon chain上几乎实时地交易,其手续费几乎可忽略。
    • 3.5)将Polygon上的资产提回到以太坊上分为2步:首先,需要在Polygon chain上burn相应的token资产;然后,需要将proof of burn交易提交到以太坊主链上。
    • 3.6)需要由Proof of Stake validators对burn交易进行checkpoint,用时约需20分钟到3小时,然后再提交到以太坊主链上。
    • 3.7)一旦交易被添加到了check point中,则可调用部署在以太坊上的RootChainManager合约的exit函数来提交proof of burn交易。调用的exit函数会验证the checkpoint inclusion,然后出发部署在以太坊上的Predicate合约(之前存入时通过该合约lock了相应token资产)。
    • 3.8)最后,部署在以太坊上的Predicate合约会释放the locked tokens,然后将资金重新冲入相应的以太坊用户账号中。

4. Polygon中的state sync机制

详细参看:


  • https://github.com/maticnetwork/matic-docs/blob/master/docs/contribute/state-sync/state-sync-mechamism.md
  • https://github.com/maticnetwork/matic-docs/blob/master/docs/contribute/state-sync/state-sync-mechamism.md

4.1 State Sync

State Sync为native机制,用于从以太坊主链上读取state并发送到Bor链上。
Heimdall层的Validators会监听StateSynced 事件,然后将该事件传输给Bor层。

receiver合约继承了IStateReceiver,自定义逻辑体现在onStateReceive函数中:

pragma solidity ^0.5.11;// IStateReceiver represents interface to receive state
interface IStateReceiver {function onStateReceive(uint256 stateId, bytes calldata data) external;
}

是需要dapps/users按如下流程操作来实现state-sync:


  • 1)调用以太坊主链上部署的StateSender合约中的syncState函数。
  • 2)syncState函数会释放event StateSynced( uint256 indexed id, address indexed contractAddress, bytes data ); 事件。
  • 3)Heimdall chain中的所有Validators将监听到该事件,然后其中的一个想要获得tx fee的Validator将该交易发送到heimdall。
  • 4)一旦state-sync交易被包含在heimdall上的一个区块中(经过2/3+ validators同意),其即被添加到了pending state-sync list。
  • 5)在bor中的每个sprint(当前为64 blocks on Bor)之后,bor节点会通过调用API从heimdall中提取pending state-sync states。详细代码为:【在调用commitState时,stateIddata为参数。】

func (gc *GenesisContractsClient) CommitState(event *EventRecordWithTime,state *state.StateDB,header *types.Header,chCtx chainContext,
) error {eventRecord := event.BuildEventRecord()recordBytes, err := rlp.EncodeToBytes(eventRecord)if err != nil {return err}method := "commitState"t := event.Time.Unix()data, err := gc.stateReceiverABI.Pack(method, big.NewInt(0).SetInt64(t), recordBytes)if err != nil {log.Error("Unable to pack tx for commitState", "error", err)return err}log.Info("→ committing new state", "eventRecord", event.String())msg := getSystemMessage(common.HexToAddress(gc.StateReceiverContract), data)if err := applyMessage(msg, state, header, gc.chainConfig, chCtx); err != nil {return err}return nil
}

  • 6)部署在Bor链(子链)上的receiver合约继承了IStateReceiver,在onStateReceive函数中可实现自定义逻辑来解析data并实现任意action。

4.2 Bor Block Receipt

详细参看:


  • https://github.com/maticnetwork/bor/pull/90

Bor会为client生成新的tx/receipt,包含了all logs for state-sync。Tx hash有block number和block hash(sprint中最后一个区块的block hash)派生而来:

keccak256("matic-bor-receipt-" + block number + block hash)

这并不会影响共识逻辑,仅会影响客户端。eth_getBlockByNumbereth_getTransactionReceipteth_getLogs 会包含派生的state-sync logs。注意,区块中的bloom过滤器不会包含inclusion for state-sync logs,同时也不会在transactionRootreceiptRoot中包含派生的tx。


5. polygon protocol

主网实际部署信息参见:


  • https://static.matic.network/network/mainnet/v1/index.json

{
Main: {
NetworkName: "Ethereum",
ChainId: 1,
DaggerEndpoint: "wss://mainnet.dagger.matic.network",
WatcherAPI: "https://sentinel.matic.network/api/v2",
StakingAPI: "https://sentinel.matic.network/api/v2",
Explorer: "https://etherscan.io",
SupportsEIP1559: true,
Contracts: {
BytesLib: "0x1d21fACFC8CaD068eF0cbc87FdaCdFb20D7e2417",
Common: "0x31851aAf1FA4cC6632f45570c2086aDcF8B7BD75",
ECVerify: "0x71d91a8988D81617be53427126ee62471321b7DF",
Merkle: "0x8b90C7633F1f751E19E76433990B1663c625B258",
MerklePatriciaProof: "0x8E51a119E892D3fb324C0410F11f39F61dec9DC8",
PriorityQueue: "0x61AdDcD534Bdc1721c91740Cf711dBEcE936053e",
RLPEncode: "0x021c2Bf4d2941cE3D593e07317EC355937bae495",
RLPReader: "0xD75f1d6A8A7Dc558A65c2f30eBF876DdbeE035a2",
SafeMath: "0x96D358795782a73d90F2ed2d505aB235D197ca05",
Governance: "0x98165b71cdDea047C0A49413350C40571195fd07",
GovernanceProxy: "0x6e7a5820baD6cebA8Ef5ea69c0C92EbbDAc9CE48",
Registry: "0x33a02E6cC863D393d6Bf231B697b82F6e499cA71",
RootChain: "0x536c55cFe4892E581806e10b38dFE8083551bd03",
RootChainProxy: "0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287",
ValidatorShareFactory: "0xc4FA447A0e77Eff9717b09C057B40570813bb642",
StakingInfo: "0xa59C847Bd5aC0172Ff4FE912C5d29E5A71A7512B",
StakingNFT: "0x47Cbe25BbDB40a774cC37E1dA92d10C2C7Ec897F",
StakeManager: "0xd6f5c46d4e1a02f9d145cee41d2f8af30d8d2d76",
StakeManagerProxy: "0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908",
SlashingManager: "0x01F645DcD6C796F6BC6C982159B32fAaaebdC96A",
ValidatorShare: "0x01d5dc56ad4206bb0c132d834644d57f51fed5ec",
StateSender: "0x28e4F3a7f651294B9564800b2D01f35189A5bFbE",
DepositManager: "0xd505C3822C787D51d5C2B1ae9aDB943B2304eB23",
DepositManagerProxy: "0x401F6c983eA34274ec46f84D70b31C151321188b",
WithdrawManager: "0x017C89Ca4Bda3D66cC65E3d20DD95432258201Ca",
WithdrawManagerProxy: "0x2A88696e0fFA76bAA1338F2C74497cC013495922",
ExitNFT: "0xDF74156420Bd57ab387B195ed81EcA36F9fABAca",
ERC20Predicate: "0x158d5fa3ef8e4dda8a5367decf76b94e7effce95",
ERC721Predicate: "0x54150f44c785d412ec262fe895cc3b689c72f49b",
Tokens: {
MaticToken: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0",
TestToken: "0x3db715989dA05C1D17441683B5b41d4510512722",
RootERC721: "0x96CDDF45C0Cd9a59876A2a29029d7c54f6e54AD3",
MaticWeth: "0xa45b966996374E9e65ab991C6FE4Bfce3a56DDe8"
}
},
POSContracts: {
Merkle: "0x195fe6EE6639665CCeB15BCCeB9980FC445DFa0B",
MerklePatriciaProof: "0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa",
RLPReader: "0xBEFe614A45A8300f2a4A00fb634b7137b6b1Bc47",
SafeERC20: "0xeFfdCB49C2D0EF813764B709Ca3c6fe71f230E3e",
SafeMath: "0x6EBEAC13f6403D19C95b6B75008B12fd21a93Aab",
RootChainManager: "0x7cfa0f105a4922e89666d7d63689d9c9b1ea7a19",
RootChainManagerProxy: "0xA0c68C638235ee32657e8f720a23ceC1bFc77C77",
ERC20Predicate: "0x608669d4914eec1e20408bc4c9efff27bb8cbde5",
ERC20PredicateProxy: "0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf",
ERC721Predicate: "0xb272b6d99858b0efb079946942006727fe105201",
ERC721PredicateProxy: "0xE6F45376f64e1F568BD1404C155e5fFD2F80F7AD",
ERC1155Predicate: "0x62d7e87677ac7e3bd02c198e3fabeffdbc5eb2a3",
ERC1155PredicateProxy: "0x0B9020d4E32990D67559b1317c7BF0C15D6EB88f",
MintableERC20Predicate: "0xFdc26CDA2d2440d0E83CD1DeE8E8bE48405806DC",
MintableERC20PredicateProxy: "0x9923263fA127b3d1484cFD649df8f1831c2A74e4",
MintableERC721Predicate: "0x58adfa7960bf7cf39965b46d796fe66cd8f38283",
MintableERC721PredicateProxy: "0x932532aA4c0174b8453839A6E44eE09Cc615F2b7",
MintableERC1155Predicate: "0x62414d03084eeb269e18c970a21f45d2967f0170",
MintableERC1155PredicateProxy: "0x2d641867411650cd05dB93B59964536b1ED5b1B7",
EtherPredicate: "0x499a865ac595e6167482d2bd5a224876bab85ab4",
EtherPredicateProxy: "0x8484Ef722627bf18ca5Ae6BcF031c23E6e922B30",
DummyStateSender: "0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39",
Tokens: {
DummyERC20: "0xf2F3bD7Ca5746C5fac518f67D1BE87805a2Be82A",
DummyERC721: "0x71B821aa52a49F32EEd535fCA6Eb5aa130085978",
DummyMintableERC721: "0x578360AdF0BbB2F10ec9cEC7EF89Ef495511ED5f",
DummyERC1155: "0x556f501CF8a43216Df5bc9cC57Eb04D4FFAA9e6D"
}
},
FxPortalContracts: {
FxERC20RootTunnel: "0x9194ec72B67ce7AE51074aFdAd44f937CE1dD447"
}
},
Matic: {
NetworkName: "Polygon",
ChainId: 137,
RPC: "https://matic-mainnet.chainstacklabs.com",
DaggerEndpoint: "wss://matic-mainnet.dagger.matic.network",
Explorer: "https://polygonscan.com",
NetworkAPI: "https://apis.matic.network/api/v1/matic",
SupportsEIP1559: false,
Contracts: {
ChildChain: "0xD9c7C4ED4B66858301D0cb28Cc88bf655Fe34861",
Tokens: {
MaticWeth: "0x8cc8538d60901d19692F5ba22684732Bc28F54A3",
MaticToken: "0x0000000000000000000000000000000000001010",
TestToken: "0x5E1DDF2e5a0eCDD923692d4b4429d8603825A8C6",
RootERC721: "0xa35363CFf92980F8268299D0132D5f45834A9527",
WMATIC: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270"
}
},
POSContracts: {
ChildChainManager: "0xa40fc0782bee28dd2cf8cb4ac2ecdb05c537f1b5",
ChildChainManagerProxy: "0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa",
Tokens: {
DummyERC20: "0xeFfdCB49C2D0EF813764B709Ca3c6fe71f230E3e",
DummyERC721: "0x6EBEAC13f6403D19C95b6B75008B12fd21a93Aab",
DummyMintableERC721: "0xD4888faB8bd39A663B63161F5eE1Eae31a25B653",
DummyERC1155: "0xA0c68C638235ee32657e8f720a23ceC1bFc77C77",
MaticWETH: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619"
}
},
FxPortalContracts: {
FxERC20ChildTunnel: "0x918cc10cf2393bb9803f9d9D3219539a1e736dd9"
},
GenesisContracts: {
BorValidatorSet: "0000000000000000000000000000000000001000",
StateReceiver: "0000000000000000000000000000000000001001"
}
},
Heimdall: {
ChainId: "heimdall-137",
API: "https://heimdall.api.matic.network"
}
}

参考资料

[1] maticnetwork 白皮书
[2] polygon lightpaper
[3] Polygon technology
[4] Polygon PoS
[5] Polygon docs


推荐阅读
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • 在IDEA中运行CAS服务器的配置方法
    本文介绍了在IDEA中运行CAS服务器的配置方法,包括下载CAS模板Overlay Template、解压并添加项目、配置tomcat、运行CAS服务器等步骤。通过本文的指导,读者可以轻松在IDEA中进行CAS服务器的运行和配置。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
author-avatar
吉祥二宝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有