Red de conocimiento informático - Aprendizaje de código fuente - ¿Cuáles son las estructuras de datos y los algoritmos utilizados en el desarrollo de software real?

¿Cuáles son las estructuras de datos y los algoritmos utilizados en el desarrollo de software real?

Hay demasiadas aplicaciones.

Básicamente, C# se basa en un lenguaje orientado a objetos. Todas las clases/estructuras que usted define se consideran estructuras de datos, y muchos tipos disponibles se han definido en la biblioteca de clases .net para su uso. En el desarrollo real, la estructura y el algoritmo son simplemente inseparables.

La razón por la que el interrogador tiene tal problema es que básicamente se da cuenta de un problema que muchos programadores tienden a tener: la desconexión entre el conocimiento teórico y la aplicación práctica. Muchos programadores dicen que escriben programas usando No existe. conocimiento teórico, o la teoría es inútil. Siempre he creído que la teoría es la guía para la programación real. Sin mencionar el conocimiento teórico que has aprendido, a veces debemos cumplir con algunos estándares/normas/regulaciones en las actividades de software. Por ejemplo, ¿cuántos programadores han leído u oído hablar del estándar ISO29500? La verdad es que es un estándar internacional para openxml. Si queremos conseguir programas universales, es mejor leer estos estándares.

Volviendo a tu pregunta, ¿qué es una estructura de datos y qué es un algoritmo? Si realmente piensa en la estructura de datos en un sentido estricto, o simplemente a partir de los ejemplos de los libros de texto, ¿una estructura de datos se define como una clase o estructura con solo miembros de atributos como una estructura de datos? De hecho, no lo es, entonces, ¿solo las listas/pilas/colas vinculadas se consideran estructuras de datos? Se puede decir que este es un estereotipo común cuando algunas personas entienden las estructuras de datos en un sentido estricto, pero de hecho, las clases o estructuras son la base de las estructuras de datos. De lo contrario, ¿cuáles son exactamente las entidades en su lista vinculada? Por lo tanto, la estructura de datos incluye la estructura básica y el colectivo de entidades existentes, como lista de secuencia/lista enlazada/pila/equipo en sentido estricto. ¿Por qué digo que las estructuras de datos se utilizan ampliamente en aplicaciones prácticas? En lo que respecta a las estructuras de datos, los libros de texto solo explican claramente las estructuras, debilitando el significado real de las entidades en ellos, y las implementaciones específicas de diferentes lenguajes no son las mismas, por lo que las estructuras de datos de las que hablan son teorías básicas.

Déjame darte un ejemplo: lista enlazada (lenguaje C#) public?class?Member

{ public?string?Name{get;set;} public?string?Responsibility{ get;set ;} public?string?Posotion{get;set;} } public?class?MemberNode { public?Member?Member{get;set;} public?Member?Next{get;set;} }

///?El otro nodo es una estructura de nodo en la lista vinculada. Además de indicar el miembro actual, esta estructura de nodo también apunta a la siguiente estructura de Siguiente. Eventualmente puede formar una lista vinculada. Esta es una lista vinculada definida.

Puedes ver en el ejemplo anterior que esta es una definición estándar similar a la de los libros de texto, pero de hecho hay características genéricas en la sintaxis de C#, por lo que no necesitamos definir estructuras similares una por una. ¡Entiendo! Por lo tanto, para facilitar a los programadores en diferentes lenguajes, podemos incluso simplificar dicha estructura para lograr la forma de uso más sencilla. Tomando C# como ejemplo, podemos usar Node para representar una lista enlazada/List para representar una lista de secuencia/Stack para representar una pila/Queue para representar una cola. , solo necesitamos definir nuestro Solo use genéricos. Las cadenas estructurales y similares ya se han implementado en bibliotecas de clases usando genéricos; aunque no es necesario definirlos, eso no significa que no use o comprenda el conocimiento. involucrado. Cuando los libros de texto hablan de teoría, es imposible hablar de genéricos, por lo que muchas personas piensan que tienen que definir la estructura de datos ellos mismos, y esa es la estructura de datos "real", pero ese no es el caso. Tomando la lista enlazada como ejemplo, necesitamos que un nodo tenga un puntero al siguiente nodo (en realidad una referencia de dirección) además de su significado físico para ser considerado una estructura de datos.

Según el libro de texto, deben definirse así (C#): public?class?MemberNode

{

public?string?Name{get;set;}

pública?cadena?Responsabilidad{get;set;}

pública?cadena?Posición{get;set;}

pública?MemberNode?Next{get;set;}

}

//? Aquellos que estudian mucho solo admitirán que esta es la estructura de datos real (nodo de lista vinculada)

De hecho, la lista vinculada Es solo una forma, una forma de estructura de datos organizacionales que en última instancia puede formarse. Este código nos llevará a un gran malentendido: es necesario redefinir cada tipo de estructura. Si hay múltiples estructuras de tipos, tendremos múltiples definiciones diferentes, lo que conducirá a más y más definiciones de clases en el futuro, lo que será más problemático para el mantenimiento. Debido a la intervención de varios métodos de desarrollo, como patrones de diseño/orientado al corte, utilizaremos una forma relativamente simple. Es por eso que progresé en la definición de dos clases, y luego puede aparecer el paso posterior de los genéricos.

Puedes entender que esta estructura en el libro de texto hará que básicamente necesitemos redefinir cada estructura. El ejemplo que di al principio puede usar la herencia para implementar una determinada estructura. (Lo siguiente parece funcionar, pero pueden ocurrir algunos problemas durante el uso), y Node resuelve fundamentalmente este problema y puede admitir múltiples tipos.

Entonces, al comprender la estructura de datos en este momento, como Node, no solo es necesario comprender los nodos de la lista vinculada, sino también el T genérico. ya no se refiere a Es una estructura de un solo nodo y también incluye un tipo básico.

En otras palabras, ya no necesitas hacer definiciones similares en lenguajes como C#, solo necesitas definir su tipo de estructura básica. Pero cuando se enseñan conocimientos en libros de texto, no puede ser solo para lenguajes orientados a objetos o que admitan genéricos. Si los genéricos no son compatibles, debemos usar el formulario en el libro de texto o el ejemplo que escribí por primera vez. Lenguaje orientado a la herencia, el conocimiento en el libro de texto es una regla rígida. Debe hablar en esta forma y la referencia utiliza una referencia de puntero (una referencia orientada a objetos es en realidad una referencia de tipo de referencia, es decir, la referencia de dirección). o referencia de dirección, similar al puntero).

Creo que puedes entenderlo hablando de ello aquí. La estructura de datos simplemente cambia de forma en diferentes idiomas. No necesariamente tiene que tener punteros, ni es simplemente superficial. Los primeros tutoriales se basaban principalmente en el lenguaje fortain y el propósito del libro de texto era explicar la verdad, no una regla. Las personas que estudian mucho piensan que no usan estructuras de datos, pero en realidad las usan todo el tiempo.

Hablemos de nuevo del algoritmo. ¿Qué es el algoritmo? Es un modo de resolver problemas, como resolver ecuaciones lineales en dos variables, etc. Entonces, la definición de algoritmo en realidad le dice que el código secuencial también puede considerarse como un algoritmo. No se puede decir que solo el problema de la mochila, el ocho. El problema de las reinas y el problema de retroceder son algoritmos. ¿Puedes entenderlo? De hecho, lo que normalmente escribe es un algoritmo. Este algoritmo es simple y solo necesita ejecutarse secuencialmente. También es un algoritmo, incluso si existe un patrón fijo (algoritmo) para resolver un sistema de ecuaciones lineales en dos variables. no significa suma y resta. ¡La ley ya no es un algoritmo! Entonces, los algoritmos también son cosas de uso común, por lo que los algoritmos que aprendes son en realidad solo una forma de abrir ideas. Se ha determinado el concepto del algoritmo en sí. Básicamente, los programas se componen de estructuras y algoritmos.

Déjame darte un ejemplo: ¿cómo determinar si una lista enlazada es una lista enlazada circular? ¿Es su algoritmo de retroceso, su algoritmo codicioso o su algoritmo de mochila? Son solo una forma común de resolver algunos problemas típicos. Obviamente, mi problema no es un problema tan típico, pero eso no significa que no sea típico. Nuestro algoritmo normal es diseñar dos variables iguales al elemento principal y luego. Al comenzar a ingresar al ciclo, una variable empuja hacia abajo una vez cada vez, es decir, encuentra su siguiente nodo, y la otra variable encuentra su nodo nieto cada vez, incluso si las dos variables empujan hacia abajo una vez cada vez, y la otra. empuja cada punto dos veces (si es posible), si no es una lista enlazada circular, el que ingresa dos veces encontrará una referencia nula cuando sea la mitad de la longitud total de la lista enlazada; de lo contrario, los dos punteros harán referencia al mismo objeto en un determinado tiempo (no que los objetos sean iguales, sino que las referencias sean las mismas ¿Qué significa? Es como dos personas corriendo en una pista circular, una a 1 metro por segundo y la otra a 2 metros por segundo. Si empiezan desde el mismo lugar y en la misma dirección al mismo tiempo, el más rápido eventualmente alcanzará al más lento. Por supuesto, en este caso, ¿también se puede llamar "algoritmo de recuperación"? Si solo los pocos algoritmos típicos que aprendiste son algoritmos, ¿cuenta esto como un algoritmo?

Ahora nuestra pregunta es, si estas cosas se han implementado a nivel del lenguaje, ¿no podemos necesitar comprender estas teorías? La respuesta es sí: si eres simplemente un programador que no es emprendedor o un programador irresponsable que permite que los errores vuelen por ahí, no necesitas comprenderlo; después de todo, ¡algunas personas simplemente se "ganan la vida"!

Entenderla pero no aplicarla es una típica teoría que no se puede conectar con la realidad, y no saben cómo se controlará su código. Permítame darle un ejemplo. Debido a diversos requisitos, como el rendimiento, necesitamos utilizar subprocesos múltiples para procesar ciertos datos. ¿Cómo afrontarlo? Las personas malas usarán subprocesos múltiples: definen un recurso crítico y luego dejan que varios subprocesos se bloqueen al leer la tabla de datos (DataSet), y luego cada subproceso maneja esos problemas de tiempo de espera prolongado y luego presiona Leer datos de esta manera. ¿Hay algún problema con esto? ¡No, esto puede considerarse un tipo de algoritmo! De todos modos, si tienes una buena base en programación de código, no habrá problema. ¿Se considera que este tipo de código es elegante? ¡Mucha gente piensa que la elegancia del código es la forma del proceso de escritura del código o los buenos hábitos de programación! De hecho, aquí no se utilizan estructuras de datos ni algoritmos.

Está bien, lo admito, pero si lo vemos de otra manera, si uso un hilo para leer datos y sigo colocándolos en una cola, mientras varios hilos leen datos de la cola ¿Qué tal constantemente? ¿Leer y procesar los datos puestos? Lo que quiero decir es que en lugar de procesarlo directamente en el DataSet, elijo usar una cola.

Veamos un problema, esta cola Cola, se usa un subproceso para insertar datos, se usan varios subprocesos para leer datos y, para garantizar que no se pueda repetir, entonces podemos usar el versión segura de la cola (CorrentQueue, si no es seguro para subprocesos en .net, el subproceso múltiple debe encontrar su versión segura correspondiente o controlar la seguridad del subproceso).

Si el hilo de inserción encuentra que la longitud (capacidad) en la cola es grande, puede suspender la inserción. Esto puede garantizar que la longitud de la cola sea básicamente fija y que el uso de la memoria esté controlado (no es que el conjunto de datos lea mucho en lotes). Dado que se utiliza la cola de seguridad, cada subproceso no necesita considerar los problemas de seguridad entre subprocesos. Cada hilo obtiene datos de la cola y la eliminación garantiza que los datos solo se procesen una vez. Por supuesto, también puede considerar un mecanismo de notificación elegante. El hilo de inserción notifica al hilo de procesamiento que comience al insertar datos si la velocidad de inserción es demasiado rápida y se descubre que el número de inserciones ha alcanzado la longitud especificada (como 30). , la inserción se detendrá y el hilo de inserción se bloqueará; el procesamiento se procesará nuevamente. Se puede notificar al hilo de inserción para que vuelva a insertar.

Esto se puede considerar un algoritmo, ¿verdad? Permite que el hilo de inserción y el hilo de procesamiento funcionen al mismo tiempo. Cuando se utilizan resultados convencionales como DataSet, solo se puede esperar a que se complete el procesamiento o agregar múltiples condiciones de control para el control. ¿Cola directamente? ¡La T en CorrentQueue también puede ser un registro DataRow!

Si crees que el primer método es el que usas con frecuencia, entonces no importa si aprendes el algoritmo o no. Debes usar tus propias habilidades de programación/depuración para asegurarte de que tu código lo tenga. pocos errores como sea posible. O no error.

Y si cree que la segunda solución es más elegante, entonces pensará que los algoritmos y estructuras que aprendió siguen siendo útiles y que la teoría y la práctica se combinan.

La razón por la que di este ejemplo es para brindarte información muy importante:

Tienes la libertad de elegir el algoritmo (solo se trata de la calidad del código, preguntas posteriores al mantenimiento). )

Si conoce más algoritmos y estructuras, tendrá más opciones.

En el uso real de algoritmos o estructuras, los llamados problemas típicos no significan que los escenarios de uso sean exactamente los mismos que los descritos en el libro (imagínese si el segundo ejemplo que consideré es menos típico que el del libro)? De hecho, también es muy típico)

Al analizar un problema, debes centrarte en los puntos clave en lugar de cubrirlo en su conjunto. (Si lo aplica en su conjunto, definitivamente no sabrá qué estructura o algoritmo usar)

Ya sea una estructura de datos/algoritmo/patrón de diseño, es necesario usarlo de manera flexible, en lugar de comparar. el uso de escenarios, ni copiarlos mecánicamente.

Imagínate, si tienes un problema con tu mochila, ¿cómo podría la empresa pedirte que la empaquetes por separado? ¿Tu empresa problemática de las ocho reinas te deja jugar al ajedrez? ¿Su codiciosa empresa de algoritmos le da cambio? ¿Su empresa de algoritmos de retroceso le permite navegar por un laberinto? La razón por la que el aprendizaje no se puede poner en práctica es que es demasiado rígido: la posibilidad de que se encuentre o se encuentre nuevamente con estos ejemplos de escenarios es muy pequeña, por lo que si siente que el aprendizaje es inútil, entonces es realmente inútil. solo que no es que el algoritmo sea inútil, ¡es que no hay personas!

Cuéntame una pequeña historia: Érase una vez, el banco de una familia se rompió y tuvieron que encontrar una rama de árbol de dos puntas adecuada para hacer nuevas patas del banco. El niño fue al jardín de árboles a hacerlo. Buscó durante mucho tiempo, y el niño regresó. Dijo: "¡Nunca había visto una rama que se bifurcara hacia abajo! Su padre estaba tan enojado - ¡cómo podría haber una rama que se bifurcara hacia abajo! ¿Es este niño estúpido? No lo harías. t cava el suelo ¡Encuentra la raíz de un árbol que se ramifique hacia abajo!

Lo mismo ocurre con el algoritmo. Puedes usar el algoritmo de retroceso para encontrar caminos en laberintos, pero no todos los algoritmos de retroceso se usan para encontrar caminos en laberintos; ser utilizado para diseñar laberintos!