Sari la conținut

NOT a MERCEDES

LCS PREMIUM
  • Număr conținut

    81
  • Înregistrat

  • Ultima Vizită

  • Country

    Romania

2 Urmăritori

Despre NOT a MERCEDES

  • Dată Naștere 04.01.2000

Câmpuri de profil

  • Titlul de membru
    #mostHated.

Configurații server

  • Server & Games
    ESL

Vizitatori Recenți Profil

775 citiri profil

Realizările lui NOT a MERCEDES

BRONZE II

BRONZE II (5/25)

  • Moderatorul Anului 2024 Rar
  • 1 an de LeagueCS

Insigne recente

627

Reputație Comunitate

  1. In aceasta parte , vom implementa partea de conexiune cu baza de date MySQL . ** Configuratie ** Pe de o parte , vom introduce in fisierul de configuratie '.env' , informatii si credentiale pentru efectuarea conexiuni : # .env ## ... alte variabile ## SETARI PRECUM HOSTUL , PORTUL , NUMELE BAZEI DE DATE + CREDENTIALE (UTILIZATOR SI PAROLA) HOST_DB = LOCALHOST PORT_DB = 3306 NAME_DB = SocialMediaDB USERNAME_DB = root PASSWORD_DB = ******* ## la parola inlocuiti acele caractere cu parola voastra Pe de alta parte , va trebui sa exportam configuratia prin 'configData.ts' (din folderul Configuratie) , cu scopul de a fi accesibila informatia in tot proiectul . // configData.ts /// alte informatii .... export const dbConfig = { // Exportam credentialele Bazei de Date host:process.env.HOST_DB, port:+process.env.PORT_DB!, // +! ==> forteaza ca portul sa fie tratat CA NUMAR SI NU , SIR DE CARACTERE !! user:process.env.USERNAME_DB, password:process.env.PASSWORD_DB, database:process.env.NAME_DB } ** Conexiune cu Baza de date ** In primul rand , ne asiguram ca avem instalata dependenta la 'mysql' (prin CMD) : npm i mysql2 Apoi , construim un fisier typeScript ('dbConnection.ts' --> la nivel cu 'server.ts') , construim o clasa 'DBConnection' ce gestioneaza poolul de conexiuni (de la constructie la reutilizare) . // dbConnection.ts import * as mysqlConection from 'mysql2/promise' // Importam Dependenta MySQL import {dbConfig} from './configurations/configData' // Importam Configuratia cu Credentialele export class DBConnection { // Pregatim clasa de export pentru utilizarea si reutilizarea conexiunilor // .. } Declaram doua proprietati : dbInstance (statica centralizata pentru a si mentine valorile) si 'databaseConnectionPool' care ne ofera , prin intermediul 'dbInstance' , accesul la baza de date . // dbConnection.ts export class DBConnection { private static dbInstance : DBConnection // Instanta private databaseConnectionPool : mysqlConection.Pool; // Connexiunea /// .. } Pe baza modelului 'Singleton' , va trebui sa ne facem un constructor PRIVAT (accesibil doar in clasa) pentru a preveni initializarea din exterior : // dbConnection.ts export class DBConnection { // ... private constructor() // Prevenim Initializarea din Exterior { const dbConfigCopy = { ... dbConfig} // Copiem Configuratia bazei de date delete dbConfigCopy.database // EXCLUDEM NUMELE bazei de date this.databaseConnectionPool = mysqlConection.createPool(dbConfigCopy) // Construim o conexiune de tip Pool // FARA SA SPECIFICAM NUMELE BAZEI DE DATE } public static getInstance = () : DBConnection => { // Accesibil din afara , ne returneaza instanta if(!this.dbInstance) // Daca instanta nu e definita { this.dbInstance = new DBConnection() // Apelam Constructorul si Initializam Baza de Date } return this.dbInstance // RETURNAM INSTANTA } } Acum , va trebui sa initializam baza de date construind-o , DACA NU O GASIM : // dbConnection.ts export class DBConnection { // Pregatim clasa de export pentru utilizarea si reutilizarea conexiunilor // .. public initialize = async () : Promise<void> => { // Returnam un Promise try{ // Incercam // SA CONSTRUIM O BAZA DE DATE DACA ACEASTA NU EXISTA await this.databaseConnectionPool .query(`CREATE DATABASE IF NOT EXISTS \`${dbConfig.database}\``) this.databaseConnectionPool = mysqlConection.createPool({ // Construim un pool de conexiuni precizand numele bazei de date ...dbConfig, waitForConnections:true, // Asteptam pentru conexiune daca sunt ocupate connectionLimit:10, // Limita pentru conexiuni in asteptare atunci cand poolul este plin . queueLimit:0, // Nu stabilim o limita debug:true // Afisam in consola anumite informatii referitoare la operatiuni. }) // Afisam un mesaj ca totul e ok console.log(`AM CONSTRUIT SI AM INITIALIZAT CU SUCCES UN POOL DE CONEXIUNI !!`) } catch(err) // DACA APARE O EROARE PE URMA ACESTOR OPERATIUNI { console.error(`A APARUT O EROARE LA CONEXIUNEA CU BAZA DE DATE ${dbConfig.database} : ${err}`) throw err // Declansam eroarea } } public getPoolConnection = () : mysqlConection.Pool => { // Reutilizam poolul de conexiuni return this.databaseConnectionPool } } ** Testare ** Construim o functie asincrona (doarece returnam un Promise) in 'index.ts' , numita 'connectDB' , care ne efectueaza o conexiune la baza de date : export class API{ //////////................. constructor() { //........ this.connectDB() // Declansam Functia } public connectDB = async () => { try{ let dbInstance = DBConnection.getInstance() // Primim instanta si construim o conexiune cu credentiale await dbInstance.initialize() // Construim o baza de date daca aceasta NU exista SI pregatim un pool de conexiuni console.log(`CONEXIUNEA CU BAZA DE DATE A FOST REALIZATA CU SUCCES !!`) } catch(err) { console.error(`A aparut o eroare la conectarea cu baza de date : ${err} `); } } } Dupa care , rulam serverul prin 'cmd' cu npm run dev si primim ca rezultat : NOTA ** : NU VOM AVEA NEVOIE DE MODIFICARILE FACUTE DE LA 'TESTARE' IN JOS , AM VRUT SA FAC O DEMONSTRATIE PE PARTE DE APELARE SI TESTARE !! EA VA FI AUTOMAT , APELATA CAND CONSTRUIM RUTELE SI CONTROLLERELE .
  2. In acest tutorial , vom invata concepte care intervin in constructia bazei de date precum enumeram : Configuratia Bazei de date , asta include atat informatii cat si credentiale referitoare la conectarea catre baza noastra de date . In cazul in care , credentialele NU sunt trecute corespunzator , conectarea catre aceasta poate ESUA . Toate datele , le vom stoca in fisierul de configuratie ".env" . Modelul de Design Pattern Creational , 'Singleton' ne asigura reutilizarea conexiuni . Cu alte cuvinte , la fiecare operatiune catre baza noastra de date , NU va fi necesar sa trecem prin procesul de constructie deoarece ne folosim de o instanta statica (centralizata) care si mentine valoarea pana la oprirea serverului . Conexiune si Pool de Conexiuni . Ele sunt concepte cu un obiectiv similar , acela de a ne face legatura catre baza de date atunci cand aplicam o interogare . Totusi, poolul de conexiuni e un mecanism mult mai scalabil si mai avansat , astfel ca ne permite legaturi multiple in acelasi timp , gestioneaza eficient resursele reutilizand conexiunile existente . In acest sens , vom lucra cu 'pooluri' in tutorialele viitoare pentru o intelegere mai buna . Interogarea 'CREATE DATABASE IF NOT EXISTS \`NUME_BAZA_DATE\`' ne ofera posibilitatea de a construi o baza de date DACA nu avem una existenta cu acel nume . Lucrand cu baze de date DOAR din cod (NodeJS) , va fi necesar sa o construim . Cu alte cuvinte , va trebui sa construim o conexiune cu baza noastra de date FARA sa mentionam numele , dupa care va trebui ne folosim de interogarea de mai sus pentru a ne construi o baza unde vom stoca informatii ulterior .
  3. ** OBIECTIVE ** INSTALARE SI CONFIGURARE DEPENDENTE ; CONFIGURARE SERVER ; TESTARE . ** Instalare si Configurare Dependente ** Prima data , vom adauga (in terminal): dotenv (pentru citirea fisierelor de configuratie .env) si express.JS (instrumentul pentru dezvoltarea serverului) : npm i --save express dotenv Adaugam suportul TS pentru "expressJS" si "dotEnv" , ts-node (ne ajuta sa rulam cod TS FARA sa le compilam in JS) si nodemon (ne ajuta sa tinem server-ul deschis iar la fiecare modificare acesta va reincerca sa l deschida fara interventia noastra) . npm i --save-dev typescript @types/express ts-node nodemon @types/dotenv Acum , vom face un fisier de configuratie 'tsconfig.json'(Setarile de Compilare) la nivelul proiectului si notam : // Setari Pentru Compilare { "compilerOptions": { "target": "ES6", "module": "CommonJS", "outDir": "./dist", "rootDir": "./source", "strict": true } } ** CONFIGURARE SERVER ** Acum , vom diviza proiectul (adaugam cate un folder ++ fisiere in directorul 'source' care se afla la randul lui , sub cel principal) : 'Configurations' (Toate Setarile de Configurare, port server , setari baze de date etc.) la care adaugam : ## .env ## Server Configurations SERVER_PORT=8080 ## DB Settings && Others Privacy Settings /// configData.ts import * as dotEnv from 'dotenv' // Importam dotEnv if(dotEnv.config({ path:'./source/configurations/.env' // Citim fisierul de configuratie // ++ incarcam variabile de mediu }).error) { throw new Error('NU AM PUTUT GASI SAU ACCESA FISIERUL DE CONFIGURATIE !!') // Declansam o eroare // daca nu gasim fisierul } export const serverConfig = { // Trimitem catre export , credentialele acumulate !! port: +process.env.SERVER_PORT!, } 'Routes' (Unde inregistram toate rutele aplicatiei noastre) : // Router.ts ==> Clasa de Baza import {Application, Router} from "express" // Importam Router + Application export abstract class BaseRouter{ // Clasa de Baza Router ++ Abstracta (Contine Functii Pur Virtuale) protected router: Router // Declaram variabila router de tip Router constructor(pathRoute:string,API:Application) // Constructor care preia de la clasele derivate (prin 'super()') // ruta exprimata in Sir de Caractere si API ==> serverul ExpressJS unde inregistram rutele { this.router = Router() // Initializam o Ruta 'goala' // Inregistram subRutele in clasele derivate !!! this.initializeRouters() API.use(pathRoute,this.router) // Inregistram Ruta Catre Server } // Functia PUR Virtuala ==> Se defineste doar in clasele derivate protected abstract initializeRouters() : void } // HelloWorldRouter.ts ==> Clasa Derivata din Router import { Application } from "express"; import { BaseRouter } from "./Router"; import { Request,Response} from "express"; export class HelloWorldRouter extends BaseRouter { // Clasa DERIVATA DIN BASE ROUTER constructor(API:Application) { super('/users',API) // Apelam Constructorul Clasei de Baza } protected initializeRouters(): void { // Apelam in clasa de baza rutele din 'helloWorld' this.helloWorldHTML() this.helloWorldJSON() } // Rute Hello World private helloWorldJSON():void { this.router.get('/helloJSON',(req:Request,res:Response)=>{ res.status(200).json({ 'message':'BINE AI VENIT PE LEAGUECS !!' }) })} private helloWorldHTML():void { this.router.get('/helloHTML',(req:Request,res:Response)=>{ res.status(200).send("<h1 style='text-align:center'>BINE AI VENIT PE LEAGUECS!!</h1>") }) } } PS : M-am folosit de conceptul claselor mostenite pentru a organiza si a reutiliza codul repetitiv !!! 'app.ts' si 'server.ts' le vom pune separat , pe langa folderele de mai sus , unde vom tine lucruri pentru o buna desfasurare a serverului precum : 'middlewares'(sisteme care reusesc sa intercepteze & manipuleze solicitarile http/locale catre baza de date inainte de a ajunge raspunsul('Response') la client !! ),inregistrare rutelor , setarea originilor , pornirea serverului samd. // app.ts import {Application, json, urlencoded} from 'express' import * as express from 'express' import { HelloWorldRouter } from './routes/HelloWorldRouter' export class API { public app: Application constructor(){ // CONSTRUCTOR IMPLICIT FARA PARAMETRI this.app = express() // Construim o Aplicatie ExpressJS this.middlewares() // Permitem functiile ce intercepteaza cererea (REQUEST) && raspunsul (response) inainte // de a fi confirmate catre client this.routes() // Activam rutele pentru aplicatia noastra } // Functii private middlewares(){ // Diferite this.app.use(json()) // Permitem Format JSON in cadrul cererilor this.app.use(urlencoded({ extended:true })) // Permitem Format URL-ENCODED } private routes() { // Inregistram Ruta HelloWorld new HelloWorldRouter(this.app) } public start = (port:number):void => { this.app.listen(port,()=>{ // Pornim Serverul console.log(`SERVER-UL A PORNIT CU SUCCES PE PORTUL ${port}`) // Trimitem in consola un mesaj de succes }) } } // server.ts import { serverConfig } from "./configurations/configData"; // Importam Portul Serverului import { API } from "./app"; new API().start(serverConfig.port) // Pornim serverul pe portul mentionat !! Foldere 'Controllers' , 'Models' si 'Repositories' pentru operatiunile pe baza de date (creem foldere pe '/source') , le vom implementa la urmatorul tutorial . ** TESTARE ** Inainte de a rula , vom adauga in 'package.json' , urmatoarea configuratie (pentru a permite rularea codul 'ts' fara a il compila sub contextul 'ts-node' ++ nodemon) : { // Restu Codului .. "scripts": { "start": "ts-node source/server.ts", "dev": "nodemon source/server.ts" } } Deschidem terminalul , in directorul principal (NU in /source), vom executa comanda : npm run dev Avem ca rezultat : NOTA 1 ** : DACA VREI SA INCHIZI SERVER-UL , FOLOSESTE IN CONSOLA COMBINATIA 'CTRL+C' ! NOTA 2 ** : ORICE MODIFICARE IN COD , NODEMON VA FACE CA SERVER-UL SA SE RESTARTEZE (AUTOMAT) . NOTA 3 ** : PENTRU SUGESTII , PROBLEME & RECLAMATII , V-AS RUGA SA VA ADRESATI IN TOPIC SAU PM !!
  4. Dupa cum bine stiti , pe piata exista o competitie dintre sistemele de operare : Android si IOS . Platforma Android , o regasim pe o gama larga de dispozitive (Google Pixel,Samsung,Oppo,Xiaomi samd.) iar IOS , fiind o productie privata apartinuta de catre Apple , o regasim doar in dispozitivele acestora . (Mai putin PC-urile sau laptopuri unde avem MAC) . Acum , vine intrebarea , de ce ai alege IOS , in defavoarea sistemului Android sau invers ? Daca ma intrebi pe mine , am fost posesor , ani intregi , a dispozitivelor ce ruleaza pe Android (Mai exact , Samsung Galaxy S10 in 2019) . L am tinut pana in 2022 (incepea ca sistemul sa de a rateuri) , iar apoi , la propunerea unui prieten , mi a recomandat sa mi achizitionez un iphone (13) . Ce pot spune , e ca nu m as intoarce niciodata pe Android din motiv de securitate sporita , fluiditate si organizare (Interfata Uniforma) a sistemului IOS . Desi e invechit , functioneaza perfect , primeste actualizari la timp si nu am probleme la executia aplicatiilor . Pe scurt , votul meu merge pe IOS !! ** ROG SA POSTATI IN ACEST TOPIC PAREREA VOASTRA PERSONALA , FARA OFF-TOPIC SAU JIGNIRI !!! ASTFEL DE COMPORTAMENTE , SE SANCTIONEAZA CA ATARE !!
  5. ** OBIECTIVE ** Ce este TypeScript ? Unde se foloseste TypeScript ? Configurare TypeScript ** Prezentare TypeScript ** TypeScript reprezinta un superSet sau o extensie a limbajului Javascript , cu functionalitati multiple adaugate pe langa acesta . Asta inseamna ca orice cod JS valid va fi valabil si pentru Typescript dar cu ceva adaugiri . Spre deosebire de JS , codul in TypeScript trebuie COMPILAT , sa poata fi rulat . Amintim si cateva caracteristici cheie pentru care am decis sa folosesc "TypeScript" in proiectele viitoare : Suport mai bun pentru programarea orientata pe obiecte . Asta inseamna ca putem organiza toate elementele in clase si obiecte pentru o mentenanta mai buna. E un limbaj ce cere compilare spre deosebire de JS , asta insemnand ca eventuale erori survenite apar in timpul compilatiei . In schimb , JS ne lasa sa rulam dar va trebui sa le rezolvam pe timpul executiei programului . Permite definirea tipurilor variabilelor , a functiilor samd. pentru o mentenanta mai usoara ** La ce scara se foloseste TS ? ** TypeScript se utilizeaza , in general , unde mentenanta si scalabilitatea conteaza . Cu alte cuvinte , in : CRM-URI SI ERP-URI (Aplicatii Enterprise/Financiare/Bancare) ; Aplicatii ExpressJS/NextJS de mari dimensiuni ; Aplicatii Cloud/SeverLess (Azure,AWS samd.) ; Aplicatii Mobile cu React Native . ** Configurare TypeScript ** NOTA ** : NE ASIGURAM , TOTUSI , CA AVEM INSTALAT PACHETUL NODEJS !! Deschidem terminalul , navigam catre partitia unde dorim sa facem un proiect : cd /d B:\PROIECTE NODEJS Facem un director in folderul "Proiecte NodeJS" : mkdir EXPRESSJS_TS Navigam in el cd EXPRESSJS_TS Instalam pachetul "typeScript" la nivel global : npm i -g typescript Acum , facem un fisier de tip "ts" : touch index.ts Iesim din terminal , il deschidem in Visual Studio Code si notam : class helloWorld{ // Clasa HelloWorld private readonly helloString:string // Definim un SIR DE CARACTERE PRIVAT SI CONSTANT constructor(readonly helloParameter:string) // PRIMIM UN SIR DE CARACTERE CONSTANT CA PARAMETRU { this.helloString = helloParameter // ATRIBUIM PROPRIETATII NOASTRE VALOAREA PRIMIT DIN PARAMETRU } hello(){ // FUNCTIE LA NIVELUL CLASEI return this.helloString // RETURNAM SIRUL DE CARACTERE STOCAT DE CATRE PROPRIETATE } } const helloObject = new helloWorld('BINE AI VENIT PE LEAGUECS !!') // CONSTRUIM SI APELAM CONSTRUCTORUL CU PARAMETRII console.log(helloObject.hello()) // AFISAM SIRUL DE CARACTERE IN CONSOLA Apoi , intram in terminal , in directorul proiectului , vom compila fisierul : tsc index.ts Ni se va genera un fisier .JS langa acesta , iar apoi il rulam , in contextul NodeJS : node index.js Dupa executie , vom avea rezultatul in consola : B:\PROIECTE NODEJS\EXPRESSJS_TS>tsc index.ts B:\PROIECTE NODEJS\EXPRESSJS_TS>node index.js BINE AI VENIT PE LEAGUECS !!
  6. ** OBIECTIVE ** VOM INSTALA SI CONFIGURA O BAZA DE DATE CU STOCARE LOCALA (IN PC-UL NOSTRU) DE TIP SQL (MariaDB) . ** DESCARCARE ** Pentru prima data , vom descarca MariaDB de pe urmatorul link . NOTA ** : Bineinteles , va descarcati aplicatia in functie de sistemul vostru de operare si arhitectura (x86 sau x64) . ** Instalare ** Vom executa pachetul descarcat cu drepturi de administrator . Mergem mai departe acceptand termenii si conditiile impuse de aplicatie . In continuare , ni se vor afisa componente ale pachetului printre care avem : Serverul MariaDB (Serverul in sine + interogari/comenzi) si HeidiSQL (Interfata Vizuala de a observa baza de date cu elementele acestuia) . NOTA ** : Nu sunt esentiale toate (putem lucra si fara HeidiSQL) dar va trebui sa vedem informatiile in CMD . Pe scurt , pentru cativa mega nu merita sa nu le pastram pe toate . (nu umblam si dam doar next) . Mai departe , vom avea de ales atat o parola(+ confirmare) pentru contul de administrator cat si locatia pe hard a serverului . NOTA ** : FOARTE IMPORTANT SA RETINETI PAROLA , O VOM FOLOSI ATUNCI CAND NE CONECTAM LA EXPRESSJS. In continuare , vom avea de selectat anumite proprietati precum : numele serviciului (ramane MariaDB implicit) , portul ocupat de catre baza de date (3306 este implicit, avem totusi , atentia sa NU AVEM ALT SERVICIU CARE OCUPA DEJA ACEL PORT SA NU APARA CONFLICTE) si buffer pool (reprezinta o zona de memorie , ceva gen memorie "cache" unde sunt stocate datele frecvent accesate . Pe scurt , va avea acces mai rapid la aceste date deoarece sunt stocate in memorie si nu pe unitate de stocare) . Recomandat , e sa lasam valorile implicite si sa apesam tasta de next . DAM DRUMU LA INSTALARE ** Verificare ** De asemenea , il putem include in variabile de mediu pentru a lucra din CMD . Intram in meniul de Variabile de Mediu ; Intram la sectiunea "PATH" ; Adaugam o noua cale catre C:\Program Files\MariaDB 11.6\bin Intram in CMD si tastam mariadb --version DACA PRIMIM ACEASTA CONFIRMARE , VOM STII SIGUR CA S-A INSTALAT CU SUCCES SERVICIUL MARIADB !!
  7. Contra , schimband culoarea a unor iconite implica automat modificarea temei . Prea multa bataie de cap pentru un lucru irelevant .
  8. ** OBIECTIVE ** PREZENTARE IMPORTANTA BAZELOR DE DATE IN RELATIE CU PARTEA DE SERVER !! ** PREZENTARE BAZE DE DATE ** De ce avem nevoie de o baza de date in programarea BackEnd ? Dupa cum stim , o baza de date contine date despre anumite entitati (ex: masini , utilizatori samd.) care pot avea legaturi intre ele , una sa depinda de cealalta . Informatiile pe care le preluam de la utilizator (printr-o aplicatie Android,Web,Windows samd.) vor fi preluate , mai departe , de catre partea de server , prin cereri "HTTP" (GET,POST,DELETE,PUT samd.). Pe urma , pe baza unor interogari (In format RAW) sau pe baza de gestiune a obiectelor (ORM) , datele vor fi introduse in baza de date . NOTA ** : TOATE INSTRUMENTELE DE PROIECTARE SI CONSTRUIRE A APLICATIILOR WEB MERG PE ACELASI PRINCIPIU , DIFERA DOAR TIPUL DE TEHNOLOGIE FOLOSITA . Acum , in functie de structura si legaturile formate intre entitati , deosebim cateva tipuri de baze de date : RELATIONARE (SQL) , se remarca prin o structura si legaturi bine definite (prin chei straine & primare) . Printre bazele de date Relationare , amintim : MySQL , PostgreSQL , Oracle , Microsoft Access (din pachetul Office) , SQlite samd. Sunt potrivite pentru aplicatii din zona bancara/financiara sau unde structura entitatilor necesita sa fie bine structurata . NERELATIONARA (No-SQL) , se remarca prin scalabilitate influentata de structurile flexibile . Pe scurt , n-au nevoie de o structura anume (nu trebuie sa aiba un anumit format asemenea SQL) , suporta o multime de formate precum JSON sau grafuri si pot fi folosite intr-o varietate de aplicatii precum retele sociale , forumuri samd. Cand facem referinta catre baze No-SQL , amintim Firebase ,MongoDB, Cassandra , CouchDB . BAZATA PE OBIECTE , se remarca prin structura similara cu cea a programarii orientate pe obiecte . (ObjectDB , DAO Room) . BAZATA PE GRAFURI (GraphSQL, Neo4J) ; BAZATE PE CHEIE-VALOARE (Redis) ; HYBRIDE (ARANGODB) , combina notiuni din SQL cu cele din No-SQL . NOTA ** : Pentru inceput , vom lucra cu baze de date relationare , mai exact cu MariaDB-MySQL , pentru o intelegere mai buna a bazelor de date !! ** MariaDB vs MySQL ** MariaDB reprezinta , pe scurt , o ramura a lui MySQL , dezvoltata tot de aceeasi companie dupa ce a fost achizitionata de catre Oracle . Pe de alta parte , este o varianta mai imbunatatita atat pe partea de performante (ceva mai bune la indexare,cautari etc.) cat si pe partea de securitate . Mai mult ca atat , sunt aproape compatibile intre ele . (Cu putine modificari , eventual) . NOTA ** : Atat cu prezentarea , anumite detalii le vom descoperi cu urmatoarele tutoriale !!
  9. B.U.G. Mafia - 8 Zile Din 7 (feat. AMI) (Prod. Tata Vlad)
  10. ** OBIECTIVE ** VOM CONSTRUI SI TESTA PRIMUL NOSTRU PROIECT IN NODEJS (ExpressJS) !! ** PREZENTARE ExpressJS & NextJS ** ExpressJS & NextJS sunt "framework-uri" (instrumente) pentru construirea si dezvoltarea aplicatiilor "backend" (partea de server) din pachetul NodeJS. Ele ne furnizeaza o serie de implementare pentru gestionarea cererilor "https" , rutelor ("/home,/welcome samd.") , pentru sporirea securitatii , + alte functionatii pe care le vom vedea pe viitor . Acum , NextJS asemenea MeteorJS sunt API-uri orientata catre full-stack (cu suport pentru ReactJS --> frontend) , ofera o solutie completa + optimizari SEO in timp ce ExpressJS ne poate furniza doar o parte de "backend" simplista dar si personalizabila . Pe baza acestei ipoteze , vom studia ExpressJS dupa care ne vom concentra pe NextJS/MeteorJS. ** CONSTRUIRE PROIECT ExpressJS ** NOTA ** : NE ASIGURAM CA AVEM UN EDITOR (Recomandabil , Visual Studio Code) DAR SI UN MEDIU DE EXECUTIE JAVASCRIPT (NODEJS , instalat in tutorialul trecut) !! Deschidem Visual Studio Code + Vom Selecta optiunea de deschidere a folderului . INITIALIZAM UN FOLDER (UNDE SE VOR STOCA DATELE DIN PROIECT) Dupa ce am selectat folderul , vom deschide terminalul din Editor . In terminal (din aplicatie) , vom folosi comanda npm init -y pentru initializarea proiectului nostru NodeJS . NOTA 1 ** : Fisierul "package.json" ne furnizeaza datele despre proiect precum numele , descrierea , autor , licenta , versiune dar si informatii despre dependentele instalate ulterior . (SE ADAUGA AUTOMAT DUPA INSTALAREA PACHETELOR) NOTA 2 ** : TOATE DEPENDENTELE SE INSTALEAZA IN TERMINAL !! Mai departe , instalam pachetul "ExpressJS" . npm i express Apoi , tot in terminal , scriem (Generam "executabilul" proiectului) touch index.js Mergem in fisierul respectiv si notam : const express = require('express') // SIMILAR cu #include "" (ANUNTAM CA FOLOSIM PACHETUL EXPRESSJS) const server = express() // INITIALIZAM EXPRESS JS !! Aici , anuntam ca serverul nostru foloseste pachetul "ExpressJS" . Mai departe , stabilim un port pentru aplicatia noastra : const serverINFO = { port : 8080 // SETAM PORTUL 8080 (NE ASIGURAM CA NU INTERFEREAZA CU ALTE SERVICII CARE FOLOSESC ACEST PORT !! ) } Permitem ca aplicatia noastra sa gestioneze formatul "json" : server.use(express.json()) // PERMITEM CA APLICATIA NOASTRA WEB SA FOLOSEASCA FORMAT JSON Vom implenta doua raspunsuri (UN SIMPLU "HELLO WORLD") din partea serverului atunci cand accesam rutele "/helloJSON" si "/helloHTML" server.get('/helloJSON', (request,response) => response.json({"message":"BINE AI VENIT PE LEAGUECS!!"})) // CERERE PE FORMAT JSON server.get("/helloHTML",(request,respone) => respone.status(200).send("<h1 style='text-align:center'>BINE AI VENIT PE LEAGUECS!</h1>")) // CERERE PE FORMAT HTML CENTRAT + TITLU ANUNTAM LANSAREA APLICATIEI PE PORTUL SPECIFICAT server.listen(serverINFO.port,()=>console.log(`SERVERUL EXPRESS RULEAZA CU SUCCES PE PORTUL ${serverINFO.port}`)) // RULAM SERVERUL PE PORTUL MENTIONAT !! SI GATA ** TESTARE ** Pentru lansarea aplicatiei , vom folosi , in terminal , comanda : node index.js SI REZULTATELE SUNT : 1. IN FORMAT HTML : 2. IN FORMAT JSON : NOTA ** : Pentru a inchide executia aplicatiei , te folosesti de "CTRL + Z" in consola . index.js
  11. ** OBIECTIVE ** VOM INSTALA SI CONFIGURA MEDIUL DE DEZVOLTARE NODE JS PENTRU CONSTRUIREA APLICATIILOR WEB ! ** INSTALARE ** NOTA ** : Ne asiguram ca avem un editor , o aplicatie unde putem scrie cod Javascript . Aici , pot recomanda Visual Studio Code . Pentru prima data , accesam linkul pentru descarcare . NOTA ** : Va selectati binarul pentru sistemul dvs de operare !! Mai departe , vom executa binarul descarcat . Vom accepta termenii si conditiile impuse de pachet si vom continua . Alegem zona unde dorim sa instalam pachetul (+dependente) . Ne asiguram ca avem spatiul necesar . ALEGEM CE DORIM SA INSTALAM DIN PACHET . RECOMANDABIL , E SA NU SCOATEM NIMIC (PACHETUL , DEPENDETELE , DOCUMENTATIA DAR SI ADAUGAREA VARIABILELOR DE MEDIU). NU NE VOM FOLOSI DE ACESTE MODULE DAR DACA E NECESAR , LE VOM INSTALA SEPARAT . DAM DRUMU LA INSTALARE ASTEPTAM (ACCEPTAND TOATE RESURSELE CARE CER PERMISIUNEA) SI GATA Pentru a verifica daca s-a instalat cu succes pachetul , vom verifica prin CMD ("cmd" dupa "WIN+R") versiunea acestui pachet . npm --version
  12. ** OBIECTIVE ** PREZENTARE MEDIU DE DEZVOLTARE WEB NODEJS !! ** DEZVOLTARE WEB ** Aplicatiile Web , asemenea celorlalte (Android,IOS,Windows samd) , au in componenta doua structuri : Partea de suprafata (front-end) , partea unde se construieste interfata aplicatiei , de la controale vizuale pana la teme sau asezare in pagina . Cu alte cuvinte , partea de front-end este ceea vizibila de catre utilizator . In mediul online , front-end se poate construieste atat pentru pagini statice , folosind HTML (+ Canvas , SVG samd. ) & CSS (+ Bootstrap , o extensie pentru usurare) cat si pentru pagini dinamice , utilizand "framework-uri" precum ReactJS , AngularJS sau VueJS. Partea de adancime (back-end) , reprezinta partea "server-side" , ascunsa de catre utilizator , ea preia informatiile stocate de catre utilizator prin controalele vizuale si le trimite mai departe catre o baza de date (Nu numai) . Partea de Backend , se dezvolta folosind o varietate de tehnologii WEB precum ExpressJS/NextJS (din pachetul NodeJS) , Java Spring/EE (folosind Java) , Ruby on Rail (Ruby) , ASP.NET (din pachetul .NET C#) , Laravel/Symfony(folosind PHP) samd. (Merge chiar si in C dar e greu si ineficient ) . Revenind la oile noastre , in tutorialul acesta , vom invata cateva lucruri referitor de pachetul NodeJS !! ** Prezentare NodeJS ** NodeJS reprezinta un mediu de dezvoltare JavaScript pentru partea de server . Initial , Javascript putea fi folosit doar pentru partea de client ("front-end") , totusi , acest pachet ne ofera oportunitatea de a rula cod de aceasta natura pentru structura noastra "back-end" . Totusi , cu ce este mai special spre deosebire de celalalte medii ? Ne ofera oportunitatea sa lucram "full stack" folosind doar JavaScript . Cu alte cuvinte , nu trebuie sa invatam alte limbaje pentru a lucra atat pe partea de suprafata (client) cat si adancime (server) . Ne ofera SCALABILITATE deoarece reuseste sa proceseze mai multe cereri simultane fara a astepta sa se termine una si sa inceapa urmatoarea (ASINCRONITATE) . Reuseste sa proceseze informatia rapid si eficient deaoarece operatiune de Intrare/Iesire sunt realizate folosind "callbackuri" . Cu alte cuvinte , este potrivit pentru aplicatii "real-time" (precum chaturile) . Pe de alta parte , datorita avantajelor (scalabilitatii si eficientii) , o serie de aplicatii precum "Netflix" , "Uber" , "Medium" , "PayPal" , "eBay" folosesc NodeJS. NOTA ** : In tutorialele ce urmeaza , vom configura si ne vom construi propria noastra aplicatie NodeJS !
  13. Bine ai venit pe LeagueCS !
  14. ** OBIECTIV ** VOM PROIECTA (PRIN DIAGRAMA UML) , IMPLEMENTA (COD C) SI TESTA ALGORITMUL DE CAUTARE BINARA IN STIL RECURSIV SI GENERIC !! ** PROIECTARE ** AICI AVEM O PROIECTARE A ALGORITMULUI DE CAUTARE BINARA IN LIMBAJUL UML (Modelare). NOTA ** : SUNT INCEPATOR IN UML , PRIN URMARE SE POT VEDEA ANUMITE GRESELI DE ASEZARE A ACTIUNILOR DAR IDEEA E ACEEASI ! ** IMPLEMENTARE IN C ** NOTA ** : Sa presupunem ca avem un SIR SORTAT . ESTE INEFICIENT DACA NU E SORTAT !! ANTENTUL FUNCTIEI VA ARAT , OARECUM , SIMILAR CU CEL DE LA TUTORIALUL TRECUT (TOTUSI , APAR MICI DIFERENTE PE CARE LE VOM NOTA ) int binary_search_recursive(void* a,size_t elementSize,int lowIndex , int highIndex,void* searchedElement,int (*genericCMP)(const void*,const void*)) { // CODUL CE VA FI SCRIS } pointerul "a" reprezinta colectia de numere preluata de la tastatura ; "elementSize" reprezinta numarul de biti stocata de tipul de date pe care dorim sa l prelucram ; "lowIndex" reprezinta indexul inferior (Limita din Stanga) ; Cum ar venii [3,7] ==> 0 (3) "highIndex" reprezinta indexul superior (Limita din Dreapta) ; Cum ar venii [3,7] ==> N-1 (7) ==> Unde "N" reprezinta numarul total de elemente ; "searchedElement" reprezinta elementul cautat ; "generic" reprezinta interfata generic de comparare a elementelor . Practic , e o functie generica care pointeaza catre o functie de comparare potrivita pentru tipul de date prezent . Revenim , prima data , ne intereseaza daca mai avem elemente de comparat . Astfel , va trebui sa comparam limita inferioara cu superioara . // 1. VERIFICAM DACA MAI EXISTA ELEMENTE (FARA ASTA DUCEM ALGORITMUL IN STACKOVERFLOW !! ) if(lowIndex > highIndex) Daca se indeplineste conditia , ne da de inteles ca nu am gasit elementul, desi , am traversat intervalele "targetate" . Prin urmare , oprim algoritmul pentru a evita "stackoverflow" (supraincarcarea memoriei stack la infinit). return -1; // NU AM GASIT ELEMENTUL Mai departe , daca avem de verificat , vom afla mijlocul dintre cele doua extreme . // 2. AFLAM MEDIA DINTRE CELE DOUA EXTREME int mid = (lowIndex + highIndex)/2; Comparam elementul din mijloc cu cel cautat // 3. COMPARAM ELEMENTUL DIN MIJLOCUL INTERVALULUI FORMAT DINTRE CELE DOUA EXTREME int result = genericCMP((char*)a+mid*elementSize,searchedElement); // TRIMITEM ADRESELE PENTRU COMPARATIA VALORILOR ASOCIATE ACESTORA Pentru acest algoritm , vom schimba putin interfata de comparatie a numerelor : int compareInt(const void* a,const void* b) // FUNCTIE PENTRU COMPARAREA INTREGILOR { if(*(int*)a == *(int*)b) return 1; else if((*(int*)a > *(int*)b)) return 0; else return -1; } Acum , vom avea 3 rezultate : --> In cazul in care elementele sunt egale (avem 1) , am gasit elementul cautat si vom returna indexul asociat acestuia : if(result == 1) // SUNT EGALE return mid; // AM GASIT ELEMENTUL SI TRIMITEM INDEXUL ASOCIAT VALORI --> In cazul in care elementul cautat este mai mic decat mijlocul (avem 0) , vom cauta spre partea inferioara (stanga) : else if(result == 0) // DACA ELEMENTUL ACTUAL ESTE MAI MARE DECAT CEL CAUTAT return binary_search_recursive(a,elementSize,lowIndex,mid,searchedElement,genericCMP); // VOM RETURNA RECURSIV FUNCTIA FORMAND ALT INTERVAL MAI MIC CU INDEXUL INFERIOR SI MIJLOCUL --> In cazul in care elementul cautat este mai mare decat mijlocul (avem -1) , vom cauta spre partea superioara (dreapta) : else return binary_search_recursive(a,elementSize,mid,highIndex,searchedElement,genericCMP); // VOM RETURNA RECURSIV FUNCTIA FORMAND ALT INTERVAL MAI MIC CU INDEXUL DIN MIJLOC SI INDEXUL SUPERIOR Pe scurt , subprogramul cu algoritmul de cautare , va arat in felul urmator : int binary_search_recursive(void* a,size_t elementSize,int lowIndex , int highIndex,void* searchedElement,int (*genericCMP)(const void*,const void*)) //RETURNAM INDEXUL ELEMENTULUI CAUTAT { // 1. VERIFICAM DACA MAI EXISTA ELEMENTE (FARA ASTA DUCEM ALGORITMUL IN STACKOVERFLOW !! ) if(lowIndex > highIndex) return -1; // NU AM GASIT ELEMENTUL // 2. AFLAM MEDIA DINTRE CELE DOUA EXTREME int mid = (lowIndex + highIndex)/2; // 3. COMPARAM ELEMENTUL DIN MIJLOCUL INTERVALULUI FORMAT DINTRE CELE DOUA EXTREME int result = genericCMP((char*)a+mid*elementSize,searchedElement); // TRIMITEM ADRESELE PENTRU COMPARATIA VALORILOR ASOCIATE ACESTORA if(result == 1) // SUNT EGALE return mid; // AM GASIT ELEMENTUL SI TRIMITEM INDEXUL ASOCIAT VALORI // 4. DACA NU L-AM GASIT else if(result == 0) // DACA ELEMENTUL ACTUAL ESTE MAI MARE DECAT CEL CAUTAT return binary_search_recursive(a,elementSize,lowIndex,mid,searchedElement,genericCMP); else return binary_search_recursive(a,elementSize,mid,highIndex,searchedElement,genericCMP); } ** TESTARE ** Dupa implementare , vom testa in programul principal codul : int main() { int* a = (int*)malloc(sizeof(int)); // Declaram o colectie cu un element int bufferArr = insertArray(&a);// Trimitem pointerul a prin adresa (VOM MODIFICA STRUCTRURA ACESTUIA IN FUNCTIE ) si // ++ Vom returna lungimea finala in bufferArr int searchedNumber, searchedIndex; printf("\nINTRODUCETI NUMARUL CAUTAT : "); scanf("%d",&searchedNumber); // APELAM FUNCTIA DE CAUTARE LINIARA ; if((searchedIndex = binary_search_recursive(a,sizeof(int),0,bufferArr-1,&searchedNumber,compareInt)) != -1) printf("AM GASIT ELEMENTUL CAUTAT LA INDEXUL %d !!",searchedIndex); else printf("NU AM GASIT ELEMENTUL IN COLECTIE !! \n"); free(a); // Eliberam Colectia in Sine a = NULL; // Setam NULL Pointer } Dupa o simpla executie , vom avea :
×
×
  • Creează nouă...

Informații Importante

Termeni de Utilizare & Politică Intimitate